fix(telegram): download inbound media via file_path

This commit is contained in:
Peter Steinberger
2025-12-13 16:18:44 +00:00
parent 99660db73f
commit 237933069e

View File

@@ -26,11 +26,8 @@ type TelegramMessage = Message.CommonMessage;
type TelegramContext = { type TelegramContext = {
message: TelegramMessage; message: TelegramMessage;
me?: { username?: string; token?: string }; me?: { username?: string };
api?: { token?: string };
getFile: () => Promise<{ getFile: () => Promise<{
getUrl?: (token?: string) => string | Promise<string>;
download: () => Promise<Uint8Array | ArrayBuffer>;
file_path?: string; file_path?: string;
}>; }>;
}; };
@@ -113,7 +110,12 @@ export function createTelegramBot(opts: TelegramBotOptions) {
return; return;
} }
const media = await resolveMedia(ctx, mediaMaxBytes); const media = await resolveMedia(
ctx,
mediaMaxBytes,
opts.token,
opts.proxyFetch,
);
const rawBody = ( const rawBody = (
msg.text ?? msg.text ??
msg.caption ?? msg.caption ??
@@ -290,6 +292,8 @@ function hasBotMention(msg: TelegramMessage, botUsername: string) {
async function resolveMedia( async function resolveMedia(
ctx: TelegramContext, ctx: TelegramContext,
maxBytes: number, maxBytes: number,
token: string,
proxyFetch?: typeof fetch,
): Promise<{ path: string; contentType?: string; placeholder: string } | null> { ): Promise<{ path: string; contentType?: string; placeholder: string } | null> {
const msg = ctx.message; const msg = ctx.message;
const m = const m =
@@ -300,17 +304,25 @@ async function resolveMedia(
msg.voice; msg.voice;
if (!m?.file_id) return null; if (!m?.file_id) return null;
const file = await ctx.getFile(); const file = await ctx.getFile();
const url = if (!file.file_path) {
typeof file.getUrl === "function" throw new Error("Telegram getFile returned no file_path");
? file.getUrl(ctx.me?.token ?? ctx.api?.token ?? undefined) }
: undefined; const fetchImpl = proxyFetch ?? globalThis.fetch;
const data = if (!fetchImpl) {
url && typeof fetch !== "undefined" throw new Error("fetch is not available; set telegram.proxy in config");
? Buffer.from(await (await fetch(url)).arrayBuffer()) }
: Buffer.from(await file.download()); const url = `https://api.telegram.org/file/bot${token}/${file.file_path}`;
const res = await fetchImpl(url);
if (!res.ok) {
throw new Error(
`Failed to download telegram file: HTTP ${res.status} ${res.statusText}`,
);
}
const data = Buffer.from(await res.arrayBuffer());
const mime = detectMime({ const mime = detectMime({
buffer: data, buffer: data,
filePath: file.file_path ?? undefined, headerMime: res.headers.get("content-type"),
filePath: file.file_path,
}); });
const saved = await saveMediaBuffer(data, mime, "inbound", maxBytes); const saved = await saveMediaBuffer(data, mime, "inbound", maxBytes);
let placeholder = "<media:document>"; let placeholder = "<media:document>";