fix(telegram): download inbound media via file_path
This commit is contained in:
@@ -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>";
|
||||||
|
|||||||
Reference in New Issue
Block a user