From 125e09ac03aed49010e22696fef91e3e32f7cc9b Mon Sep 17 00:00:00 2001 From: Muhammed Mukhthar CM Date: Tue, 27 Jan 2026 18:15:29 +0000 Subject: [PATCH] telegram-user: require explicit mention in groups --- .../telegram-user/src/monitor/handler.ts | 38 ++++++++++++++++++- extensions/telegram-user/src/monitor/index.ts | 19 +++++++++- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/extensions/telegram-user/src/monitor/handler.ts b/extensions/telegram-user/src/monitor/handler.ts index 61237a2e6..224f3eb73 100644 --- a/extensions/telegram-user/src/monitor/handler.ts +++ b/extensions/telegram-user/src/monitor/handler.ts @@ -23,7 +23,7 @@ type TelegramUserHandlerParams = { accountId: string; accountConfig: TelegramUserAccountConfig; abortSignal?: AbortSignal; - self?: { id: number; username?: string | null }; + self?: { id: number; username?: string | null; name?: string | null }; }; function normalizeAllowEntry(raw: string): string { @@ -84,6 +84,37 @@ function isClientDestroyed(client: TelegramClient): boolean { return candidate.destroyed === true; } +function escapeRegExp(text: string): string { + return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + +function buildTelegramUserSelfMentionRegexes(params: { + username?: string | null; + name?: string | null; +}): RegExp[] { + const patterns: string[] = []; + const username = params.username?.trim().replace(/^@/, ""); + if (username) { + patterns.push(String.raw`\b@?${escapeRegExp(username)}\b`); + } + const name = params.name?.trim(); + if (name) { + const parts = name.split(/\s+/).filter(Boolean).map(escapeRegExp); + if (parts.length > 0) { + patterns.push(String.raw`\b@?${parts.join(String.raw`\s+`)}\b`); + } + } + return patterns + .map((pattern) => { + try { + return new RegExp(pattern, "i"); + } catch { + return null; + } + }) + .filter((entry): entry is RegExp => Boolean(entry)); +} + async function safeSendTyping(params: { client: TelegramClient; target: number | string; @@ -452,7 +483,10 @@ export function createTelegramUserMessageHandler(params: TelegramUserHandlerPara id: isGroup && groupPeerId ? groupPeerId : senderId, }, }); - const mentionRegexes = core.channel.mentions.buildMentionRegexes(cfg, route.agentId); + const mentionRegexes = [ + ...core.channel.mentions.buildMentionRegexes(cfg, route.agentId), + ...buildTelegramUserSelfMentionRegexes({ username: self?.username, name: self?.name }), + ]; const hasAnyMention = msg.entities.some( (ent) => ent.kind === "mention" || ent.kind === "text_mention", ); diff --git a/extensions/telegram-user/src/monitor/index.ts b/extensions/telegram-user/src/monitor/index.ts index c9742c7dc..1110c56b9 100644 --- a/extensions/telegram-user/src/monitor/index.ts +++ b/extensions/telegram-user/src/monitor/index.ts @@ -86,6 +86,19 @@ export async function monitorTelegramUserProvider(opts: MonitorTelegramUserOpts const { Dispatcher, filters } = await loadMtcuteDispatcher(); const dispatcher = Dispatcher.for(client); const self = await client.getMe().catch(() => undefined); + const selfName = + self && typeof (self as unknown as { displayName?: unknown }).displayName === "string" + ? (self as unknown as { displayName: string }).displayName + : self && typeof (self as unknown as { firstName?: unknown }).firstName === "string" + ? [ + (self as unknown as { firstName?: string }).firstName, + typeof (self as unknown as { lastName?: unknown }).lastName === "string" + ? (self as unknown as { lastName: string }).lastName + : undefined, + ] + .filter((entry): entry is string => Boolean(entry && entry.trim())) + .join(" ") + : undefined; const handleMessage = createTelegramUserMessageHandler({ client, cfg, @@ -94,7 +107,11 @@ export async function monitorTelegramUserProvider(opts: MonitorTelegramUserOpts accountConfig: account.config, abortSignal: opts.abortSignal, self: self - ? { id: self.id, username: "username" in self ? self.username : undefined } + ? { + id: self.id, + username: "username" in self ? self.username : undefined, + name: selfName, + } : undefined, });