From 5b8fc68ea2daa16f31de0a75221668854eab9ffe Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Tue, 3 Mar 2026 16:35:28 +0530 Subject: [PATCH] fix(telegram): include reply hook metadata --- src/telegram/bot/delivery.replies.ts | 17 +++++++++++------ src/telegram/bot/delivery.test.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/telegram/bot/delivery.replies.ts b/src/telegram/bot/delivery.replies.ts index 597cf1a5976..b6fef8dd91b 100644 --- a/src/telegram/bot/delivery.replies.ts +++ b/src/telegram/bot/delivery.replies.ts @@ -459,7 +459,12 @@ export async function deliverReplies(params: { }); for (const originalReply of params.replies) { let reply = originalReply; - const hasMedia = Boolean(reply?.mediaUrl) || (reply?.mediaUrls?.length ?? 0) > 0; + const mediaList = reply.mediaUrls?.length + ? reply.mediaUrls + : reply.mediaUrl + ? [reply.mediaUrl] + : []; + const hasMedia = mediaList.length > 0; if (!reply?.text && !hasMedia) { if (reply?.audioAsVoice) { logVerbose("telegram reply has audioAsVoice without media/text; skipping"); @@ -475,6 +480,11 @@ export async function deliverReplies(params: { { to: params.chatId, content: rawContent, + metadata: { + channel: "telegram", + mediaUrls: mediaList, + threadId: params.thread?.id, + }, }, { channelId: "telegram", @@ -495,11 +505,6 @@ export async function deliverReplies(params: { const deliveredCountBeforeReply = progress.deliveredCount; const replyToId = params.replyToMode === "off" ? undefined : resolveTelegramReplyId(reply.replyToId); - const mediaList = reply.mediaUrls?.length - ? reply.mediaUrls - : reply.mediaUrl - ? [reply.mediaUrl] - : []; const telegramData = reply.channelData?.telegram as | { buttons?: TelegramInlineButtons } | undefined; diff --git a/src/telegram/bot/delivery.test.ts b/src/telegram/bot/delivery.test.ts index 26ccd4b006f..50704b0cc4a 100644 --- a/src/telegram/bot/delivery.test.ts +++ b/src/telegram/bot/delivery.test.ts @@ -149,6 +149,34 @@ describe("deliverReplies", () => { ); }); + it("passes media metadata to message_sending hooks", async () => { + messageHookRunner.hasHooks.mockImplementation((name: string) => name === "message_sending"); + + const runtime = createRuntime(false); + const sendPhoto = vi.fn().mockResolvedValue({ message_id: 2, chat: { id: "123" } }); + const bot = createBot({ sendPhoto }); + + mockMediaLoad("photo.jpg", "image/jpeg", "image"); + + await deliverWith({ + replies: [{ text: "caption", mediaUrl: "https://example.com/photo.jpg" }], + runtime, + bot, + }); + + expect(messageHookRunner.runMessageSending).toHaveBeenCalledWith( + expect.objectContaining({ + to: "123", + content: "caption", + metadata: expect.objectContaining({ + channel: "telegram", + mediaUrls: ["https://example.com/photo.jpg"], + }), + }), + expect.objectContaining({ channelId: "telegram", conversationId: "123" }), + ); + }); + it("invokes onVoiceRecording before sending a voice note", async () => { const events: string[] = []; const runtime = createRuntime(false);