diff --git a/locales/en.ftl b/locales/en.ftl
index aff30f4..648d79d 100644
--- a/locales/en.ftl
+++ b/locales/en.ftl
@@ -161,7 +161,7 @@ cmd_unmute = 🔊 User unMuted successfully!
e_issue_opened =
🔘 Issue: { $issueTitle }.
- 👤 Author: { $user }
+ 👤 Author: { $user } { $telegramStatus }
— { $issueUrl }
@@ -170,7 +170,7 @@ e_issue_opened =
e_pull_request_closed_merged =
🌳 PR Merged!
- 👤 Author: { $user }
+ 👤 Author: { $user } { $telegramStatus }
— { $prUrl }
@@ -179,7 +179,7 @@ e_pull_request_closed_merged =
e_pull_request_opened =
🌴 PR Created: { $prTitle }
- 👤 Author: { $user }!
+ 👤 Author: { $user } { $telegramStatus }!
— { $prUrl }
@@ -211,14 +211,14 @@ e_repository_created =
{ $repoHashtag } #new_repo
e_star_created =
- 🌟 { $user } gave star number { $starNumber } to { $repoName }.
+ 🌟 { $user } { $telegramStatus } gave star number { $starNumber } to { $repoName }.
{ $repoHashtag } #star
e_issue_assigned =
👥 Issue Assigned: { $issueTitle }.
- 👤 Assignee: { $assignee }
+ 👤 Assignee: { $assignee } { $telegramStatus }
— { $issueUrl }
diff --git a/src/bot/bot.ts b/src/bot/bot.ts
index 9b8952b..c0cbdd5 100644
--- a/src/bot/bot.ts
+++ b/src/bot/bot.ts
@@ -81,9 +81,7 @@ export class Bot extends GrammyBot {
this.use(userCommands);
- const isAdmin = (ctx: Context) =>
- ctx.from !== undefined &&
- config.bot.adminIds.includes(ctx.from.id);
+ const isAdmin = (ctx: Context) => ctx.from !== undefined && config.bot.adminIds.includes(ctx.from.id);
this.filter(isAdmin).use(adminCommands);
diff --git a/src/bot/commands/private/link.ts b/src/bot/commands/private/link.ts
index a807e5f..08b22aa 100644
--- a/src/bot/commands/private/link.ts
+++ b/src/bot/commands/private/link.ts
@@ -16,8 +16,19 @@ export async function handler(ctx: BotContext>) {
const repliedMessage = ctx.message.reply_to_message;
const isActualReply = repliedMessage && !repliedMessage.forum_topic_created;
- const { ghUsername, tgUsername } = ctx.args;
- const tgId = isActualReply ? repliedMessage.from?.id : null;
+ const { ghUsername } = ctx.args;
+ let { tgUsername } = ctx.args;
+
+ const from = isActualReply ? repliedMessage.from : undefined;
+ const tgId = from?.id ?? null;
+ const tgName = from ? [from.first_name, from.last_name].filter(Boolean).join(" ") : null;
+
+ if (from?.username) {
+ const result = zs.tgUsername.safeParse(from.username);
+ if (result.success) {
+ tgUsername = result.data;
+ }
+ }
if (!tgId && !tgUsername) {
return await ctx.html.replyToMessage(ctx.t("cmd_link_no_user"));
@@ -25,6 +36,7 @@ export async function handler(ctx: BotContext>) {
const set: SQLiteInsertValue = { ghUsername };
if (tgId) set.tgId = tgId;
+ if (tgName) set.tgName = tgName;
if (tgUsername) set.tgUsername = tgUsername;
await db
diff --git a/src/lib/github/webhooks/handlers/_utils.ts b/src/lib/github/webhooks/handlers/_utils.ts
index 8635ca9..92e3bcb 100644
--- a/src/lib/github/webhooks/handlers/_utils.ts
+++ b/src/lib/github/webhooks/handlers/_utils.ts
@@ -4,9 +4,16 @@ import type { components } from "@octokit/openapi-webhooks-types";
import { bot } from "#bot";
import { db, schema } from "#db";
+import { escapeHtml } from "../../../escape-html.ts";
+
export interface User {
- user: string;
- userUrl: string;
+ ghUsername: string;
+ ghProfileUrl: string;
+ ghDisplayname: string;
+ tgId?: number | null;
+ tgUsername?: string | null;
+ tgDisplayName?: string | null;
+ telegramStatus: string;
}
type SimpleUser = Pick;
@@ -35,24 +42,36 @@ export async function isUserMuted(githubUsername: string): Promise {
return !!contributor?.isMuted;
}
-export async function getUser(simpleUser: SimpleUser): Promise {
- const ghUsername = simpleUser.login;
-
- let user = simpleUser.name ?? ghUsername;
- let userUrl = simpleUser.html_url;
+export async function getUser(githubUser: SimpleUser): Promise {
+ const ghUsername = githubUser.login;
- const dbUser = await db.query.contributors.findFirst({
+ const contributor = await db.query.contributors.findFirst({
where: (f, o) => o.eq(f.ghUsername, ghUsername),
});
- if (!dbUser?.ghUsername) {
+ if (!contributor) {
await db.insert(schema.contributors).values({ ghUsername });
}
- if (dbUser?.tgId && dbUser?.tgName) {
- user = dbUser.tgName;
- userUrl = `tg://user?id=${dbUser.tgId}`;
+ let telegramStatus = "(-)";
+ const isLinked = contributor?.tgId || contributor?.tgUsername;
+ if (isLinked) {
+ if (contributor.tgUsername) {
+ telegramStatus = `(@${escapeHtml(contributor.tgUsername)})`;
+ } else if (contributor.tgName) {
+ telegramStatus = `(${escapeHtml(contributor.tgName)})`;
+ } else {
+ telegramStatus = `(-)`;
+ }
}
- return { user, userUrl };
+ return {
+ ghUsername,
+ ghProfileUrl: githubUser.html_url,
+ ghDisplayname: githubUser.name ?? ghUsername,
+ tgId: contributor?.tgId,
+ tgUsername: contributor?.tgUsername,
+ tgDisplayName: contributor?.tgName,
+ telegramStatus,
+ };
}
diff --git a/src/lib/github/webhooks/handlers/issues-assigned.ts b/src/lib/github/webhooks/handlers/issues-assigned.ts
index fb7ed80..79afdd7 100644
--- a/src/lib/github/webhooks/handlers/issues-assigned.ts
+++ b/src/lib/github/webhooks/handlers/issues-assigned.ts
@@ -20,8 +20,9 @@ export const issuesAssignedCallback: HandlerFunction<"issues.assigned", unknown>
await bot.announce(
botText("e_issue_assigned", {
issueTitle: escapeHtml(issue.title),
- assignee: escapeHtml(assignee.user),
- assigneeUrl: assignee.userUrl,
+ assignee: escapeHtml(assignee.ghDisplayname),
+ telegramStatus: assignee.telegramStatus,
+ assigneeUrl: assignee.ghProfileUrl,
issueUrl: issue.html_url,
repoHashtag: escapeHtml(repoHashtag),
}),
diff --git a/src/lib/github/webhooks/handlers/issues-opened.ts b/src/lib/github/webhooks/handlers/issues-opened.ts
index 1112411..76f8483 100644
--- a/src/lib/github/webhooks/handlers/issues-opened.ts
+++ b/src/lib/github/webhooks/handlers/issues-opened.ts
@@ -13,8 +13,9 @@ export const issuesOpenedCallback: HandlerFunction<"issues.opened", unknown> = a
await bot.announce(
botText("e_issue_opened", {
issueTitle: escapeHtml(issue.title),
- user: escapeHtml(user.user),
- userUrl: escapeHtml(user.userUrl),
+ user: escapeHtml(user.ghDisplayname),
+ telegramStatus: user.telegramStatus,
+ userUrl: escapeHtml(user.ghProfileUrl),
issueUrl: escapeHtml(issue.html_url),
repoHashtag: escapeHtml(repoHashtag),
}),
diff --git a/src/lib/github/webhooks/handlers/pull-request-closed.ts b/src/lib/github/webhooks/handlers/pull-request-closed.ts
index c26cacc..44263a5 100644
--- a/src/lib/github/webhooks/handlers/pull-request-closed.ts
+++ b/src/lib/github/webhooks/handlers/pull-request-closed.ts
@@ -14,8 +14,9 @@ export const pullRequestClosedCallback: HandlerFunction<"pull_request.closed", u
await bot.announce(
botText("e_pull_request_closed_merged", {
- user: escapeHtml(user.user),
- userUrl: escapeHtml(user.userUrl),
+ user: escapeHtml(user.ghDisplayname),
+ telegramStatus: user.telegramStatus,
+ userUrl: escapeHtml(user.ghProfileUrl),
prUrl: escapeHtml(pr.html_url),
repoHashtag: escapeHtml(repoHashtag),
}),
diff --git a/src/lib/github/webhooks/handlers/pull-request-opened.ts b/src/lib/github/webhooks/handlers/pull-request-opened.ts
index 278fdc8..4e0c80b 100644
--- a/src/lib/github/webhooks/handlers/pull-request-opened.ts
+++ b/src/lib/github/webhooks/handlers/pull-request-opened.ts
@@ -13,8 +13,9 @@ export const pullRequestOpenedCallback: HandlerFunction<"pull_request.opened", u
await bot.announce(
botText("e_pull_request_opened", {
prTitle: escapeHtml(pr.title),
- user: escapeHtml(user.user),
- userUrl: escapeHtml(user.userUrl),
+ user: escapeHtml(user.ghDisplayname),
+ telegramStatus: user.telegramStatus,
+ userUrl: escapeHtml(user.ghProfileUrl),
prUrl: escapeHtml(pr.html_url),
repoHashtag: escapeHtml(repoHashtag),
}),
diff --git a/src/lib/github/webhooks/handlers/star-created.ts b/src/lib/github/webhooks/handlers/star-created.ts
index 7eeac5f..c30c872 100644
--- a/src/lib/github/webhooks/handlers/star-created.ts
+++ b/src/lib/github/webhooks/handlers/star-created.ts
@@ -7,19 +7,19 @@ import { botText, getRepoHashtag, getUser } from "./_utils.ts";
export const starCreatedCallback: HandlerFunction<"star.created", unknown> = async (event) => {
const user = await getUser(event.payload.sender);
- const githubUrl = event.payload.sender.html_url;
const repo = event.payload.repository;
const repoHashtag = getRepoHashtag(repo.name);
await bot.announce(
botText("e_star_created", {
- user: escapeHtml(user.user),
- userUrl: escapeHtml(githubUrl),
+ user: escapeHtml(user.ghDisplayname),
+ userUrl: escapeHtml(user.ghProfileUrl),
+ telegramStatus: user.telegramStatus,
repoName: escapeHtml(repo.name),
repoUrl: escapeHtml(repo.html_url),
repoHashtag: escapeHtml(repoHashtag),
starNumber: repo.stargazers_count,
}),
- { link_preview_options: { prefer_small_media: true, url: githubUrl } },
+ { link_preview_options: { prefer_small_media: true, url: user.ghProfileUrl } },
);
};