LOADING
shortlink ads cutw bypass or solver get final url support all domain maybe
#!/usr/bin/env node
/**
* CutWin Final URL Resolver (curl backend)
*
* node cutw.js <url>
* node cutw.js <url> --raw # JSON 1 baris
* node cutw.js <url> --wait=2000 # jeda sebelum POST (ms)
*/
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import { mkdtemp, readFile, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
const execFileAsync = promisify(execFile);
const SUPPORTED_DOMAINS = [
'cutw.in', 'cutwin.com', 'cutwin.net', 'cutwin.org', 'cutwin.cz',
'www.cutw.in', 'www.cutwin.com', 'www.cutwin.net', 'www.cutwin.org', 'www.cutwin.cz',
];
const UA =
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36';
function sleep(ms) {
return new Promise((r) => setTimeout(r, ms));
}
/**
* @param {string} shortUrl
* @param {{ wait?: number }} [opts]
*/
export async function resolveCutw(shortUrl, opts = {}) {
const waitMs = opts.wait ?? 0;
const startedAt = Date.now();
const result = {
success: false,
input: shortUrl,
finalUrl: null,
intermediateUrl: null,
domain: null,
flowId: null,
durationMs: 0,
error: null,
timestamp: new Date().toISOString(),
};
let tmpDir = null;
try {
let parsed;
try {
parsed = new URL(String(shortUrl).trim());
} catch {
throw new Error('URL tidak valid');
}
const host = parsed.hostname.toLowerCase();
if (!SUPPORTED_DOMAINS.includes(host)) {
throw new Error(
`Domain tidak didukung: ${host}. Didukung: cutw.in, cutwin.com, cutwin.net, cutwin.org, cutwin.cz`
);
}
result.domain = host;
try {
await execFileAsync('curl', ['--version']);
} catch {
throw new Error('curl tidak ditemukan. Install curl dulu.');
}
tmpDir = await mkdtemp(join(tmpdir(), 'cutw-'));
const cookieFile = join(tmpDir, 'cookies.txt');
const htmlFile = join(tmpDir, 'page.html');
// 1. GET short link
const { stdout: finalUrlOut } = await execFileAsync(
'curl',
[
'-sL',
'-A', UA,
'-H', 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'-H', 'Accept-Language: en-US,en;q=0.9',
'-H', 'Sec-Fetch-Dest: document',
'-H', 'Sec-Fetch-Mode: navigate',
'-H', 'Sec-Fetch-Site: none',
'-H', 'Sec-Fetch-User: ?1',
'-H', 'Upgrade-Insecure-Requests: 1',
'-c', cookieFile,
'-b', cookieFile,
'-o', htmlFile,
'-w', '%{url_effective}',
'--max-time', '20',
'--connect-timeout', '10',
parsed.href,
],
{ maxBuffer: 5 * 1024 * 1024 }
);
const intermediateUrl = finalUrlOut.trim();
result.intermediateUrl = intermediateUrl;
const html = await readFile(htmlFile, 'utf8');
// 2. Extract tokens
const csrfMatch = html.match(/adxCsrfToken\s*=\s*["']([^"']*)["']/i);
const flowMatch = html.match(/adxFlowId\s*=\s*["']([^"']+)["']/i);
let flowId = flowMatch?.[1] || null;
try {
if (!flowId) flowId = new URL(intermediateUrl).searchParams.get('flow');
} catch { /* ignore */ }
if (!flowId) {
throw new Error('Tidak menemukan flowId. Struktur halaman mungkin berubah.');
}
const csrfToken = csrfMatch ? csrfMatch[1].replace(/\\\//g, '/') : '';
result.flowId = flowId;
// 3. Optional wait
if (waitMs > 0) await sleep(waitMs);
// 4. POST get_link
const origin = new URL(intermediateUrl).origin;
const { stdout: postOut } = await execFileAsync(
'curl',
[
'-s',
'-X', 'POST',
'-A', UA,
'-H', 'Accept: */*',
'-H', 'Accept-Language: en-US,en;q=0.9',
'-H', 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
'-H', 'X-Requested-With: XMLHttpRequest',
'-H', `Origin: ${origin}`,
'-H', `Referer: ${intermediateUrl}`,
'-H', 'Sec-Fetch-Dest: empty',
'-H', 'Sec-Fetch-Mode: cors',
'-H', 'Sec-Fetch-Site: same-origin',
'-b', cookieFile,
'-c', cookieFile,
'--data-urlencode', '_method=POST',
'--data-urlencode', 'ajax=get_link',
'--data-urlencode', `_csrfToken=${csrfToken}`,
'--data-urlencode', `flow=${flowId}`,
'--max-time', '15',
'--connect-timeout', '10',
intermediateUrl,
],
{ maxBuffer: 2 * 1024 * 1024 }
);
let data;
try {
data = JSON.parse(postOut.replace(/^\uFEFF/, '').trim());
} catch {
throw new Error(`Response bukan JSON: ${postOut.slice(0, 200)}`);
}
if (data?.status === 'success' && data?.url) {
result.success = true;
result.finalUrl = data.url;
} else {
throw new Error(
data?.message || data?.debug || (data ? JSON.stringify(data) : 'Gagal get_link')
);
}
} catch (err) {
result.success = false;
result.error = err.message || String(err);
} finally {
result.durationMs = Date.now() - startedAt;
if (tmpDir) {
try { await rm(tmpDir, { recursive: true, force: true }); } catch { /* ignore */ }
}
}
return result;
}
export { SUPPORTED_DOMAINS };
// ── CLI ──────────────────────────────────────────────────────────
async function main() {
const args = process.argv.slice(2);
// Pretty = default. Pakai --raw untuk 1 baris
const raw = args.includes('--raw') || args.includes('-r');
const waitArg = args.find((a) => a.startsWith('--wait='));
const wait = waitArg ? Number(waitArg.split('=')[1]) : 0;
const input = args.find((a) => !a.startsWith('-'));
if (!input) {
console.log(JSON.stringify({
success: false,
error: 'URL short link diperlukan',
usage: 'node cutw.js <url> [--raw|-r] [--wait=0]',
examples: [
'node cutw.js https://cutw.in/rPe73P',
'node cutw.js https://cutw.in/rPe73P --raw',
'node cutw.js https://cutw.in/rPe73P --wait=2000',
],
supportedDomains: ['cutw.in', 'cutwin.com', 'cutwin.net', 'cutwin.org', 'cutwin.cz'],
}, null, 2));
process.exit(1);
}
const result = await resolveCutw(input, { wait });
console.log(JSON.stringify(result, null, raw ? 0 : 2));
process.exit(result.success ? 0 : 1);
}
main();Resolve final destination URL dari short link CutWin tanpa browser.
Script memakai curl di backend (menghindari deteksi TLS fingerprint Node.js fetch).
| Domain | Status |
|---|---|
cutw.in | ✅ |
cutwin.com | ✅ |
cutwin.net | ✅ |
cutwin.org | ✅ |
cutwin.cz | ✅ |
Alias/short-code sama di semua domain.
Cek curl:
bashcurl --version
Tidak perlu npm install — zero dependency.
bash# Cukup salin file cutw.js (atau rename jadi cutw.js) chmod +x cutw.js # opsional
bash# Pretty JSON (default) node cutw.js https://cutw.in/rPe73P # JSON 1 baris node cutw.js https://cutw.in/rPe73P --raw # Tambah jeda sebelum POST (jika kena lock) node cutw.js https://cutw.in/rPe73P --wait=2000
json{ "success": true, "input": "https://cutw.in/rPe73P", "finalUrl": "https://code.vyrgo.cyou/donate", "intermediateUrl": "https://www.masrawytrend.com/..../?flow=....", "domain": "cutw.in", "flowId": "5703b746f29eb837", "durationMs": 6000, "error": null, "timestamp": "2026-10-11T04:25:45.987Z" }
json{ "success": false, "input": "https://cutw.in/rPe73P", "finalUrl": null, "intermediateUrl": "...", "domain": "cutw.in", "flowId": "...", "durationMs": 5000, "error": "Flow is locked due to suspicious activity", "timestamp": "..." }
| Exit code | Arti |
|---|---|
0 | Sukses |
1 | Gagal |
jsimport { resolveCutw } from './cutw.js'; const res = await resolveCutw('https://cutw.in/rPe73P'); if (res.success) { console.log(res.finalUrl); // https://... console.log(res.durationMs); // ms } else { console.error(res.error); }
jsawait resolveCutw('https://cutw.in/xxx', { wait: 2000, // jeda sebelum POST (ms), default 0 });
curl GET short URL → ikuti redirect ke halaman intermediateadxCsrfToken + adxFlowIdcurl POST ajax=get_link ke intermediate page{ "status": "success", "url": "https://..." }| Error | Solusi |
|---|---|
Flow is locked due to suspicious activity | Tunggu beberapa menit, ganti jaringan/IP, atau tambah --wait=2000 |
curl tidak ditemukan | Install curl (brew install curl / apt install curl) |
Tidak menemukan flowId | Struktur HTML berubah / halaman error |
Domain tidak didukung | Pakai domain di tabel atas |
| Lambat (5–8 detik) | Normal dari Indonesia; 2 request + latency jaringan |
fetch / axios murni sering kena lock karena TLS fingerprint berbeda dari browser.MIT