LOADING
cek aja website aslinya ya hehe
const fs = require("fs");
const axios = require("axios");
const { load } = require("cheerio");
const { HttpsProxyAgent } = require("https-proxy-agent");
const BASE_URL = "https://www.getvoila.ai";
const TOOL_URL = `${BASE_URL}/ai-tools/code-explainer`;
const LANGUAGES = [
"", "American English", "British English", "English (Canada)",
"English (Australia)", "English (India)", "Arabic", "Amharic",
"Bulgarian", "Bengali", "Catalan", "Chinese (China)", "Chinese (Taiwan)",
"Czech", "Croatian", "Danish", "Dutch", "Estonian", "Finnish", "Filipino",
"French", "French (Canada)", "French (Belgium)", "French (Switzerland)",
"German", "German (Austria)", "German (Switzerland)", "Greek", "Hebrew",
"Hindi", "Gujarati", "Hungarian", "Indonesian", "Italian", "Japanese",
"Kannada", "Korean", "Latvian", "Lithuanian", "Malay", "Malayalam",
"Marathi", "Norwegian", "Persian", "Polish", "Portuguese (Brazil)",
"Portuguese (Portugal)", "Romanian", "Russian", "Serbian", "Slovak",
"Slovenian", "Spanish", "Spanish (Latin America,Caribbean)", "Swedish",
"Swahili", "Tamil", "Telugu", "Thai", "Turkish", "Ukrainian", "Vietnamese",
];
const TONES = [
"", "Formal", "Friendly", "Casual", "Professional", "Diplomatic",
"Confident", "Middle school", "High school", "Academic", "Journalistic",
"Simplified", "Bold", "Empathetic", "Luxury", "Engaging", "Direct",
"Persuasive", "Tone down", "Exciting",
];
const SOLVER_URL = "https://cf-solver-renofc.my.id/solve";
// Isi langsung di sini (gampang diedit), atau kosongin "" dan pakai env var
// VOILA_PROXY pas jalanin script (overrides nilai di bawah).
const PROXY = ""; // contoh: "http://user:pass@host:port"
function getManualSession() {
const cookies = process.env.VOILA_COOKIE;
const csrf = process.env.VOILA_CSRF;
const userAgent = process.env.VOILA_UA || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36";
if (!cookies) throw new Error("Missing VOILA_COOKIE env var. Copy the Cookie header from your browser's request to getvoila.ai");
if (!csrf) throw new Error("Missing VOILA_CSRF env var. Run document.querySelector('meta[name=\"csrf-token\"]').content in browser console on the page");
return { cookies, csrf, userAgent };
}
// Priority: argumen CLI > env var VOILA_PROXY > konstanta PROXY di atas
function getProxyConfig(explicitProxy) {
const proxyUrl = explicitProxy || process.env.VOILA_PROXY || PROXY;
if (!proxyUrl) return null;
const parsed = new URL(proxyUrl);
return {
proxyUrl,
agent: new HttpsProxyAgent(proxyUrl),
body: {
host: parsed.hostname,
port: Number(parsed.port),
username: parsed.username ? decodeURIComponent(parsed.username) : undefined,
password: parsed.password ? decodeURIComponent(parsed.password) : undefined,
},
};
}
async function solveWaf(proxyConfig) {
const body = { mode: "waf-session", url: TOOL_URL };
if (proxyConfig) body.proxy = proxyConfig.body;
const res = await axios.post(SOLVER_URL, body, {
headers: { "Content-Type": "application/json" },
});
const data = res.data;
if (!data.cookies || !Array.isArray(data.cookies)) {
throw new Error("WAF solver did not return cookies");
}
const cookies = data.cookies
.map((c) => `${c.name}=${c.value}`)
.join("; ");
const userAgent = data.headers?.["user-agent"] || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36";
return { cookies, userAgent };
}
async function getSession(explicitProxy) {
if (process.env.VOILA_COOKIE) {
const { cookies, csrf, userAgent } = getManualSession();
return { csrf, cookies, userAgent, agent: null };
}
const proxyConfig = getProxyConfig(explicitProxy);
const { cookies, userAgent } = await solveWaf(proxyConfig);
if (process.env.VOILA_DEBUG) {
console.error("DEBUG cookies:", cookies);
console.error("DEBUG userAgent:", userAgent);
console.error("DEBUG proxy:", proxyConfig ? proxyConfig.body.host + ":" + proxyConfig.body.port : "none");
}
let res;
try {
res = await axios.get(TOOL_URL, {
headers: {
"User-Agent": userAgent,
"Cookie": cookies,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
},
httpsAgent: proxyConfig?.agent,
proxy: false,
});
} catch (err) {
if (process.env.VOILA_DEBUG) {
console.error("DEBUG GET failed status:", err.response?.status);
console.error("DEBUG GET failed body:", err.response?.data?.slice?.(0, 1000));
}
throw err;
}
const extraCookies = res.headers["set-cookie"]
?.map((c) => c.split(";")[0])
.join("; ");
const finalCookies = extraCookies ? `${cookies}; ${extraCookies}` : cookies;
const $ = load(res.data);
const csrf = $('meta[name="csrf-token"]').attr("content");
if (!csrf) throw new Error("Failed to get CSRF token");
return { csrf, cookies: finalCookies, userAgent, agent: proxyConfig?.agent };
}
async function explain(code, options = {}) {
const { language = "", tone = "", proxy = "" } = options;
if (language && !LANGUAGES.includes(language)) {
return { success: false, error: `Invalid language. Valid: ${LANGUAGES.filter(Boolean).join(", ")}` };
}
if (tone && !TONES.includes(tone)) {
return { success: false, error: `Invalid tone. Valid: ${TONES.filter(Boolean).join(", ")}` };
}
const { csrf, cookies, userAgent, agent } = await getSession(proxy);
if (process.env.VOILA_DEBUG) {
console.error("DEBUG csrf:", csrf);
}
const params = new URLSearchParams();
params.append("authenticity_token", csrf);
params.append("form[input]", code);
params.append("form[language]", language);
params.append("form[tone]", tone);
let res;
try {
res = await axios.post(TOOL_URL, params.toString(), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": userAgent,
"Referer": TOOL_URL,
"Cookie": cookies,
"X-CSRF-Token": csrf,
},
httpsAgent: agent,
proxy: false,
maxRedirects: 10,
});
} catch (err) {
if (process.env.VOILA_DEBUG) {
console.error("DEBUG POST failed status:", err.response?.status);
console.error("DEBUG POST failed body:", err.response?.data?.slice?.(0, 1000));
}
throw err;
}
const $ = load(res.data);
const resultEl = $(".MarkdownBlock[data-copy]");
if (!resultEl.length) {
return { success: false, error: "No result found" };
}
const raw = resultEl.attr("data-copy")
?.replace(/"/g, '"')
.replace(/"/g, '"')
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.trim();
const html = resultEl.html()?.trim();
return {
success: true,
result: {
text: raw,
html,
language: language || "English",
tone: tone || "Neutral",
},
};
}
module.exports = { explain, LANGUAGES, TONES };
// CLI
if (require.main === module) {
const args = process.argv.slice(2);
if (args.length === 0) {
console.log(JSON.stringify({
usage: "node voila.js \"<code>\" [language] [tone] [proxy]",
example: 'node voila.js "print(\'hello\')" "Indonesian" "Casual"',
example_with_proxy: 'node voila.js "print(\'hello\')" "Indonesian" "Casual" "http://user:pass@host:port"',
example_from_file: 'node voila.js "@script.py" "Indonesian" "Casual"',
note: "Pakai '@nama_file' sebagai argumen kode buat baca dari file, contoh: \"@script.py\"",
languages: LANGUAGES.filter(Boolean),
tones: TONES.filter(Boolean),
}, null, 2));
process.exit(0);
}
let [code, language = "", tone = "", proxy = ""] = args;
if (code.startsWith("@")) {
const filePath = code.slice(1);
try {
code = fs.readFileSync(filePath, "utf-8");
} catch (err) {
console.log(JSON.stringify({ success: false, error: `Gagal baca file "${filePath}": ${err.message}` }, null, 2));
process.exit(1);
}
}
explain(code, { language, tone, proxy })
.then((res) => console.log(JSON.stringify(res, null, 2)))
.catch((err) => console.log(JSON.stringify({ success: false, error: err.message }, null, 2)));
}bashnpm install axios cheerio https-proxy-agent
bashisi dulu proxy di code nya, contoh: const PROXY = "http://user:pass@host:port";
bashnode voila.js "def faktorial(n): return 1 if n==0 else n*faktorial(n-1)" "Indonesian" "Casual"
atau
bashnode voila.js "@input.js" "Indonesian" "Casual"