mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-20 21:23:23 +00:00
fix: preserve Telegram local Bot API MIME types (#54603) (thanks @jzakirov)
* fix(telegram): preserve content type for local Bot API media files * fix: preserve Telegram local Bot API MIME types (#54603) (thanks @jzakirov) --------- Co-authored-by: Ayaan Zaidi <hi@obviy.us>
This commit is contained in:
@@ -9,6 +9,10 @@ Docs: https://docs.openclaw.ai
|
||||
- Agents/compaction: resolve `agents.defaults.compaction.model` consistently for manual `/compact` and other context-engine compaction paths, so engine-owned compaction uses the configured override model across runtime entrypoints. (#56710) Thanks @oliviareid-svg
|
||||
- Channels/session routing: move provider-specific session conversation grammar into plugin-owned session-key surfaces, preserving Telegram topic routing and Feishu scoped inheritance across bootstrap, model override, restart, and tool-policy paths.
|
||||
|
||||
### Fixes
|
||||
|
||||
- Telegram/local Bot API: preserve media MIME types for absolute-path downloads so local audio files still trigger transcription and other MIME-based handling. (#54603) Thanks @jzakirov
|
||||
|
||||
## 2026.3.31
|
||||
|
||||
### Breaking
|
||||
|
||||
@@ -40,7 +40,7 @@ const BOT_TOKEN = "tok123";
|
||||
function makeCtx(
|
||||
mediaField: "voice" | "audio" | "photo" | "video" | "document" | "animation" | "sticker",
|
||||
getFile: TelegramContext["getFile"],
|
||||
opts?: { file_name?: string },
|
||||
opts?: { file_name?: string; mime_type?: string },
|
||||
): TelegramContext {
|
||||
const msg: Record<string, unknown> = {
|
||||
message_id: 1,
|
||||
@@ -48,7 +48,12 @@ function makeCtx(
|
||||
chat: { id: 1, type: "private" },
|
||||
};
|
||||
if (mediaField === "voice") {
|
||||
msg.voice = { file_id: "v1", duration: 5, file_unique_id: "u1" };
|
||||
msg.voice = {
|
||||
file_id: "v1",
|
||||
duration: 5,
|
||||
file_unique_id: "u1",
|
||||
...(opts?.mime_type && { mime_type: opts.mime_type }),
|
||||
};
|
||||
}
|
||||
if (mediaField === "audio") {
|
||||
msg.audio = {
|
||||
@@ -56,6 +61,7 @@ function makeCtx(
|
||||
duration: 5,
|
||||
file_unique_id: "u2",
|
||||
...(opts?.file_name && { file_name: opts.file_name }),
|
||||
...(opts?.mime_type && { mime_type: opts.mime_type }),
|
||||
};
|
||||
}
|
||||
if (mediaField === "photo") {
|
||||
@@ -74,6 +80,7 @@ function makeCtx(
|
||||
file_id: "d1",
|
||||
file_unique_id: "u4",
|
||||
...(opts?.file_name && { file_name: opts.file_name }),
|
||||
...(opts?.mime_type && { mime_type: opts.mime_type }),
|
||||
};
|
||||
}
|
||||
if (mediaField === "animation") {
|
||||
@@ -359,13 +366,18 @@ describe("resolveMedia getFile retry", () => {
|
||||
it("uses local absolute file paths directly for media downloads", async () => {
|
||||
const getFile = vi.fn().mockResolvedValue({ file_path: "/var/lib/telegram-bot-api/file.pdf" });
|
||||
|
||||
const result = await resolveMedia(makeCtx("document", getFile), MAX_MEDIA_BYTES, BOT_TOKEN);
|
||||
const result = await resolveMedia(
|
||||
makeCtx("document", getFile, { mime_type: "application/pdf" }),
|
||||
MAX_MEDIA_BYTES,
|
||||
BOT_TOKEN,
|
||||
);
|
||||
|
||||
expect(fetchRemoteMedia).not.toHaveBeenCalled();
|
||||
expect(saveMediaBuffer).not.toHaveBeenCalled();
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
path: "/var/lib/telegram-bot-api/file.pdf",
|
||||
contentType: "application/pdf",
|
||||
placeholder: "<media:document>",
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -90,6 +90,17 @@ function resolveTelegramFileName(msg: TelegramContext["message"]): string | unde
|
||||
);
|
||||
}
|
||||
|
||||
function resolveTelegramMimeType(msg: TelegramContext["message"]): string | undefined {
|
||||
return (
|
||||
msg.audio?.mime_type ??
|
||||
msg.voice?.mime_type ??
|
||||
msg.video?.mime_type ??
|
||||
msg.document?.mime_type ??
|
||||
msg.animation?.mime_type ??
|
||||
undefined
|
||||
);
|
||||
}
|
||||
|
||||
async function resolveTelegramFileWithRetry(
|
||||
ctx: TelegramContext,
|
||||
): Promise<{ file_path?: string } | null> {
|
||||
@@ -152,10 +163,11 @@ async function downloadAndSaveTelegramFile(params: {
|
||||
transport: TelegramTransport;
|
||||
maxBytes: number;
|
||||
telegramFileName?: string;
|
||||
mimeType?: string;
|
||||
apiRoot?: string;
|
||||
}) {
|
||||
if (path.isAbsolute(params.filePath)) {
|
||||
return { path: params.filePath, contentType: undefined };
|
||||
return { path: params.filePath, contentType: params.mimeType };
|
||||
}
|
||||
const apiBase = resolveTelegramApiBase(params.apiRoot);
|
||||
const url = `${apiBase}/file/bot${params.token}/${params.filePath}`;
|
||||
@@ -320,6 +332,7 @@ export async function resolveMedia(
|
||||
transport: resolveRequiredTelegramTransport(transport),
|
||||
maxBytes,
|
||||
telegramFileName: resolveTelegramFileName(msg),
|
||||
mimeType: resolveTelegramMimeType(msg),
|
||||
apiRoot,
|
||||
});
|
||||
const placeholder = resolveTelegramMediaPlaceholder(msg) ?? "<media:document>";
|
||||
|
||||
Reference in New Issue
Block a user