Edit: atur-subdomain
Nama Worker
Kode Sumber
// KODE FINAL - SUDAH TERMASUK PEMBUATAN DNS RECORD addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) // Fungsi untuk membuat DNS Record DAN Worker Route async function createSubdomainAndRoute(subdomain, domain, workerName) { const zoneId = CF_ZONE_ID; const apiToken = CF_API_TOKEN; if (!zoneId || !apiToken) { throw new Error('Zone ID and API Token must be configured in Worker Secrets.'); } // === LANGKAH 1: MEMBUAT DNS RECORD === const dnsUrl = `https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records`; const dnsData = { // Membuat record "dummy" AAAA yang aman. Tujuannya hanya agar ada dan bisa di-proxy. type: 'AAAA', name: subdomain, // Cloudflare akan otomatis menambahkan .gratisan.filegear-sg.me content: '100::', // Alamat IPV6 "blackhole" yang direkomendasikan Cloudflare proxied: true, // WAJIB, ini yang mengaktifkan Worker ttl: 1, // Otomatis }; const dnsResponse = await fetch(dnsUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiToken}`, }, body: JSON.stringify(dnsData), }); const dnsResult = await dnsResponse.json(); if (!dnsResult.success) { const errorMessage = dnsResult.errors.map(err => `DNS Error (Code ${err.code}): ${err.message}`).join(', '); throw new Error(errorMessage); } // === LANGKAH 2: MEMBUAT WORKER ROUTE === const routeUrl = `https://api.cloudflare.com/client/v4/zones/${zoneId}/workers/routes`; const routeData = { pattern: `${subdomain}.${domain}/*`, script: workerName, }; const routeResponse = await fetch(routeUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiToken}`, }, body: JSON.stringify(routeData), }); const routeResult = await routeResponse.json(); if (!routeResult.success) { const errorMessage = routeResult.errors.map(err => `Route Error (Code ${err.code}): ${err.message}`).join(', '); throw new Error(errorMessage); } return { dnsResult, routeResult }; } async function handleRequest(request) { if (request.method === 'POST') { try { const data = await request.json(); const subdomain = data.subdomain; const workerName = data.workerName; const domain = "gratisan.filegear-sg.me"; if (!subdomain || !workerName) { return new Response(JSON.stringify({ success: false, message: 'Subdomain and Worker Name are required.' }), { status: 400, headers: { 'Content-Type': 'application/json' }, }); } const response = await createSubdomainAndRoute(subdomain, domain, workerName); return new Response(JSON.stringify({ success: true, message: `DNS and Route created successfully!`, result: response }), { headers: { 'Content-Type': 'application/json' }, }); } catch (error) { return new Response(JSON.stringify({ success: false, message: error.message }), { status: 500, headers: { 'Content-Type': 'application/json' }, }); } } const domain_utama = "gratisan.filegear-sg.me"; return new Response(` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Create Worker Route</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css"> </head> <body> <main class="container"> <article> <header> <h1>Create Worker Route</h1> <p>Assign a subdomain to run a specific Worker script.</p> </header> <form id="route-form"> <label for="subdomain"> Subdomain Name <div style="display: flex; align-items: center;"> <input type="text" id="subdomain" name="subdomain" placeholder="my-api" required /> <span style="margin-left: 10px; font-weight: bold;">.${domain_utama}</span> </div> </label> <label for="workerName"> Worker Script Name <input type="text" id="workerName" name="workerName" placeholder="e.g., tevekuh" required /> </label> <button type="submit" id="submit-btn">Create DNS & Route</button> </form> <div id="result" style="margin-top: 1rem;"></div> </article> </main> <script> document.getElementById('route-form').addEventListener('submit', async function(event) { event.preventDefault(); const submitBtn = document.getElementById('submit-btn'); const resultDiv = document.getElementById('result'); submitBtn.setAttribute('aria-busy', 'true'); submitBtn.disabled = true; resultDiv.innerHTML = ''; const formData = new FormData(this); const response = await fetch(window.location.href, { method: 'POST', body: JSON.stringify({ subdomain: formData.get('subdomain'), workerName: formData.get('workerName') }), headers: { 'Content-Type': 'application/json' } }); const data = await response.json(); if (data.success) { resultDiv.innerHTML = \` <div class="pico-color-green-200" style="padding: 1rem; border-radius: var(--border-radius); border-left: 5px solid var(--pico-color-green-500);"> <strong>Success!</strong> DNS and Route created. </div> \`; } else { resultDiv.innerHTML = \` <div class="pico-color-red-200" style="padding: 1rem; border-radius: var(--border-radius); border-left: 5px solid var(--pico-color-red-500);"> <strong>Error:</strong> \${data.message} </div> \`; } submitBtn.removeAttribute('aria-busy'); submitBtn.disabled = false; }); </script> </body> </html> `, { headers: { 'Content-Type': 'text/html' }, }); }
Bindings
Tambah KV
Tambah R2
Tambah D1
← Kembali
Simpan & Deploy
Hapus Script Worker Ini