Skip to content

Commit

Permalink
Use Patreon v2 API to get user details
Browse files Browse the repository at this point in the history
  • Loading branch information
cynicaloptimist committed Sep 14, 2023
1 parent f1a46a8 commit 3a5778e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 22 deletions.
64 changes: 43 additions & 21 deletions server/patreon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import * as crypto from "crypto";
import * as express from "express";

import * as _ from "lodash";
import * as patreon from "patreon";
import axios from "axios";
import * as querystring from "querystring";

import * as request from "request";

Expand Down Expand Up @@ -60,17 +61,22 @@ export function configureLoginRedirect(app: express.Application): void {

app.get(redirectPath, async (req: Req, res: Res) => {
try {
console.log("req.query >" + JSON.stringify(req.query));
console.log("req.body >" + JSON.stringify(req.body));
const code = req.query.code;

const OAuthClient = patreon.oauth(patreonClientId, patreonClientSecret);

const tokens = await OAuthClient.getTokens(code, redirectUri);

const APIClient = patreon.patreon(tokens.access_token);
const { rawJson } = await APIClient(`/current_user`);
await handleCurrentUser(req, res, rawJson);
const code = req.query.code as string;

const tokens = await getTokens(code, redirectUri);

const userResponse = await axios.get(
`https://www.patreon.com/api/oauth2/v2/identity` +
`?${encodeURIComponent("fields[user]")}=email` +
`&include=memberships.currently_entitled_tiers`,
{
headers: {
authorization: "Bearer " + tokens.access_token
}
}
);

await handleCurrentUser(req, res, userResponse.data);
} catch (err) {
console.error("Patreon login flow failed:", JSON.stringify(err));
res
Expand All @@ -82,27 +88,43 @@ export function configureLoginRedirect(app: express.Application): void {
});
}

async function getTokens(code: string, redirectUri: string) {
const tokensResponse = await axios.post(
"https://www.patreon.com/api/oauth2/token",
querystring.stringify({
code: code,
grant_type: "authorization_code",
client_id: patreonClientId,
client_secret: patreonClientSecret,
redirect_uri: redirectUri
}),
{ headers: { "content-type": "application/x-www-form-urlencoded" } }
);

const tokens = tokensResponse.data;
return tokens;
}

export async function handleCurrentUser(
req: Req,
res: Res,
apiResponse: Record<string, any>
): Promise<void> {
//console.log(`api response: ${JSON.stringify(apiResponse)}`);
let encounterId = "";
if (req.query && req.query.state) {
encounterId = (req.query.state as string).replace(/['"]/g, "");
}

const pledges = (apiResponse.included || []).filter(
item => item.type == "pledge" && item.attributes.declined_since == null
);

const userRewards = pledges.map((r: Pledge) =>
_.get(r, "relationships.reward.data.id", "none")
);
const memberships = apiResponse.included.filter(i => i.type === "member");
const entitledTierIds = _.flatMap(
memberships,
m => m.relationships.currently_entitled_tiers.data
)
.filter(d => d.type === "tier")
.map(d => d.id);

const userId = apiResponse.data.id;
const standing = getUserAccountLevel(userId, userRewards);
const standing = getUserAccountLevel(userId, entitledTierIds);
const emailAddress = _.get(apiResponse, "data.attributes.email", "");

const session = req.session;
Expand Down
3 changes: 2 additions & 1 deletion server/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ const getClientOptions = (session: Express.Session) => {
"http://www.patreon.com/oauth2/authorize" +
`?response_type=code&client_id=${patreonClientId}` +
`&redirect_uri=${baseUrl}/r/patreon` +
`&scope=users pledges-to-me` +
`&scope=` +
encodeURIComponent(`identity identity.memberships identity[email]`) +
`&state=${encounterId}`;

const environment: ClientEnvironment = {
Expand Down

0 comments on commit 3a5778e

Please sign in to comment.