diff --git a/infra/workers/README.md b/infra/workers/README.md index 887dd4357..e6d312317 100644 --- a/infra/workers/README.md +++ b/infra/workers/README.md @@ -7,7 +7,7 @@ Each worker is a self contained directory with its each `package.json`. ## Deploying -* Switch to a worker directory, e.g. `cd health-check`. +* Switch to a worker directory, e.g. `cd github-discord-notifier`. * Install dependencies (if needed) with `yarn` @@ -21,8 +21,8 @@ wrangler tail`. ## Creating a new worker -Copy paste an existing one. Unironically this is a good option because the -Cloudflare template has a lot of unnecessary noise, but if really do want to +Copy paste an existing one. Unironically this is a good option because +Cloudflare's template has a lot of unnecessary noise, but if really do want to create one from scratch, use `npm create cloudflare@latest`. To import an existing worker from the Cloudflare dashboard, use diff --git a/infra/workers/github-discord-notifier/package.json b/infra/workers/github-discord-notifier/package.json new file mode 100644 index 000000000..165c48aea --- /dev/null +++ b/infra/workers/github-discord-notifier/package.json @@ -0,0 +1,9 @@ +{ + "name": "github-discord-notifier", + "private": true, + "devDependencies": { + "@cloudflare/workers-types": "^4.20240314.0", + "typescript": "^5", + "wrangler": "^3" + } +} diff --git a/infra/workers/github-discord-notifier/src/index.ts b/infra/workers/github-discord-notifier/src/index.ts new file mode 100644 index 000000000..7a70206b6 --- /dev/null +++ b/infra/workers/github-discord-notifier/src/index.ts @@ -0,0 +1,49 @@ +/** + * Forward notifications from GitHub to Discord. + * + * This worker receives webhooks from GitHub, filters out the ones we don't + * need, and forwards them to a Discord webhook. + * + * [Note: GitHub specific Discord Webhooks] + * + * By appending `/github` to the end of the webhook URL, we can get Discord to + * automatically parse the payload sent by GitHub. + * https://discord.com/developers/docs/resources/webhook#execute-githubcompatible-webhook + * + * Note that this doesn't work for all events. And sadly, the events it doesn't + * work for get silently ignored (Discord responds with a 204). + * https://github.com/discord/discord-api-docs/issues/6203#issuecomment-1608151265 + */ +export default { + async fetch(request: Request, env: Env) { + return handleRequest(request, env.DISCORD_WEBHOOK_URL); + }, +} satisfies ExportedHandler; + +interface Env { + DISCORD_WEBHOOK_URL: string; +} + +const handleRequest = async (request: Request, targetURL: string) => { + const requestBody = await request.text(); + let sender = JSON.parse(requestBody)["sender"]["login"]; + if (sender === "cloudflare-pages[bot]" || sender === "CLAassistant") { + // Ignore pings from CF bot + return new Response(null, { status: 200 }); + } + + const response = await fetch(targetURL, { + method: request.method, + headers: request.headers, + body: requestBody, + }); + + const responseBody = await response.text(); + const newResponse = new Response(responseBody, { + status: response.status, + statusText: response.statusText, + headers: response.headers, + }); + + return newResponse; +}; diff --git a/infra/workers/github-discord-notifier/tsconfig.json b/infra/workers/github-discord-notifier/tsconfig.json new file mode 100644 index 000000000..70c70a35d --- /dev/null +++ b/infra/workers/github-discord-notifier/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "../tsconfig.base.json", "include": ["src/**/*.ts"] } diff --git a/infra/workers/github-discord-notifier/wrangler.toml b/infra/workers/github-discord-notifier/wrangler.toml new file mode 100644 index 000000000..bce72b1c3 --- /dev/null +++ b/infra/workers/github-discord-notifier/wrangler.toml @@ -0,0 +1,3 @@ +name = "github-discord-notifier" +main = "src/index.ts" +compatibility_date = "2024-03-14"