From 6dca1ed840ddde6c7f51b9a626254ed8ce360c27 Mon Sep 17 00:00:00 2001 From: Florian Klampfer Date: Sat, 7 Sep 2024 15:09:22 +0700 Subject: [PATCH] Add ping endpoint --- .gitignore | 2 +- functions/[[catchall]].ts | 2 +- functions/api/ping/[[catchall]].ts | 75 ++++++++++++++++++++++++++++++ package.json | 10 ++++ 4 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 functions/api/ping/[[catchall]].ts create mode 100644 package.json diff --git a/.gitignore b/.gitignore index a543d68..42b2a8e 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,7 @@ nbproject # Folders to ignore node_modules -package*.json +package-lock.json vendor .sass-cache .jekyll-metadata diff --git a/functions/[[catchall]].ts b/functions/[[catchall]].ts index 3a0557a..1b9ee77 100644 --- a/functions/[[catchall]].ts +++ b/functions/[[catchall]].ts @@ -29,7 +29,7 @@ async function getPrices(request: Request, env: Env, waitUntil: (promise: Promis const productUrl = new URL(`https://api.gumroad.com/v2/products/${ProductId}`); productUrl.searchParams.append('access_token', env.GUMROAD_ACCESS_TOKEN); - const productResponse = await fetch(productUrl, { method: 'GET' }); + const productResponse = await fetch(productUrl, { method: 'GET', headers: [[ 'user-agent', navigator.userAgent ]] }); if (!productResponse.ok) { console.error('Product response not ok', productResponse.status); return null; diff --git a/functions/api/ping/[[catchall]].ts b/functions/api/ping/[[catchall]].ts new file mode 100644 index 0000000..4f8d7ef --- /dev/null +++ b/functions/api/ping/[[catchall]].ts @@ -0,0 +1,75 @@ +/// + +import qs from 'qs'; + +const ShortProductId = 'nuOluY'; + +const Org = 'hydecorp'; +const TeamSlug = 'pro-customers'; +const GitHubApiVersion = '2022-11-28'; + +interface Env { + GUMROAD_ACCESS_TOKEN: string + GITHUB_ADMIN_PAT: string + PING_SECRET: string + SELLER_ID: string + KV?: KVNamespace +} + +export const onRequestPost: PagesFunction = async (context) => { + const { env, params } = context; + const request = context.request as Request; + + const secret = params.catchall?.[0]; + if (secret !== env.PING_SECRET) { + console.error("Invalid secret:", secret); + return new Response(null, { status: 401 }); + } + + console.debug("content-type", request.headers.get('content-type')); + if (!request.headers.get('content-type')?.includes('x-www-form-urlencoded')) { + console.error("Invalid content-type", request.headers.get('content-type')); + return new Response(null, { status: 400 }); + } + const payload = qs.parse(await request.text()) + console.debug("payload", payload); + + if (payload.seller_id !== env.SELLER_ID) { + console.error("Invalid seller_id, this should never happen"); + return new Response(null, { status: 400 }); + } + if (payload.short_product_id !== ShortProductId) { + console.warn("Unsupported product_permalink"); + return new Response(); // ok + } + if (!payload.custom_fields) { + console.error("No custom_fields"); + return new Response(null, { status: 400 }); + } + console.debug("payload.custom_fields", payload.custom_fields); + + const customFields = payload.custom_fields as Record|null; + const githubHandle = customFields && Object.entries(customFields).find(([k]) => k.trim().toLowerCase().startsWith('github'))?.[1]; + console.debug("githubHandle", githubHandle); + + if (!githubHandle) { + console.warn("No GitHub handle provided"); + return new Response(); // ok + } + + const url = `https://api.github.com/orgs/${Org}/teams/${TeamSlug}/memberships/${githubHandle}`; + const ghResponse = await fetch(url, { + method: 'PUT', + headers: { + 'accept': 'application/vnd.github+json', + 'authorization': `Bearer ${env.GITHUB_ADMIN_PAT}`, + 'x-github-api-version': GitHubApiVersion, + 'content-type': 'application/json', + 'user-agent': navigator.userAgent + }, + body: JSON.stringify({ role: 'member' }) + }); + console.debug("ghResponse/status", ghResponse.status); + console.debug("ghResponse/body", await ghResponse.text()); + return new Response(null, { status: ghResponse.status }); +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..bbaf773 --- /dev/null +++ b/package.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "qs": "^6.13.0", + "re-template-tag": "^2.0.1" + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20240903.0", + "@types/qs": "^6.9.15" + } +}