import { GuildScheduledEventEntityType, GuildScheduledEventPrivacyLevel, TextChannel } from "discord.js"; import { CClient, Modul } from "../utils/types"; import { betterFetch, log, sendWithoutReply } from "../utils/utils"; import { RawData, WebSocket } from "ws"; import { emouty } from "../utils/emotes"; let client: CClient; const logg = (...cokoli: any[]) => log("[OnePlayDownloader]: ", ...cokoli); const token = process.env.OnePlayToken; let canForceNotify = true; function createOneplayBody(payload: Record, customData: string, clientId: string, sessionId: string, serverId: string) { const vec = { "deviceInfo": { "deviceType": "web", "appVersion": "R11.35", "deviceManufacturer": "Unknown", "deviceOs": "Windows" }, "capabilities": { "async": "websockets" }, "payload": payload, "context": { "customData": customData, "requestId": crypto.randomUUID(), "clientId": clientId, "sessionId": sessionId, "serverId": serverId } }; return JSON.stringify(vec); } async function udelejOneplayRquest(cesta: string, body: string) { if (!token) { throw new Error("token more"); } let ok = false; const res = await betterFetch(`https://http.cms.jyxo.cz/api/v1.11/${cesta}`, { method: "POST", body, headers: { Authorization: token } }).then(res => { ok = res.ok; return res.json(); }) .catch(e => { throw new Error(`chyba pri udelejoneplayrequest fetch ${e}`); }); logg(`nejspis ${ok ? "" : "ne"}uspesna odpoved`, res); return res; } const getServerInfo = (socket: WebSocket) => new Promise<[string, string]>((res, rej) => { const listener = (m: RawData) => { const json = JSON.parse(m.toString()); logg("celyjson je", json); if (json.result?.schema == "ConnectionInitData") { clearTimeout(timeout); socket.off("message", listener); res([json.data.serverId, json.data.sessionId]); } }; const timeout = setTimeout(() => { socket.off("message", listener); // Odstraníme posluchač rej(new Error("Časový limit vypršel, jméno nebylo přijato.")); }, 10000); // Timeout 10 sekund socket.on("message", listener); }); async function ziskatNazev() { // Tak tohle stojí fakt za hovno oproti voyu :sjeta: // Ale bejvalo to mnohem horší :sjeta: const clientId = crypto.randomUUID(); logg("moje Ws id je", clientId); let socket: WebSocket | null = null; try { socket = new WebSocket(`wss://ws.cms.jyxo.cz/websocket/${clientId}`); const [serverId, sessionId] = await getServerInfo(socket); const output = await udelejOneplayRquest("carousel.display", createOneplayBody({ carouselId: "show:1;tab:65;parent:64;carousel:65", criteria: { filterCriterias: "season:117525", sortOption: "DESC" } }, `{"blockId":"show:1;tab:65;parent:64;block:65"}`, clientId, sessionId, serverId)); const nazev = output?.data?.carousel?.tiles?.[0]?.title; if (!nazev) { throw new Error("nazev neexistuje"); } if (typeof nazev != "string") { throw new Error("nazev neni string"); } return nazev; } catch (e) { logg("nazev ordinace se nepodarilo ziskat", e); throw new Error("nazev neni"); } finally { socket?.close(); logg("zavrel jsem soket"); } } async function naplanovat() { const datum = new Date(); const den = datum.getDay(); if (!(den == 1 && datum.getHours() < 13)) datum.setDate(datum.getDate() + ((den == 0 ? 1 : 8) - den)); datum.setHours(13); datum.setMinutes(0); datum.setSeconds(1); setTimeout(urobit, Number(datum) - Number(new Date())); } async function urobit() { canForceNotify = true; // Hádám, kdyby se to nějak nepovedlo a bot nespadnul, aby se to dalo znovu spustit const guilda = client.guilds.cache.get("555779161067749446"); if (!guilda) return log(new Error("dobytcarna nenalezena")); const kdyToBude = new Date(); kdyToBude.setHours(20); kdyToBude.setMinutes(0); kdyToBude.setSeconds(0); let nazev = ""; try { nazev = await ziskatNazev(); } catch (e) { logg("nepodarilo se ziskat nazev, pouzivam default"); nazev = "Vordinačka"; } const event = await guilda.scheduledEvents.create({ name: nazev, scheduledStartTime: kdyToBude, entityType: GuildScheduledEventEntityType.Voice, privacyLevel: GuildScheduledEventPrivacyLevel.GuildOnly, channel: "891067481651839037" }); const general = guilda.channels.cache.get("555779161067749448") as TextChannel; if (!general) return log(new Error("general nenalezen")); sendWithoutReply(general, `<@&1123186280843444274> ${event.url}`); canForceNotify = false; naplanovat(); } const exp: Modul = { more_komandy: { dalsiordinacka: () => `dalsi ordnacka `, vynutitordinaceoznameni: { run: async mes => { if (!token) { return "nemamheslo"; } if (!canForceNotify) { return "uz ne tyy mrtko"; } await urobit(); mes.react(emouty.d3k); } } }, on_clientReady: async () => { client = module.exports.client; if (token) { // naplanovat(); logg("nazev ordinace je:", await ziskatNazev()); } } }; module.exports = exp;