From 434a6e2e5084e902cee969017fa47130b0931ccd Mon Sep 17 00:00:00 2001 From: ziad Date: Sun, 12 Jul 2026 12:55:39 +1000 Subject: [PATCH] Fall back to document.thumb for videos sent as a Telegram document MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit extractTelegramFileIds only read raw.video?.thumb, so videos sent as a Telegram "document" (to skip compression) never got a thumbnail — Telegram puts those under message.document, whose thumb was never checked. Minted tokens for document-uploaded videos ended up with no preview image as a result. Co-Authored-By: Claude Sonnet 5 --- .../__tests__/extractTelegramFileIds.test.ts | 40 +++++++++++++++++++ .../chat/attachment/extractTelegramFileIds.ts | 5 ++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/lib/telegram/chat/attachment/__tests__/extractTelegramFileIds.test.ts b/src/lib/telegram/chat/attachment/__tests__/extractTelegramFileIds.test.ts index a1385622..bba5b392 100644 --- a/src/lib/telegram/chat/attachment/__tests__/extractTelegramFileIds.test.ts +++ b/src/lib/telegram/chat/attachment/__tests__/extractTelegramFileIds.test.ts @@ -67,6 +67,46 @@ describe('extractTelegramFileIds', () => { expect(fileId).toBe('document_id'); expect(thumbFileId).toBeUndefined(); }); + + it('extracts thumbFileId when a video sent as a document has a thumb', () => { + const message = { + raw: { + document: { file_id: 'document_id', thumb: { file_id: 'thumb_id' } }, + }, + }; + const { fileId, thumbFileId } = extractTelegramFileIds( + message as never, + attachment('document_id') + ); + expect(fileId).toBe('document_id'); + expect(thumbFileId).toBe('thumb_id'); + }); + + it('returns undefined thumbFileId when the document has no thumb', () => { + const message = { raw: { document: { file_id: 'document_id' } } }; + const { thumbFileId } = extractTelegramFileIds( + message as never, + attachment('document_id') + ); + expect(thumbFileId).toBeUndefined(); + }); + + it('prefers video.thumb over document.thumb when both are present', () => { + const message = { + raw: { + video: { file_id: 'video_id', thumb: { file_id: 'video_thumb_id' } }, + document: { + file_id: 'video_id', + thumb: { file_id: 'document_thumb_id' }, + }, + }, + }; + const { thumbFileId } = extractTelegramFileIds( + message as never, + attachment('video_id') + ); + expect(thumbFileId).toBe('video_thumb_id'); + }); }); describe('missing media', () => { diff --git a/src/lib/telegram/chat/attachment/extractTelegramFileIds.ts b/src/lib/telegram/chat/attachment/extractTelegramFileIds.ts index dd4c2b0b..673e13f3 100644 --- a/src/lib/telegram/chat/attachment/extractTelegramFileIds.ts +++ b/src/lib/telegram/chat/attachment/extractTelegramFileIds.ts @@ -11,8 +11,11 @@ const extractTelegramFileIds = ( const raw = message.raw as { video?: { thumb?: { file_id: string } }; + document?: { thumb?: { file_id: string } }; }; - const thumbFileId = raw.video?.thumb?.file_id; + // A video sent as a Telegram "document" (to skip compression) carries its + // thumbnail under `document.thumb`, not `video.thumb`. + const thumbFileId = raw.video?.thumb?.file_id ?? raw.document?.thumb?.file_id; return { fileId, thumbFileId }; };