From e418deb0abcb1f233e579c5d46ab93d2d3cab63b Mon Sep 17 00:00:00 2001 From: ehsanKey Date: Sun, 12 Jul 2026 18:30:42 +0330 Subject: [PATCH] feat(webhooks): add comment notification support --- locales/en.ftl | 8 +++ .../webhooks/handlers/comment-created.ts | 55 +++++++++++++++++++ src/lib/github/webhooks/index.ts | 5 +- 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/lib/github/webhooks/handlers/comment-created.ts diff --git a/locales/en.ftl b/locales/en.ftl index 9c810de..fa2500e 100644 --- a/locales/en.ftl +++ b/locales/en.ftl @@ -232,3 +232,11 @@ e_project_item_status_changed = 👉 status: { $status } { $repoHashtag } #project + +e_comment_created = + 💬 { $commentAuthor } { $telegramStatus } commented on { $repoName }#{ $number }: + + { $title } +
{ $commentPreview }
+ + { $repoHashtag } #{ $type } diff --git a/src/lib/github/webhooks/handlers/comment-created.ts b/src/lib/github/webhooks/handlers/comment-created.ts new file mode 100644 index 0000000..4e09e23 --- /dev/null +++ b/src/lib/github/webhooks/handlers/comment-created.ts @@ -0,0 +1,55 @@ +import type { HandlerFunction } from "@octokit/webhooks/types"; + +import { bot } from "#bot"; + +import { escapeHtml } from "../../../escape-html.ts"; +import { botText, getRepoHashtag, getUser } from "./_utils.ts"; + +export const commentCreatedCallback: HandlerFunction< + "issue_comment.created" | "pull_request_review_comment.created", + unknown +> = async (event) => { + const comment = event.payload.comment; + const repository = event.payload.repository; + const sender = event.payload.sender; + + const user = await getUser(sender); + const repoHashtag = getRepoHashtag(repository.name); + + let title: string; + let number: number; + let type: "issue" | "pull_request"; + + if ("issue" in event.payload) { + const issue = event.payload.issue; + title = issue.title; + number = issue.number; + type = "issue"; + } else if ("pull_request" in event.payload) { + const pr = event.payload.pull_request; + title = pr.title; + number = pr.number; + type = "pull_request"; + } else { + return; + } + + const commentLink = comment.html_url; + const commentPreview = comment.body.length > 100 ? `${comment.body.substring(0, 100)}...` : comment.body; + + await bot.announce( + botText("e_comment_created", { + commentAuthor: escapeHtml(user.ghDisplayname), + telegramStatus: user.telegramStatus, + repoName: escapeHtml(repository.full_name), + repoHashtag: escapeHtml(repoHashtag), + title: escapeHtml(title), + number: number.toString(), + commentPreview: escapeHtml(commentPreview), + commentLink: escapeHtml(commentLink), + ghProfileUrl: escapeHtml(user.ghProfileUrl), + type, + }), + { link_preview_options: { prefer_small_media: true, url: commentLink } }, + ); +}; diff --git a/src/lib/github/webhooks/index.ts b/src/lib/github/webhooks/index.ts index b464b70..ef27563 100644 --- a/src/lib/github/webhooks/index.ts +++ b/src/lib/github/webhooks/index.ts @@ -1,6 +1,7 @@ import { Webhooks } from "@octokit/webhooks"; import { config } from "#config"; +import { commentCreatedCallback } from "./handlers/comment-created.ts"; import { issuesAssignedCallback } from "./handlers/issues-assigned.ts"; import { issuesOpenedCallback } from "./handlers/issues-opened.ts"; import { projectItemEditedCallback } from "./handlers/projects-item-edited.ts"; @@ -20,4 +21,6 @@ webhooks.on("pull_request.opened", withGuards(pullRequestOpenedCallback)); webhooks.on("release.created", withGuards(releaseCreatedCallback)); webhooks.on("repository.created", withGuards(repositoryCreatedCallback)); webhooks.on("star.created", withGuards(starCreatedCallback)); -webhooks.on("projects_v2_item.edited", withGuards(projectItemEditedCallback, { skipRepositoryCheck: true })); +webhooks.on("issue_comment.created", withGuards(commentCreatedCallback)); +webhooks.on("pull_request_review_comment.created", withGuards(commentCreatedCallback)); +webhooks.on("projects_v2_item.edited", withGuards(projectItemEditedCallback));