import { join } from "node:path"; import { respond } from "../audio/AudioService.js"; import type { Module } from "./types.js"; /** * Calls Google Translate's unofficial endpoint. No SDK — the maintained * `node-google-translate-skidz` wrapper was abandoned, so we hit the same * single_translate endpoint directly with a fetch. */ async function translate(text: string, fromLang: string, toLang: string): Promise { const url = new URL("https://translate.googleapis.com/translate_a/single"); url.searchParams.set("client", "gtx"); url.searchParams.set("sl", fromLang); url.searchParams.set("tl", toLang); url.searchParams.set("dt", "t"); url.searchParams.set("q", text); const res = await fetch(url.toString()); if (!res.ok) throw new Error(`translate ${fromLang}->${toLang} failed: ${res.status}`); const json = (await res.json()) as unknown[]; const segments = json[0]; if (!Array.isArray(segments)) throw new Error("translate: unexpected response shape"); return segments .map((seg) => (Array.isArray(seg) && typeof seg[0] === "string" ? seg[0] : "")) .join(""); } export const mangle: Module = ({ audio, commands, config, rootDir }) => { const sysmsg = join(rootDir, "sysmsg.wav"); const langs = (config.MANGLE_LANGS ?? "en,de,ja,ru,en").split(",").map((l) => l.trim()); commands.register("mangle", async (_args, message) => { let str = message.content.slice(config.PREFIX.length + "mangle".length).trim(); if (!str) return; for (let i = 0; i < langs.length - 1; i++) { const from = langs[i]; const to = langs[i + 1]; if (!from || !to) break; str = await translate(str, from, to); } respond(audio, sysmsg, message, str); }); };