diff --git a/lib/formatter.ts b/lib/formatter.ts new file mode 100644 index 0000000..f4e37fb --- /dev/null +++ b/lib/formatter.ts @@ -0,0 +1,34 @@ +// Empirically determined GitHub embed description limit in the Discord API. +// Anything above this will be ellipsized :/ +const EMBED_LIMIT = 500; + +function maybeTransformText(s: string): string { + // If length exceeds limit, add backticks since they might otherwise be removed + const suffix = "…\n```"; + const maxLen = EMBED_LIMIT - suffix.length; + if (s.includes("```") && s.length > maxLen) { + s = s.substring(0, maxLen) + suffix; + } + return s; +} + +export default function fixupEmbeds(data: Record): void { + for ( + const field of [ + // issue + "issue", + // issue/pr/discussion comment + "comment", + // pr + "pull_request", + // pr review + "review", + // discussion + "discussion", + // discussion answer + "answer", + ] + ) { + if (data[field]?.body) data[field].body = maybeTransformText(data[field].body); + } +} diff --git a/lib/handler.ts b/lib/handler.ts index 1e0feee..e4efeae 100644 --- a/lib/handler.ts +++ b/lib/handler.ts @@ -2,6 +2,7 @@ import { http } from "../deps.ts"; import config from "./config.ts"; import { hasKey, verify } from "./crypto.ts"; import filterWebhook from "./filter.ts"; +import fixupEmbeds from "./formatter.ts"; import { UrlConfig } from "./types.d.ts"; import { parseBool, requestLog } from "./util.ts"; import { sendWebhook } from "./webhook.ts"; @@ -37,7 +38,7 @@ export default async function handle( // extract data const urlConfig = getUrlConfig(url.searchParams); const data = await req.text(); - const json = JSON.parse(data); + const json: Record = JSON.parse(data); // do the thing const filterReason = await filterWebhook(req.headers, json, urlConfig); @@ -47,7 +48,10 @@ export default async function handle( return new Response(`Ignored by webhook filter (reason: ${filterReason})`, { status: 203 }); } - return await sendWebhook(id, token, req.headers, data); + // mutate `json` in-place (fixing codeblocks etc.) + fixupEmbeds(json); + + return await sendWebhook(id, token, req.headers, json); } function getUrlConfig(params: URLSearchParams): UrlConfig { diff --git a/lib/webhook.ts b/lib/webhook.ts index 4bdf551..53dfa13 100644 --- a/lib/webhook.ts +++ b/lib/webhook.ts @@ -5,10 +5,11 @@ export async function sendWebhook( id: string, token: string, headers: Headers, - body: string, + data: Record, ): Promise<[Response, Record]> { const reqLog = requestLog(headers); const url = `https://discord.com/api/webhooks/${id}/${token}/github?wait=1`; + const body = JSON.stringify(data); let res: Response; let retries = 0;