From 296f8253476fb9004aacc05fdce8952d33632491 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Mon, 21 Sep 2026 15:38:21 +0700 Subject: [PATCH] fix(discord): strip HTML table markup from review notifications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Discord embeds render markdown, not HTML — the PR Reviewer Guide table (
…) was appearing as literal HTML in the webhook message. Added htmlToDiscordPlain(): collapses the table into readable lines (score/effort/security/key-issues), keeps emoji + **bold** markdown, and decodes entities. Also fixed review score suffix '/10' → '/100' (the LLM score scale is 0-100, matching the table's 'Score: 72'). --- server/src/index.ts | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/server/src/index.ts b/server/src/index.ts index e5edd7c..07a9a48 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -117,7 +117,7 @@ export async function handleWebhook( (result.data && result.data["review"] && (result.data["review"] as Record)["score"] ? ` — score ${(result.data["review"] as Record)["score"]}/100` : "") + - `\n${result.markdown.slice(0, 4000)}`, + `\n${htmlToDiscordPlain(result.markdown).slice(0, 4000)}`, "✅ PR-Agent Review Complete", ); } @@ -147,6 +147,37 @@ async function getHttpx() { return fetch; } +/** Strip HTML table markup down to Discord-friendly plain text. + * Discord embeds render limited markdown — raw / tags + * would show as literal HTML. Convert the reviewer table into lines. */ +function htmlToDiscordPlain(html: string): string { + let s = html + .replace(/
/g, "") + .replace(/<\/details>/g, "") + .replace(//g, "▶ ") + .replace(/<\/summary>/g, "\n") + .replace(//gi, "\n") + .replace(/<\/tr>/gi, "\n") + .replace(/<\/td>/gi, "") + .replace(/<\/th>/gi, "") + .replace(/]*>/gi, "") + .replace(/]*>/gi, "") + .replace(/]*>/gi, "") + .replace(/]*>/gi, "") + .replace(/<\/table>/gi, "") + .replace(/]*>/gi, "• ") + .replace(/<[^>]+>/g, "") + .replace(/ /g, " ") + .replace(/&/g, "&") + .replace(/</g, "<") + .replace(/>/g, ">") + .replace(/"/g, '"') + .replace(/'/g, "'") + .replace(/\n{3,}/g, "\n\n") + .trim(); + return s; +} + async function sendDiscord(webhook: string, content: string, title?: string): Promise { try { await fetch(webhook, {
/