diff --git a/src/auto-reply/templating.ts b/src/auto-reply/templating.ts index 780386d264e..7b0f8ed1e1b 100644 --- a/src/auto-reply/templating.ts +++ b/src/auto-reply/templating.ts @@ -56,6 +56,8 @@ export type MsgContext = { ForwardedFromUsername?: string; ForwardedFromTitle?: string; ForwardedFromSignature?: string; + ForwardedFromChatType?: string; + ForwardedFromMessageId?: number; ForwardedDate?: number; ThreadStarterBody?: string; ThreadLabel?: string; diff --git a/src/telegram/bot-message-context.ts b/src/telegram/bot-message-context.ts index a8c20056efe..d1bcf008838 100644 --- a/src/telegram/bot-message-context.ts +++ b/src/telegram/bot-message-context.ts @@ -598,6 +598,8 @@ export const buildTelegramMessageContext = async ({ ForwardedFromUsername: forwardOrigin?.fromUsername, ForwardedFromTitle: forwardOrigin?.fromTitle, ForwardedFromSignature: forwardOrigin?.fromSignature, + ForwardedFromChatType: forwardOrigin?.fromChatType, + ForwardedFromMessageId: forwardOrigin?.fromMessageId, ForwardedDate: forwardOrigin?.date ? forwardOrigin.date * 1000 : undefined, Timestamp: msg.date ? msg.date * 1000 : undefined, WasMentioned: isGroup ? effectiveWasMentioned : undefined, diff --git a/src/telegram/bot/helpers.test.ts b/src/telegram/bot/helpers.test.ts index 5b74959a64e..ebc774b9270 100644 --- a/src/telegram/bot/helpers.test.ts +++ b/src/telegram/bot/helpers.test.ts @@ -100,6 +100,90 @@ describe("normalizeForwardedContext", () => { expect(ctx?.fromTitle).toBe("Hidden Name"); expect(ctx?.date).toBe(456); }); + + it("handles forward_origin channel with author_signature and message_id", () => { + const ctx = normalizeForwardedContext({ + forward_origin: { + type: "channel", + chat: { + title: "Tech News", + username: "technews", + id: -1001234, + type: "channel", + }, + date: 500, + author_signature: "Editor", + message_id: 42, + }, + // oxlint-disable-next-line typescript/no-explicit-any + } as any); + expect(ctx).not.toBeNull(); + expect(ctx?.from).toBe("Tech News (Editor)"); + expect(ctx?.fromType).toBe("channel"); + expect(ctx?.fromId).toBe("-1001234"); + expect(ctx?.fromUsername).toBe("technews"); + expect(ctx?.fromTitle).toBe("Tech News"); + expect(ctx?.fromSignature).toBe("Editor"); + expect(ctx?.fromChatType).toBe("channel"); + expect(ctx?.fromMessageId).toBe(42); + expect(ctx?.date).toBe(500); + }); + + it("handles forward_origin chat with sender_chat and author_signature", () => { + const ctx = normalizeForwardedContext({ + forward_origin: { + type: "chat", + sender_chat: { + title: "Discussion Group", + id: -1005678, + type: "supergroup", + }, + date: 600, + author_signature: "Admin", + }, + // oxlint-disable-next-line typescript/no-explicit-any + } as any); + expect(ctx).not.toBeNull(); + expect(ctx?.from).toBe("Discussion Group (Admin)"); + expect(ctx?.fromType).toBe("chat"); + expect(ctx?.fromId).toBe("-1005678"); + expect(ctx?.fromTitle).toBe("Discussion Group"); + expect(ctx?.fromSignature).toBe("Admin"); + expect(ctx?.fromChatType).toBe("supergroup"); + expect(ctx?.date).toBe(600); + }); + + it("uses author_signature from forward_origin", () => { + const ctx = normalizeForwardedContext({ + forward_origin: { + type: "channel", + chat: { title: "My Channel", id: -100999, type: "channel" }, + date: 700, + author_signature: "New Sig", + message_id: 1, + }, + // oxlint-disable-next-line typescript/no-explicit-any + } as any); + expect(ctx).not.toBeNull(); + expect(ctx?.fromSignature).toBe("New Sig"); + expect(ctx?.from).toBe("My Channel (New Sig)"); + }); + + it("handles forward_origin channel without author_signature", () => { + const ctx = normalizeForwardedContext({ + forward_origin: { + type: "channel", + chat: { title: "News", id: -100111, type: "channel" }, + date: 900, + message_id: 1, + }, + // oxlint-disable-next-line typescript/no-explicit-any + } as any); + expect(ctx).not.toBeNull(); + expect(ctx?.from).toBe("News"); + expect(ctx?.fromSignature).toBeUndefined(); + expect(ctx?.fromChatType).toBe("channel"); + }); }); describe("expandTextLinks", () => { diff --git a/src/telegram/bot/helpers.ts b/src/telegram/bot/helpers.ts index 05e25cd11d3..af2682ada59 100644 --- a/src/telegram/bot/helpers.ts +++ b/src/telegram/bot/helpers.ts @@ -261,6 +261,10 @@ export type TelegramForwardedContext = { fromUsername?: string; fromTitle?: string; fromSignature?: string; + /** Original chat type from forward_from_chat (e.g. "channel", "supergroup", "group"). */ + fromChatType?: string; + /** Original message ID in the source chat (channel forwards). */ + fromMessageId?: number; }; function normalizeForwardedUserLabel(user: User) { @@ -323,6 +327,7 @@ function buildForwardedContextFromChat(params: { date?: number; type: string; signature?: string; + messageId?: number; }): TelegramForwardedContext | null { const fallbackKind = params.type === "channel" ? "channel" : "chat"; const { display, title, username, id } = normalizeForwardedChatLabel(params.chat, fallbackKind); @@ -331,6 +336,7 @@ function buildForwardedContextFromChat(params: { } const signature = params.signature?.trim() || undefined; const from = signature ? `${display} (${signature})` : display; + const chatType = params.chat.type?.trim() || undefined; return { from, date: params.date, @@ -339,6 +345,8 @@ function buildForwardedContextFromChat(params: { fromUsername: username, fromTitle: title, fromSignature: signature, + fromChatType: chatType, + fromMessageId: params.messageId, }; } @@ -369,6 +377,7 @@ function resolveForwardOrigin(origin: MessageOrigin): TelegramForwardedContext | date: origin.date, type: "channel", signature: origin.author_signature, + messageId: origin.message_id, }); default: // Exhaustiveness guard: if Grammy adds a new MessageOrigin variant,