diff --git a/src/modules/denim-Dobroty.ts b/src/modules/denim-Dobroty.ts index f8ad735..30d4e4c 100644 --- a/src/modules/denim-Dobroty.ts +++ b/src/modules/denim-Dobroty.ts @@ -5,7 +5,7 @@ import { join } from "path"; import { Priority, novejPlay } from "../utils/voice"; import { lidiCoMajDenimPremium } from "../utils/denim-Spravce"; import { exec } from "child_process"; -import { log, messageReply } from "../utils/utils"; +import { betterFetch, log, messageReply } from "../utils/utils"; const kmenovaCesta = join(__dirname, `../../zvuky/priVstupu`); const formaty = ["mp3", "wav", "ogg"]; @@ -34,7 +34,7 @@ const exp: Modul = { const typ = soubor.name.slice(-3); const docasnaCesta = `${kmenovaCesta}/temp${Math.round(Math.random() * 1000)}.${typ}`; - const odpoved = await fetch(soubor.url).then(r => r.arrayBuffer()); + const odpoved = await betterFetch(soubor.url).then(r => r.arrayBuffer()); writeFileSync(docasnaCesta, new DataView(odpoved)); // Zjistit running-time diff --git a/src/modules/magazin.ts b/src/modules/magazin.ts index 571aae2..494345e 100644 --- a/src/modules/magazin.ts +++ b/src/modules/magazin.ts @@ -1,6 +1,6 @@ import { TextChannel } from "discord.js"; import { CClient, Modul } from "../utils/types"; -import { log, sendWithoutReply } from "../utils/utils"; +import { betterFetch, log, sendWithoutReply } from "../utils/utils"; let client: CClient; @@ -10,7 +10,7 @@ let posledniNazev: string; let posledniOdkaz: string; async function zkontrolovatNovinky() { - const stranka = await fetch("https://histmy.eu/BUM/clanky") + const stranka = await betterFetch("https://histmy.eu/BUM/clanky") .then(r => r.text()) .catch(e => log("chyba pri accessovani BUM stránky", e)); diff --git a/src/modules/muzika.ts b/src/modules/muzika.ts index 4461be0..8e70e71 100644 --- a/src/modules/muzika.ts +++ b/src/modules/muzika.ts @@ -6,7 +6,7 @@ import { search, validate, video_basic_info } from "play-dl"; import ytdlko from "@distube/ytdl-core"; import { emouty } from "../utils/emotes"; import { Modul } from "../utils/types"; -import { adminLog, log, messageReply } from "../utils/utils"; +import { adminLog, betterFetch, log, messageReply } from "../utils/utils"; import { getConn, Hratelny, novejJoin, novejPlay, Priority, stopPlayer } from "../utils/voice"; import { array, record, safeParse, string } from "valibot"; @@ -216,7 +216,7 @@ const exp: Modul = { const nameSplited = kju[0].name.split("-"); const query = nameSplited[1] ?? kju[0].name; - const res = await fetch(`https://search.karaoketexty.cz/index.php?q=${query}`) + const res = await betterFetch(`https://search.karaoketexty.cz/index.php?q=${query}`) .then(res => res.text()) .catch(log); @@ -238,7 +238,7 @@ const exp: Modul = { if (!vysledek) return "KaraokeTexty nic nenasli"; - const res2 = await fetch(`https://www.karaoketexty.cz/texty-pisni/h/h-${vysledek.id}`) + const res2 = await betterFetch(`https://www.karaoketexty.cz/texty-pisni/h/h-${vysledek.id}`) .then(res => res.text()) .catch(log); diff --git a/src/modules/status.ts b/src/modules/status.ts index bfb2098..2911e01 100644 --- a/src/modules/status.ts +++ b/src/modules/status.ts @@ -1,7 +1,7 @@ // Trekování statusů všech lidí o kterých bot ví import { Client, Guild, Presence } from "discord.js"; import { FakePresence, Modul, SRecord, StatusyINaFounu, UserChange, ZmenovejObjekt } from "../utils/types"; -import { adminLog, log } from "../utils/utils"; +import { adminLog, betterFetch, log } from "../utils/utils"; const statusy = { Offline: "0", Online: "1", Idle: "2", DND: "3", OnlinePhone: "11", IdlePhone: "12", DNDPhone: "13" }; const prepSend = (zmeny: UserChange[]) => { @@ -25,7 +25,7 @@ const prepSend = (zmeny: UserChange[]) => { const poslatData = (data: SRecord) => { data.pwd = process.env.statPass; - fetch("http://deadfish.cz:4629/endpoint-pro-denimka/", { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) + betterFetch("http://deadfish.cz:4629/endpoint-pro-denimka/", { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .catch(err => { log("err:", err); const client: Client = module.exports.client; diff --git a/src/modules/vordinace.ts b/src/modules/vordinace.ts index db977ce..015b8cc 100644 --- a/src/modules/vordinace.ts +++ b/src/modules/vordinace.ts @@ -1,6 +1,6 @@ import { GuildScheduledEventEntityType, GuildScheduledEventPrivacyLevel, TextChannel } from "discord.js"; import { CClient, Modul } from "../utils/types"; -import { log, sendWithoutReply } from "../utils/utils"; +import { betterFetch, log, sendWithoutReply } from "../utils/utils"; import { RawData, WebSocket } from "ws"; import { emouty } from "../utils/emotes"; @@ -50,7 +50,7 @@ async function udelejOneplayRquest(cesta: string, body: string) { throw new Error("token more"); } - const res = await fetch(`https://http.cms.jyxo.cz/api/v3/${cesta}`, { + const res = await betterFetch(`https://http.cms.jyxo.cz/api/v3/${cesta}`, { method: "POST", body, headers: { Authorization: token } diff --git a/src/modules/zbytek.ts b/src/modules/zbytek.ts index 8c7578a..c1d1930 100644 --- a/src/modules/zbytek.ts +++ b/src/modules/zbytek.ts @@ -4,7 +4,7 @@ import { getVoiceConnections } from "@discordjs/voice"; import { Client } from "discord.js"; import { createServer } from "http"; import { Modul } from "../utils/types"; -import { adminLog, formatCas, log, nabidni, messageReply, sendDM, sendWithoutReply } from "../utils/utils"; +import { adminLog, formatCas, log, nabidni, messageReply, sendDM, sendWithoutReply, betterFetch } from "../utils/utils"; import { emouty } from "../utils/emotes"; import { readFileSync } from "fs"; @@ -28,7 +28,7 @@ const exp: Modul = { run: async mes => { const sudo = mes.channel.id == process.env.adminChannel || mes.author.id == process.env.adminID; if (!sudo) { - const verze = await fetch("https://gitea.deadfish.cz/Histmy/Denim-Bot/raw/branch/main/package.json") + const verze = await betterFetch("https://gitea.deadfish.cz/Histmy/Denim-Bot/raw/branch/main/package.json") .then(r => r.json()) .then(d => d.version) .catch(e => { diff --git a/src/utils/denim-Spravce.ts b/src/utils/denim-Spravce.ts index 5d78366..f129c5f 100644 --- a/src/utils/denim-Spravce.ts +++ b/src/utils/denim-Spravce.ts @@ -1,5 +1,5 @@ import { array, safeParse, string } from "valibot"; -import { adminLog, log } from "./utils"; +import { adminLog, betterFetch, log } from "./utils"; import { Client } from "discord.js"; let client: Client; @@ -20,7 +20,7 @@ function naplanovat() { } async function sync() { - const res = await fetch("https://util.deadfish.cz/denim+/subscriptions.json") + const res = await betterFetch("https://util.deadfish.cz/denim+/subscriptions.json") .then(r => r.json()) .catch(e => log("chyba pri ziskavani denim- predplatitelu", e)); diff --git a/src/utils/sachyServer.ts b/src/utils/sachyServer.ts index aa208de..f687017 100644 --- a/src/utils/sachyServer.ts +++ b/src/utils/sachyServer.ts @@ -5,7 +5,7 @@ import { SRecord } from "./types"; import { join } from "path"; import { readFileSync } from "fs"; import { TypedEmitter } from "tiny-typed-emitter"; -import { log } from "./utils"; +import { betterFetch, log } from "./utils"; const basePath = join(__dirname, "../../res/sachy"); const sessions: SRecord = {}; @@ -106,13 +106,13 @@ function loginErr(res: ServerResponse) { async function overeni(url: URL, session: Session, res: ServerResponse) { const code = url.searchParams.get("code"); - const data = await fetch("https://discord.com/api/v10/oauth2/token", { method: "post", body: `client_id=1064269692165963826&client_secret=8HHKODmb1HTLWoJGVyoinSU_9323dEla&grant_type=authorization_code&code=${code}&redirect_uri=http%3A%2F%2F${encodeURIComponent(sachyDomena)}%2Foauth`, headers: { "Content-type": "application/x-www-form-urlencoded" } }) + const data = await betterFetch("https://discord.com/api/v10/oauth2/token", { method: "post", body: `client_id=1064269692165963826&client_secret=8HHKODmb1HTLWoJGVyoinSU_9323dEla&grant_type=authorization_code&code=${code}&redirect_uri=http%3A%2F%2F${encodeURIComponent(sachyDomena)}%2Foauth`, headers: { "Content-type": "application/x-www-form-urlencoded" } }) .then(r => r.json()) .catch(err => log("sachy jednotka:", err)); if (!data?.access_token) return loginErr(res); - const uzivatel = await fetch("https://discord.com/api/v10/users/@me", { headers: { authorization: `Bearer ${data.access_token}` } }) + const uzivatel = await betterFetch("https://discord.com/api/v10/users/@me", { headers: { authorization: `Bearer ${data.access_token}` } }) .then(r => r.json()) .catch(err => log("sachy dva:", err)); diff --git a/src/utils/utils.ts b/src/utils/utils.ts index e2b1f92..c1137be 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -285,3 +285,19 @@ export const areStatusesSame = (object1?: ClientPresenceStatusData | null, objec } return true; }; + +export async function betterFetch(url: string, options?: RequestInit) { + const maxRetry = 5; + const retryWait = 3_000; + + for (let currentAttempt = 1; currentAttempt < maxRetry; currentAttempt++) { + try { + return await fetch(url, options); + } catch (err) { + log(`Chyba při stahování ${url}, pokus číslo ${currentAttempt}, čekám ${retryWait / 1000} sekund`); + await new Promise(r => setTimeout(r, retryWait)); + } + } + + throw new Error(`Nepodařilo se stáhnout ${url} ani na ${maxRetry} pokusů`); +}