From d39c236d5c66a97bcdfce3497d2ef3c0b5e71c3a Mon Sep 17 00:00:00 2001 From: Damir Modyarov Date: Tue, 30 Apr 2024 12:51:08 +0300 Subject: [PATCH] feat: Implement API_BASE_URL fallback --- src/env.ts | 5 ++++- src/request.ts | 25 ++++++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/env.ts b/src/env.ts index 6386942..acb7270 100644 --- a/src/env.ts +++ b/src/env.ts @@ -8,7 +8,10 @@ export const env = createEnv({ server: { BOT_TOKEN: z.string(), INLINE_FIX_CHAT_ID: z.coerce.number().int(), - API_BASE_URL: z.string().url().default("https://co.wuk.sh/api"), + API_BASE_URL: z.string() + .default("https://co.wuk.sh/api") + .transform(s => s.split(";")) + .pipe(z.array(z.string().url())), SELECT_TYPE_PHOTO_URL: z.string().url().default("https://i.otomir23.me/buckets/cobold/download.png"), ERROR_CHAT_ID: z.coerce.number().int().optional(), }, diff --git a/src/request.ts b/src/request.ts index 2ca8419..1ba7020 100644 --- a/src/request.ts +++ b/src/request.ts @@ -31,9 +31,17 @@ const mediaResponseSchema = z.discriminatedUnion("status", [ ]) export const fetchMedia = async ( - { url, lang, isAudioOnly = false }: { url: string, lang?: string, isAudioOnly?: boolean }, -) => { - const res = await fetch(`${env.API_BASE_URL}/json`, { + { url, lang, isAudioOnly = false, fails = [] }: { + url: string, + lang?: string, + isAudioOnly?: boolean, + fails?: number[], + }, +): Promise> => { + if (fails.length >= env.API_BASE_URL.length) + throw new Error(`fetch failed with ${fails}`) + + const res = await fetch(`${env.API_BASE_URL[fails.length]}/json`, { method: "POST", headers: [ ["Accept", "application/json"], @@ -41,9 +49,16 @@ export const fetchMedia = async ( ...lang ? [["Accept-Language", lang] satisfies [string, string]] : [], ], body: JSON.stringify({ url, isAudioOnly, filenamePattern: "basic", isNoTTWatermark: true }), - }).then(r => r.json() as unknown) + }) + if (res.status >= 500) { + return await fetchMedia( + { url, lang, isAudioOnly, fails: [...fails, res.status] }, + ) + } + + const body = await res.json() - return mediaResponseSchema.parse(res) + return mediaResponseSchema.parse(body) } // Stream