mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-21 06:24:59 +00:00
fix(telegram): move network fallback to resolver-scoped dispatchers (#40740)
Merged via squash.
Prepared head SHA: a4456d48b4
Co-authored-by: sircrumpet <4436535+sircrumpet@users.noreply.github.com>
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Reviewed-by: @obviyus
This commit is contained in:
@@ -293,6 +293,62 @@ describe("resolveMedia getFile retry", () => {
|
||||
expect(getFile).toHaveBeenCalledTimes(3);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it("uses caller-provided fetch impl for file downloads", async () => {
|
||||
const getFile = vi.fn().mockResolvedValue({ file_path: "documents/file_42.pdf" });
|
||||
const callerFetch = vi.fn() as unknown as typeof fetch;
|
||||
fetchRemoteMedia.mockResolvedValueOnce({
|
||||
buffer: Buffer.from("pdf-data"),
|
||||
contentType: "application/pdf",
|
||||
fileName: "file_42.pdf",
|
||||
});
|
||||
saveMediaBuffer.mockResolvedValueOnce({
|
||||
path: "/tmp/file_42---uuid.pdf",
|
||||
contentType: "application/pdf",
|
||||
});
|
||||
|
||||
const result = await resolveMedia(
|
||||
makeCtx("document", getFile),
|
||||
MAX_MEDIA_BYTES,
|
||||
BOT_TOKEN,
|
||||
callerFetch,
|
||||
);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(fetchRemoteMedia).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
fetchImpl: callerFetch,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("uses caller-provided fetch impl for sticker downloads", async () => {
|
||||
const getFile = vi.fn().mockResolvedValue({ file_path: "stickers/file_0.webp" });
|
||||
const callerFetch = vi.fn() as unknown as typeof fetch;
|
||||
fetchRemoteMedia.mockResolvedValueOnce({
|
||||
buffer: Buffer.from("sticker-data"),
|
||||
contentType: "image/webp",
|
||||
fileName: "file_0.webp",
|
||||
});
|
||||
saveMediaBuffer.mockResolvedValueOnce({
|
||||
path: "/tmp/file_0.webp",
|
||||
contentType: "image/webp",
|
||||
});
|
||||
|
||||
const result = await resolveMedia(
|
||||
makeCtx("sticker", getFile),
|
||||
MAX_MEDIA_BYTES,
|
||||
BOT_TOKEN,
|
||||
callerFetch,
|
||||
);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(fetchRemoteMedia).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
fetchImpl: callerFetch,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveMedia original filename preservation", () => {
|
||||
|
||||
@@ -92,12 +92,20 @@ async function resolveTelegramFileWithRetry(
|
||||
}
|
||||
}
|
||||
|
||||
function resolveRequiredFetchImpl(proxyFetch?: typeof fetch): typeof fetch {
|
||||
const fetchImpl = proxyFetch ?? globalThis.fetch;
|
||||
if (!fetchImpl) {
|
||||
function resolveRequiredFetchImpl(fetchImpl?: typeof fetch): typeof fetch {
|
||||
const resolved = fetchImpl ?? globalThis.fetch;
|
||||
if (!resolved) {
|
||||
throw new Error("fetch is not available; set channels.telegram.proxy in config");
|
||||
}
|
||||
return fetchImpl;
|
||||
return resolved;
|
||||
}
|
||||
|
||||
function resolveOptionalFetchImpl(fetchImpl?: typeof fetch): typeof fetch | null {
|
||||
try {
|
||||
return resolveRequiredFetchImpl(fetchImpl);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Default idle timeout for Telegram media downloads (30 seconds). */
|
||||
@@ -134,7 +142,7 @@ async function resolveStickerMedia(params: {
|
||||
ctx: TelegramContext;
|
||||
maxBytes: number;
|
||||
token: string;
|
||||
proxyFetch?: typeof fetch;
|
||||
fetchImpl?: typeof fetch;
|
||||
}): Promise<
|
||||
| {
|
||||
path: string;
|
||||
@@ -145,7 +153,7 @@ async function resolveStickerMedia(params: {
|
||||
| null
|
||||
| undefined
|
||||
> {
|
||||
const { msg, ctx, maxBytes, token, proxyFetch } = params;
|
||||
const { msg, ctx, maxBytes, token, fetchImpl } = params;
|
||||
if (!msg.sticker) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -165,15 +173,15 @@ async function resolveStickerMedia(params: {
|
||||
logVerbose("telegram: getFile returned no file_path for sticker");
|
||||
return null;
|
||||
}
|
||||
const fetchImpl = proxyFetch ?? globalThis.fetch;
|
||||
if (!fetchImpl) {
|
||||
const resolvedFetchImpl = resolveOptionalFetchImpl(fetchImpl);
|
||||
if (!resolvedFetchImpl) {
|
||||
logVerbose("telegram: fetch not available for sticker download");
|
||||
return null;
|
||||
}
|
||||
const saved = await downloadAndSaveTelegramFile({
|
||||
filePath: file.file_path,
|
||||
token,
|
||||
fetchImpl,
|
||||
fetchImpl: resolvedFetchImpl,
|
||||
maxBytes,
|
||||
});
|
||||
|
||||
@@ -229,7 +237,7 @@ export async function resolveMedia(
|
||||
ctx: TelegramContext,
|
||||
maxBytes: number,
|
||||
token: string,
|
||||
proxyFetch?: typeof fetch,
|
||||
fetchImpl?: typeof fetch,
|
||||
): Promise<{
|
||||
path: string;
|
||||
contentType?: string;
|
||||
@@ -242,7 +250,7 @@ export async function resolveMedia(
|
||||
ctx,
|
||||
maxBytes,
|
||||
token,
|
||||
proxyFetch,
|
||||
fetchImpl,
|
||||
});
|
||||
if (stickerResolved !== undefined) {
|
||||
return stickerResolved;
|
||||
@@ -263,7 +271,7 @@ export async function resolveMedia(
|
||||
const saved = await downloadAndSaveTelegramFile({
|
||||
filePath: file.file_path,
|
||||
token,
|
||||
fetchImpl: resolveRequiredFetchImpl(proxyFetch),
|
||||
fetchImpl: resolveRequiredFetchImpl(fetchImpl),
|
||||
maxBytes,
|
||||
telegramFileName: resolveTelegramFileName(msg),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user