Ini adalah kode sumber dari proyek saat ini. Gunakan ini sebagai konteks untuk melakukan perubahan yang diminta. // FILE: vercel.json {} --- // FILE: tailwind.config.js /** @type {import('tailwindcss').Config} */ module.exports = { content: [ "./app/**/*.{js,ts,jsx,tsx,mdx}", "./components/**/*.{js,ts,jsx,tsx,mdx}", "./public/**/*.html", ], theme: { extend: {}, }, plugins: [], } --- // FILE: postcss.config.js module.exports = { plugins: { tailwindcss: {}, autoprefixer: {}, }, } --- // FILE: package.json { "name": "NextA-API", "version": "1.0.0", "description": "Proyek API Publik modular dengan fitur Fast Update via AI - Next.js Version.", "scripts": { "dev": "next dev", "build": "node scripts/generate-docs.js && next build", "start": "next start", "lint": "next lint" }, "dependencies": { "axios": "^1.7.2", "axios-cookiejar-support": "^5.0.0", "cheerio": "^1.0.0-rc.12", "cloudscraper": "^4.6.0", "crypto-js": "^4.2.0", "form-data": "^4.0.0", "fs-extra": "^11.2.0", "glob": "^10.3.10", "mime-types": "^2.1.35", "next": "14.2.3", "nprogress": "^0.2.0", "pg": "^8.11.5", "qs": "^6.11.0", "react": "^18", "react-dom": "^18", "react-markdown": "^9.0.1", "react-virtuoso": "^4.7.11", "remark-gfm": "^4.0.0", "tough-cookie": "^4.1.3", "uuid": "^9.0.1" }, "devDependencies": { "autoprefixer": "^10.4.19", "eslint": "^8", "eslint-config-next": "14.2.3", "postcss": "^8.4.38", "tailwindcss": "^3.4.4" } } --- // FILE: next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: false, // Nonaktifkan strict mode untuk menghindari double-invocation pada useEffect di dev (opsional) images: { remotePatterns: [ { protocol: 'https', hostname: 'avatars.githubusercontent.com', }, ], }, async headers() { return [ { // Terapkan header CORS dan Contact ke semua rute API source: "/api/:path*", headers: [ { key: "Access-Control-Allow-Credentials", value: "true" }, { key: "Access-Control-Allow-Origin", value: "*" }, // Izinkan akses dari semua domain { key: "Access-Control-Allow-Methods", value: "GET,DELETE,PATCH,POST,PUT" }, { key: "Access-Control-Allow-Headers", value: "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }, { key: "Contact", value: "wa.me/6283894391287" } // Header kontak tambahan ] } ] }, async rewrites() { return [ { source: '/admin', destination: '/admin.html', }, { source: '/fastupdate', destination: '/fastupdate.html', }, // Mapping endpoint lama agar kompatibel dengan frontend { source: '/download', destination: '/api/fastupdate/download', }, { source: '/update', destination: '/api/fastupdate/update', }, // Fix Favicon untuk Search Engine (Map .ico request ke .jpg) { source: '/favicon.ico', destination: '/favicon.jpg', }, ]; }, }; module.exports = nextConfig; --- // FILE: scripts/generate-docs.js const { scanDocs } = require('../lib/docsService'); const fse = require('fs-extra'); const path = require('path'); (async () => { console.log('🚀 Starting API Documentation Generation...'); try { const spec = await scanDocs(); // Output ke folder public agar bisa diakses/dibaca di runtime production const outputPath = path.join(process.cwd(), 'public', 'docs.json'); await fse.ensureDir(path.dirname(outputPath)); await fse.writeJson(outputPath, spec, { spaces: 2 }); console.log(`✅ Success! docs.json generated at: ${outputPath}`); console.log(`📊 Stats: Found ${Object.keys(spec).length} categories.`); } catch (err) { console.error('❌ Failed to generate docs:', err); process.exit(1); } })(); --- // FILE: public/google41f3f05fef8cd977.html google-site-verification: google41f3f05fef8cd977.html --- // FILE: public/fastupdate.html System Updater

Fast Update

AI-Powered Code Implementation

1
2
3

Context Extraction

Download the latest source code to give full context to the AI.

Download Context

Prompt Generation

Apply Changes

--- // FILE: public/docs.json { "ai": [ { "title": "Blackbox AI", "summary": "AI Chat dengan Konteks (History).", "description": "Berinteraksi dengan Blackbox AI yang mendukung percakapan berkelanjutan. Riwayat percakapan disimpan per user di Firebase dan otomatis dibersihkan jika tidak ada aktivitas selama 3 hari.", "method": "POST", "path": "/api/ai/blackbox", "responseType": "json", "example": "async function chat() {\n const res = await fetch('/api/ai/blackbox', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"message\": \"Halo, siapa namamu?\",\n \"userId\": \"user-123\",\n \"system\": \"Kamu adalah asisten yang ramah.\"\n })\n });\n const data = await res.json();\n console.log(data.result.answer);\n }", "params": [ { "name": "message", "in": "body", "type": "string", "description": "Pesan dari pengguna.", "required": true }, { "name": "userId", "in": "body", "type": "string", "description": "ID unik pengguna (DeviceId/Username) untuk menyimpan riwayat chat.", "required": false }, { "name": "system", "in": "body", "type": "string", "description": "Instruksi sistem kustom untuk AI.", "required": false } ] }, { "title": "Chat Espanyol", "summary": "Chat AI (ChatEspanyol).", "description": "Melakukan percakapan dengan AI dari ChatEspanyolGratis. Mendukung percakapan berkelanjutan dengan menyertakan `sessionId` dan `conversationUuid`.", "method": "POST", "path": "/api/ai/chatespanyol", "responseType": "json", "example": "async function chat() {\n try {\n const response = await fetch('/api/ai/chatespanyol', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"message\": \"Halo Kawanku\" \n })\n });\n \n const data = await response.json();\n console.log(data);\n } catch (error) {\n console.error('Error:', error);\n }\n }\n \n chat();", "params": [ { "name": "message", "in": "body", "type": "string", "description": "Pesan yang ingin dikirim ke AI.", "required": true }, { "name": "sessionId", "in": "body", "type": "string", "description": "ID sesi untuk menjaga konteks percakapan (opsional).", "required": false }, { "name": "conversationUuid", "in": "body", "type": "string", "description": "UUID percakapan (opsional).", "required": false } ] }, { "title": "DeepSearch Chat", "summary": "DeepSeek R1 / Deep Thinking Chat.", "description": "Berinteraksi dengan model DeepSearch (DeepSeek R1/V3) yang mendukung kemampuan \"Reasoning\" atau berpikir mendalam sebelum menjawab. Endpoint ini menggunakan Server-Sent Events (SSE) untuk streaming output proses berpikir (reasoning) dan jawaban akhir.", "method": "POST", "path": "/api/ai/deepsearch", "responseType": "json", "example": "async function askDeepSearch() {\n const response = await fetch('/api/ai/deepsearch', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"prompt\": \"Jelaskan tentang Black Hole secara sederhana\",\n \"modelType\": \"reasoner\"\n })\n });\n \n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n \n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n const text = decoder.decode(value);\n // Format SSE: data: {\"type\": \"reasoning\"|\"text\", \"content\": \"...\"}\n console.log(text);\n }\n }", "params": [ { "name": "prompt", "in": "body", "type": "string", "description": "Pertanyaan atau instruksi.", "required": true }, { "name": "modelType", "in": "body", "type": "string", "description": "Tipe model: 'reasoner' (Deep Thinking) atau 'chat' (Fast). Default: 'reasoner'.", "required": false } ] }, { "title": "DeepSeek R1", "summary": "DeepSeek R1 via ChatGot.", "description": "Berinteraksi dengan model DeepSeek R1 yang memiliki kemampuan reasoning (berpikir). Endpoint ini menggunakan Server-Sent Events (SSE) untuk streaming output proses berpikir (reasoning) dan jawaban akhir.", "method": "POST", "path": "/api/ai/deepseek", "responseType": "json", "example": "async function askDeepSeek() {\n const response = await fetch('/api/ai/deepseek', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"prompt\": \"Jelaskan kenapa langit berwarna biru?\"\n })\n });\n \n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n \n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n const text = decoder.decode(value);\n // Output berupa SSE event: data: {...}\n console.log(text);\n }\n }", "params": [ { "name": "prompt", "in": "body", "type": "string", "description": "Pertanyaan atau instruksi.", "required": true } ] }, { "title": "Dracin TTS", "summary": "AI Voice gaya Drama China (Dracin).", "description": "Mengubah teks menjadi suara dengan nada ala narator drama China. Mengembalikan URL audio hasil proses.", "method": "POST", "path": "/api/ai/dracin", "responseType": "json", "example": "async function speakDracin() {\n const res = await fetch('/api/ai/dracin', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"text\": \"Halo di sini soume\",\n \"music\": true \n })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "text", "in": "body", "type": "string", "description": "Teks yang akan diubah menjadi suara.", "required": true }, { "name": "music", "in": "body", "type": "boolean", "description": "Menggunakan musik latar? Default: true.", "required": false }, { "name": "speed", "in": "body", "type": "number", "description": "Kecepatan bicara (0.5 - 2.0). Default: 1.0.", "required": false }, { "name": "volume", "in": "body", "type": "number", "description": "Volume musik latar (0.1 - 1.0). Default: 0.3.", "required": false } ] }, { "title": "Flux Image", "summary": "Generate Gambar Flux AI.", "description": "Menghasilkan gambar berkualitas tinggi menggunakan model Flux melalui proxy worker. Endpoint ini menggunakan Server-Sent Events (SSE).", "method": "POST", "path": "/api/ai/flux", "responseType": "json", "example": "// Contoh penggunaan (Membaca stream SSE di client)\n async function generateImage() {\n const response = await fetch('/api/ai/flux', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"prompt\": \"Cyberpunk city with neon lights, realistic style\" \n })\n });\n \n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n \n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n const text = decoder.decode(value);\n console.log(\"Stream:\", text);\n \n if(text.includes('[true]')) {\n const resultUrl = text.replace('[true]', '').trim();\n console.log(\"Result JSON URL:\", resultUrl);\n // fetch(resultUrl).then(res => res.json()).then(console.log);\n }\n }\n }\n \n generateImage();", "params": [ { "name": "prompt", "in": "body", "type": "string", "description": "Deskripsi gambar yang ingin dibuat.", "required": true } ] }, { "title": "Gemini AI Chat", "summary": "Chat via Google Gemini (Proxy).", "description": "Berinteraksi dengan Google Gemini menggunakan browser automation.", "method": "POST", "path": "/api/ai/gemini", "responseType": "json", "example": "async function chatGemini() {\n const response = await fetch('/api/ai/gemini', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"prompt\": \"Halo Gemini!\" })\n });\n \n const data = await response.json();\n console.log(data);\n }", "params": [ { "name": "prompt", "in": "body", "type": "string", "description": "Pertanyaan yang ingin diajukan ke Gemini.", "required": true } ] }, { "title": "Grok-4 Chat", "summary": "Chat AI Grok-4 Fast.", "description": "Berinteraksi dengan model Grok-4 Fast melalui ToolBaz. Model ini dikenal cepat dalam memberikan respons.", "method": "POST", "path": "/api/ai/grok", "responseType": "json", "example": "async function chat() {\n try {\n const response = await fetch('/api/ai/grok', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"message\": \"Siapa pencipta bahasa pemrograman JavaScript?\" \n })\n });\n \n const data = await response.json();\n console.log(data);\n } catch (error) {\n console.error('Error:', error);\n }\n }\n \n chat();", "params": [ { "name": "message", "in": "body", "type": "string", "description": "Pesan yang ingin dikirim ke AI.", "required": true } ] }, { "title": "LetMeGPT AI", "summary": "Chat AI via LetMeGPT.", "description": "Berinteraksi dengan model AI melalui layanan scraping LetMeGPT.", "method": "POST", "path": "/api/ai/letmegpt", "responseType": "json", "example": "async function chat() {\n const res = await fetch('/api/ai/letmegpt', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"message\": \"Siapa namamu?\" })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "message", "in": "body", "type": "string", "description": "Pesan yang ingin diajukan ke AI.", "required": true } ] }, { "title": "NoteGPT AI", "summary": "NoteGPT Multi-Model AI Chat.", "description": "Berinteraksi dengan berbagai model AI melalui NoteGPT (Gemini, DeepSeek, GPT). Mendukung fitur \"Deep Think\" (Reasoning) dan IP Spoofing untuk melewati limitasi. Endpoint ini menggunakan Server-Sent Events (SSE) untuk streaming output.", "method": "POST", "path": "/api/ai/notegpt", "responseType": "json", "example": "async function askNoteGPT() {\n const response = await fetch('/api/ai/notegpt', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"prompt\": \"Jelaskan cara kerja kuantum komputer secara sederhana\",\n \"model\": \"TA/deepseek-ai/DeepSeek-R1\",\n \"chat_mode\": \"deep_think\"\n })\n });\n \n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n \n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n const text = decoder.decode(value);\n // Format SSE: data: {\"reasoning\": \"...\", \"text\": \"...\"}\n console.log(text);\n }\n }", "params": [ { "name": "prompt", "in": "body", "type": "string", "description": "Pertanyaan atau instruksi untuk AI.", "required": true }, { "name": "model", "in": "body", "type": "string", "description": "Pilihan model: 'gemini-3-flash-preview' (default), 'TA/deepseek-ai/DeepSeek-R1', 'gpt-5-mini'.", "required": false }, { "name": "chat_mode", "in": "body", "type": "string", "description": "Mode percakapan: 'standard' (default), 'deep_think', 'guided_learning'.", "required": false } ] }, { "title": "Claude Haiku AI", "summary": "Claude Haiku Chat (Overchat).", "description": "Berinteraksi dengan model Claude Haiku melalui provider Overchat.ai. Memberikan jawaban cerdas dan cepat. Credit: Hazel.", "method": "POST", "path": "/api/ai/overchat", "responseType": "json", "example": "async function askClaude() {\n const res = await fetch('/api/ai/overchat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"question\": \"Halo Claude!\" })\n });\n const data = await res.json();\n console.log(data.result);\n }", "params": [ { "name": "question", "in": "body", "type": "string", "description": "Pertanyaan atau pesan untuk AI.", "required": true } ] }, { "title": "puruAI (Time Aware)", "summary": "Advanced AI Gateway by PuruBoy.", "description": "Model AI yang menyadari waktu dan urutan pesan. Mendukung persistensi riwayat (history) per UserID menggunakan Node-cache.", "method": "POST", "path": "/api/ai/puruai", "responseType": "json", "example": "async function chat() {\n const res = await fetch('/api/ai/puruai', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"userid\": \"user-session-001\", \n \"prompt\": \"Halo, siapa namamu?\",\n \"model\": \"puruboy-flash\",\n \"system\": \"Kamu adalah AI asisten dari PuruBoy yang ramah.\"\n })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "userid", "in": "body", "type": "string", "description": "Session ID untuk riwayat pesan persisten.", "required": true }, { "name": "prompt", "in": "body", "type": "string", "description": "Pesan dari pengguna.", "required": true }, { "name": "model", "in": "body", "type": "string", "description": "Pilihan model: 'puruboy-flash' atau 'puruboy-pro'.", "required": true }, { "name": "system", "in": "body", "type": "string", "description": "(Opsional) Instruksi kepribadian dasar AI.", "required": false } ] }, { "title": "Quillbot AI Chat", "summary": "Chat via Quillbot AI (Stream).", "description": "Berinteraksi dengan model AI Quillbot yang mendukung streaming response. Berguna untuk menjawab pertanyaan, melakukan parafrase, atau riset teks. Endpoint ini menggunakan Server-Sent Events (SSE).", "method": "POST", "path": "/api/ai/quillbot", "responseType": "json", "example": "// Contoh penggunaan SSE di Client\n async function askQuillbot() {\n const response = await fetch('/api/ai/quillbot', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"message\": \"Apa itu pemrograman fungsional?\"\n })\n });\n \n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n \n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n const text = decoder.decode(value);\n console.log(text);\n }\n }", "params": [ { "name": "message", "in": "body", "type": "string", "description": "Pesan atau perintah yang ingin dikirim ke AI.", "required": true } ] }, { "title": "ScreenApp Vision", "summary": "AI Image Analysis (Gemini).", "description": "Menganalisis gambar dan menjawab pertanyaan terkait gambar tersebut menggunakan model Gemini 2.0 Flash via ScreenApp proxy. Mendukung analisis visual yang detail.", "method": "POST", "path": "/api/ai/screenapp", "responseType": "json", "example": "async function askImage() {\n const res = await fetch('/api/ai/screenapp', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n \"url\": \"https://puruboy-api.vercel.app/favicon.jpg\",\n \"question\": \"Jelaskan gambar ini dengan detail\"\n })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL publik gambar yang akan dianalisis.", "required": true }, { "name": "question", "in": "body", "type": "string", "description": "Pertanyaan tentang gambar tersebut.", "required": true } ] }, { "title": "Svara TTS", "summary": "Membuat audio dari teks (TTS) dengan Svara AI.", "description": "Menghasilkan file audio dari teks yang diberikan menggunakan berbagai pilihan suara. Credit: Daffa dari nbscript.", "method": "POST", "path": "/api/ai/svara", "responseType": "json", "example": "// Contoh penggunaan\n async function generateSpeech() {\n try {\n const response = await fetch('/api/ai/svara', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"text\": \"Halo, selamat datang di NextA API.\",\n \"voice\": \"bella\" \n })\n });\n \n const data = await response.json();\n console.log(data);\n } catch (error) {\n console.error(\"Gagal melakukan permintaan:\", error.message);\n }\n }", "params": [ { "name": "text", "in": "body", "type": "string", "description": "Teks yang akan diubah menjadi suara (maksimal 300 karakter).", "required": true }, { "name": "voice", "in": "body", "type": "string", "description": "Nama suara yang akan digunakan. Contoh: 'bella', 'adam', 'arjun'.", "required": true } ] }, { "title": "Translapp AI", "summary": "AI Text Processing dengan Translapp.", "description": "Memproses teks dengan berbagai modul AI seperti ringkasan, parafrase, terjemahan, penyesuaian nada, dll.", "method": "POST", "path": "/api/ai/translapp", "responseType": "json", "example": "async function processText() {\n try {\n const response = await fetch('/api/ai/translapp', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"text\": \"Hello, how are you?\",\n \"module\": \"TRANSLATE\", \n \"to\": \"jawa\"\n })\n });\n \n const data = await response.json();\n console.log(data);\n } catch (error) {\n console.error('Error:', error);\n }\n }\n \n processText();", "params": [ { "name": "text", "in": "body", "type": "string", "description": "Teks yang akan diproses.", "required": true }, { "name": "module", "in": "body", "type": "string", "description": "Modul pemrosesan: SUMMARIZE, PARAPHRASE, EXPAND, TONE, TRANSLATE, REPLY, GRAMMAR.", "required": true }, { "name": "to", "in": "body", "type": "string", "description": "Parameter tambahan tergantung modul (bahasa target untuk TRANSLATE, nada untuk TONE, dll).", "required": false }, { "name": "customTone", "in": "body", "type": "string", "description": "Nada kustom jika memilih TONE dengan opsi \"Other\".", "required": false } ] }, { "title": "Tsundere TTS", "summary": "AI Voice dengan gaya Tsundere.", "description": "Mengubah teks menjadi suara dengan nada Tsundere (ketus/malu-malu) menggunakan model Gemini TTS. Mengembalikan URL audio hasil proses.", "method": "POST", "path": "/api/ai/tsundere", "responseType": "json", "example": "async function speakTsundere() {\n const res = await fetch('/api/ai/tsundere', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"text\": \"Bukannya aku menyukaimu ya, dasar baka!\" })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "text", "in": "body", "type": "string", "description": "Teks yang akan diubah menjadi suara.", "required": true } ] }, { "title": "Unlimited AI", "summary": "Unlimited AI Chat.", "description": "Berinteraksi dengan model AI Unlimited (Reasoning) yang mendukung streaming response. Endpoint ini menggunakan Server-Sent Events (SSE).", "method": "POST", "path": "/api/ai/unlimited", "responseType": "json", "example": "async function chat() {\n const response = await fetch('/api/ai/unlimited', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"message\": \"Buatkan cerita pendek\"\n })\n });\n \n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n \n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n const text = decoder.decode(value);\n console.log(text);\n }\n }", "params": [ { "name": "message", "in": "body", "type": "string", "description": "Pesan yang ingin dikirim ke AI.", "required": true } ] } ], "anime": [ { "title": "Komiku Detail", "summary": "Detail Komik.", "description": "Mengambil informasi detail dan daftar chapter dari komik tertentu.", "method": "GET", "path": "/api/anime/komiku/detail", "responseType": "json", "example": "async function getDetail() {\n const res = await fetch('/api/anime/komiku/detail?url=https://komiku.org/manga/solo-leveling-id/');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "query", "type": "string", "description": "URL Komik (contoh: https://komiku.org/manga/solo-leveling-id/).", "required": true } ] }, { "title": "Komiku Home", "summary": "Update Terbaru Komiku.", "description": "Mengambil daftar update manga/manhwa/manhua terbaru dari Komiku.", "method": "GET", "path": "/api/anime/komiku/home", "responseType": "json", "example": "async function getUpdates() {\n const res = await fetch('/api/anime/komiku/home');\n const data = await res.json();\n console.log(data);\n }", "params": [] }, { "title": "Komiku Read", "summary": "Baca Chapter Komik.", "description": "Mengambil daftar gambar dari chapter tertentu.", "method": "GET", "path": "/api/anime/komiku/read", "responseType": "json", "example": "async function readChapter() {\n const res = await fetch('/api/anime/komiku/read?url=https://komiku.org/solo-leveling-ragnarok-chapter-68/');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "query", "type": "string", "description": "URL Chapter (contoh: https://komiku.org/solo-leveling-ragnarok-chapter-68/).", "required": true } ] }, { "title": "Komiku Search", "summary": "Pencarian Komik.", "description": "Mencari komik di Komiku berdasarkan kata kunci.", "method": "GET", "path": "/api/anime/komiku/search", "responseType": "json", "example": "async function searchKomik() {\n const res = await fetch('/api/anime/komiku/search?q=Solo Leveling');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Kata kunci pencarian (contoh: \"Solo Leveling\").", "required": true } ] }, { "title": "MAL Genre", "summary": "MyAnimeList Genre Search.", "description": "Mencari anime berdasarkan ID Genre di MyAnimeList. ID Genre bisa didapatkan dari dokumentasi Jikan atau MAL (misal: 1 = Action).", "method": "GET", "path": "/api/anime/mal/genre", "responseType": "json", "example": "async function getByGenre() {\n const res = await fetch('/api/anime/mal/genre?genreId=1');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "genreId", "in": "query", "type": "number", "description": "ID Genre (contoh: 1 untuk Action, 2 untuk Adventure).", "required": true }, { "name": "page", "in": "query", "type": "number", "description": "Nomor halaman (default: 1).", "required": false }, { "name": "limit", "in": "query", "type": "number", "description": "Jumlah item per halaman (default: 10).", "required": false } ] }, { "title": "MAL Ongoing", "summary": "MyAnimeList Ongoing Anime.", "description": "Mengambil daftar anime yang sedang tayang (Season Now) dari MyAnimeList via Jikan API.", "method": "GET", "path": "/api/anime/mal/ongoing", "responseType": "json", "example": "async function getOngoing() {\n const res = await fetch('/api/anime/mal/ongoing?page=1');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "page", "in": "query", "type": "number", "description": "Nomor halaman (default: 1).", "required": false }, { "name": "limit", "in": "query", "type": "number", "description": "Jumlah item per halaman (default: 10).", "required": false } ] }, { "title": "MAL Popular", "summary": "MyAnimeList Popular Anime.", "description": "Mengambil daftar anime populer (Top Anime) dari MyAnimeList via Jikan API.", "method": "GET", "path": "/api/anime/mal/popular", "responseType": "json", "example": "async function getPopular() {\n const res = await fetch('/api/anime/mal/popular?page=1');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "page", "in": "query", "type": "number", "description": "Nomor halaman (default: 1).", "required": false }, { "name": "limit", "in": "query", "type": "number", "description": "Jumlah item per halaman (default: 10).", "required": false } ] }, { "title": "MAL Search", "summary": "MyAnimeList Search.", "description": "Mencari anime di MyAnimeList berdasarkan kata kunci.", "method": "GET", "path": "/api/anime/mal/search", "responseType": "json", "example": "async function searchMAL() {\n const res = await fetch('/api/anime/mal/search?q=Naruto');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Kata kunci pencarian.", "required": true }, { "name": "page", "in": "query", "type": "number", "description": "Nomor halaman (default: 1).", "required": false }, { "name": "limit", "in": "query", "type": "number", "description": "Jumlah item per halaman (default: 10).", "required": false } ] }, { "title": "Oploverz Detail", "summary": "Oploverz Anime Detail.", "description": "Mengambil informasi detail anime Oploverz berdasarkan URL atau Path. Termasuk daftar episode dengan link yang disesuaikan ke API.", "method": "GET", "path": "/api/anime/oploverz/detail", "responseType": "json", "example": "async function getDetail() {\n // Gunakan path relatif (lebih stabil) atau full URL\n const res = await fetch('/api/anime/oploverz/detail?url=/series/spy-x-family-s3');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "query", "type": "string", "description": "URL Oploverz (original link) atau Path (contoh: /series/spy-x-family-s3).", "required": true } ] }, { "title": "Oploverz Home", "summary": "Oploverz Home.", "description": "Mengambil data halaman utama Oploverz, termasuk Carousel, Trending, Rilis Terbaru, dan Tambahan Baru. Link yang dihasilkan telah disesuaikan agar mengarah kembali ke API ini.", "method": "GET", "path": "/api/anime/oploverz/home", "responseType": "json", "example": "async function getHome() {\n const res = await fetch('/api/anime/oploverz/home');\n const data = await res.json();\n console.log(data);\n }\n \n getHome();", "params": [] }, { "title": "Oploverz Schedule", "summary": "Jadwal Rilis Anime.", "description": "Mengambil jadwal rilis anime mingguan dari Oploverz.", "method": "GET", "path": "/api/anime/oploverz/schedule", "responseType": "json", "example": "async function getSchedule() {\n const res = await fetch('/api/anime/oploverz/schedule');\n const data = await res.json();\n console.log(data);\n }", "params": [] }, { "title": "Oploverz Search", "summary": "Oploverz Search.", "description": "Mencari anime di Oploverz berdasarkan kata kunci menggunakan API backend resmi mereka.", "method": "GET", "path": "/api/anime/oploverz/search", "responseType": "json", "example": "async function search() {\n const res = await fetch('/api/anime/oploverz/search?q=Naruto');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Kata kunci pencarian (contoh: \"Naruto\").", "required": true } ] }, { "title": "Oploverz Stream", "summary": "Oploverz Stream & Download.", "description": "Mengambil link streaming dan download untuk episode anime Oploverz berdasarkan URL atau Path.", "method": "GET", "path": "/api/anime/oploverz/stream", "responseType": "json", "example": "async function getStream() {\n // Gunakan path relatif\n const res = await fetch('/api/anime/oploverz/stream?url=/series/spy-x-family-s3/episode/1');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "query", "type": "string", "description": "URL Episode Oploverz atau Path (contoh: /series/spy-x-family-s3/episode/1).", "required": true } ] }, { "title": "Samehadaku Detail", "summary": "Detail Anime Samehadaku.", "description": "Mengambil informasi detail anime Samehadaku berdasarkan URL atau Path. Mengembalikan metadata, sinopsis, daftar genre, rekomendasi, dan list episode.", "method": "GET", "path": "/api/anime/samehadaku/detail", "responseType": "json", "example": "async function getDetail() {\n const res = await fetch('/api/anime/samehadaku/detail?url=/anime/golden-kamuy-final-season/');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "query", "type": "string", "description": "URL Samehadaku (original link) atau Path relatif.", "required": true } ] }, { "title": "Samehadaku Embed URL", "summary": "Get Embed Iframe URL.", "description": "Mengambil link embed video (iframe) asli dari Samehadaku berdasarkan data post, nume, dan type.", "method": "GET", "path": "/api/anime/samehadaku/embed", "responseType": "json", "example": "async function getEmbed() {\n const res = await fetch('/api/anime/samehadaku/embed?post=47702&nume=2&type=schtml');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "post", "in": "query", "type": "string", "description": "ID Post episode.", "required": true }, { "name": "nume", "in": "query", "type": "string", "description": "Nomor server (nume).", "required": true }, { "name": "type", "in": "query", "type": "string", "description": "Tipe embed (misal: schtml).", "required": true }, { "name": "url", "in": "query", "type": "string", "description": "URL halaman episode sebagai referer (opsional).", "required": false } ] }, { "title": "Samehadaku Home", "summary": "Beranda Samehadaku.", "description": "Mengambil data dari halaman utama Samehadaku, mencakup anime Top 10 minggu ini, update episode terbaru, dan daftar project movies. Link sudah di-proxy ke API ini.", "method": "GET", "path": "/api/anime/samehadaku/home", "responseType": "json", "example": "async function getHome() {\n const res = await fetch('/api/anime/samehadaku/home');\n const data = await res.json();\n console.log(data);\n }", "params": [] }, { "title": "Samehadaku Anime List", "summary": "Daftar Semua Anime.", "description": "Mengambil halaman daftar anime terbaru di Samehadaku. Mendukung paginasi dan mengembalikan meta pagination untuk request halaman selanjutnya.", "method": "GET", "path": "/api/anime/samehadaku/list", "responseType": "json", "example": "async function getList() {\n const res = await fetch('/api/anime/samehadaku/list?page=1');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "page", "in": "query", "type": "number", "description": "Nomor halaman yang ingin diambil (default: 1).", "required": false } ] }, { "title": "Samehadaku Schedule", "summary": "Jadwal Rilis Mingguan.", "description": "Mengambil jadwal rilis anime mingguan (Senin - Minggu) dengan menembak API internal Samehadaku secara langsung. Data yang dihasilkan lebih lengkap dan cepat.", "method": "GET", "path": "/api/anime/samehadaku/schedule", "responseType": "json", "example": "async function getSchedule() {\n const res = await fetch('/api/anime/samehadaku/schedule');\n const data = await res.json();\n console.log(data);\n }", "params": [] }, { "title": "Samehadaku Search", "summary": "Pencarian Anime Samehadaku.", "description": "Mencari judul anime di Samehadaku. Mengembalikan daftar anime relevan lengkap dengan skor, status, dan genre yang diekstrak dari meta tooltip.", "method": "GET", "path": "/api/anime/samehadaku/search", "responseType": "json", "example": "async function search() {\n const res = await fetch('/api/anime/samehadaku/search?q=Boruto');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Kata kunci pencarian (contoh: \"Boruto\").", "required": true } ] }, { "title": "Samehadaku Stream", "summary": "Streaming & Download Samehadaku.", "description": "Mengambil data episode lengkap dari Samehadaku berdasarkan URL. Otomatis melakukan bypass AJAX untuk mendapatkan URL embed iframe server streaming, dan mengambil daftar link download file asli.", "method": "GET", "path": "/api/anime/samehadaku/stream", "responseType": "json", "example": "async function getStream() {\n const res = await fetch('/api/anime/samehadaku/stream?url=/golden-kamuy-final-season-episode-1/');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "query", "type": "string", "description": "URL Episode Samehadaku atau Path relatif.", "required": true } ] } ], "downloader": [ { "title": "Facebook DL", "summary": "Download video Facebook.", "description": "Mengunduh video dari Facebook menggunakan layanan fsave.io. Mengembalikan thumbnail dan link download video dalam kualitas SD dan HD.", "method": "POST", "path": "/api/downloader/fbdl", "responseType": "json", "example": "async function downloadFB() {\n try {\n const response = await fetch('/api/downloader/fbdl', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"url\": \"https://www.facebook.com/reel/861262849136029/\" \n })\n });\n \n const data = await response.json();\n console.log(data);\n } catch (error) {\n console.error('Error:', error.message);\n }\n }\n \n downloadFB();", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL lengkap dari video Facebook yang ingin diunduh.", "required": true } ] }, { "title": "Instagram DL", "summary": "Download Instagram (Video/Reels).", "description": "Mengunduh konten dari Instagram (Video, Reels, Post) menggunakan AllInOneDownloader.", "method": "POST", "path": "/api/downloader/instagram", "responseType": "json", "example": "async function downloadIG() {\n const res = await fetch('/api/downloader/instagram', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"url\": \"https://www.instagram.com/reel/DOxOvd9jz6f/\" })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL konten Instagram.", "required": true } ] }, { "title": "Savetube Downloader", "summary": "YouTube Video/Audio Downloader (Savetube).", "description": "Mengunduh video atau audio dari YouTube menggunakan provider Savetube. Mendukung metadata lengkap dan pemilihan kualitas (720p, 1080p, MP3).", "method": "POST", "path": "/api/downloader/savetube", "responseType": "json", "example": "async function download() {\n const res = await fetch('/api/downloader/savetube', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"url\": \"https://www.youtube.com/watch?v=Fmf-G9fpwto\",\n \"quality\": \"128\",\n \"type\": \"audio\"\n })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL Video YouTube.", "required": true }, { "name": "quality", "in": "body", "type": "string", "description": "Kualitas target (contoh: '1080', '720', '128' untuk MP3). Jika kosong, akan mengembalikan semua metadata.", "required": false }, { "name": "type", "in": "body", "type": "string", "description": "Tipe konten: 'video' atau 'audio'. Default: 'video'.", "required": false } ] }, { "title": "Snaptik TikTok DL", "summary": "Unduh Video TikTok (Snaptik).", "description": "Mengunduh video TikTok tanpa watermark menggunakan scraping Snaptik.app. Mendukung berbagai link unduhan termasuk HD.", "method": "POST", "path": "/api/downloader/snaptik", "responseType": "json", "example": "async function download() {\n const res = await fetch('/api/downloader/snaptik', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"url\": \"https://www.tiktok.com/@brilionet/video/7483341650115267847\" })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL video TikTok.", "required": true } ] }, { "title": "SoundCloud DL", "summary": "Download lagu dari SoundCloud.", "description": "Mengunduh file audio (MP3) dari SoundCloud menggunakan layanan pihak ketiga. Endpoint ini mengembalikan judul lagu dan URL unduhan langsung.", "method": "POST", "path": "/api/downloader/soundcloud", "responseType": "json", "example": "async function downloadSC() {\n try {\n const response = await fetch('/api/downloader/soundcloud', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"url\": \"https://soundcloud.com/marissa-puteri/dj-the-drum-x-ya-odna-tik-tok\" \n })\n });\n \n const data = await response.json();\n console.log(data);\n } catch (error) {\n console.error('Error:', error.message);\n }\n }\n \n downloadSC();", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL lagu SoundCloud yang ingin diunduh.", "required": true } ] }, { "title": "SoundCloud DL V2", "summary": "SoundCloud Downloader V2 (Direct).", "description": "Mengunduh lagu dari SoundCloud menggunakan metode direct scraping (Client ID Extraction). Lebih stabil dan cepat.", "method": "POST", "path": "/api/downloader/soundcloud-v2", "responseType": "json", "example": "async function downloadSC() {\n const res = await fetch('/api/downloader/soundcloud-v2', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"url\": \"https://soundcloud.com/tyo-rizki-413604039/dj-ya-odna-x-the-drum-breakbeat-andra-fvnky-rmx\" \n })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL lagu SoundCloud yang valid.", "required": true } ] }, { "title": "TikTok DL", "summary": "Mengunduh video TikTok tanpa watermark.", "description": "Memproses URL video TikTok dan mengembalikan informasi video beserta link unduhan langsung (tanpa watermark) dan link audio dalam format JSON.", "method": "POST", "path": "/api/downloader/tiktok", "responseType": "json", "example": "// Contoh penggunaan\n async function downloadTikTok() {\n try {\n const response = await fetch('/api/downloader/tiktok', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n // PENTING: Gunakan format JSON valid (key dengan kutip ganda) agar Auto Fill berfungsi\n body: JSON.stringify({ \"url\": \"https://www.tiktok.com/@brilionet/video/7483341650115267847\" })\n });\n \n const data = await response.json();\n console.log(data);\n } catch (error) {\n console.error('Error:', error.message);\n }\n }\n \n downloadTikTok();", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL lengkap dari video TikTok yang ingin diunduh.", "required": true } ] }, { "title": "TikTok DL V2", "summary": "TikTok Downloader (TikDownloader.io).", "description": "Mengunduh video TikTok tanpa watermark atau slide foto menggunakan provider TikDownloader.io. Credit: Yabes.", "method": "POST", "path": "/api/downloader/tiktok-v2", "responseType": "json", "example": "async function download() {\n const res = await fetch('/api/downloader/tiktok-v2', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"url\": \"https://www.tiktok.com/@alenkainventra/video/7351044913112321288\" })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL video TikTok.", "required": true } ] }, { "title": "X Downloader", "summary": "X/Twitter Video Downloader.", "description": "Mengunduh video dari platform X (Twitter) menggunakan layanan xsaver.io. Mengembalikan judul video dan daftar link download kualitas yang tersedia.", "method": "POST", "path": "/api/downloader/x", "responseType": "json", "example": "async function downloadX() {\n const res = await fetch('/api/downloader/x', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"url\": \"https://x.com/elsyandria/status/1218385778880831488\" })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL video X/Twitter yang ingin diunduh.", "required": true } ] }, { "title": "YouTube DL", "summary": "YouTube Downloader (YTDown).", "description": "Mengunduh video dan audio dari YouTube menggunakan layanan YTDown. Mendukung berbagai resolusi (hingga 1080p FHD).", "method": "POST", "path": "/api/downloader/youtube", "responseType": "json", "example": "async function dl() {\n const res = await fetch('/api/downloader/youtube', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"url\": \"https://www.youtube.com/watch?v=Fmf-G9fpwto\" })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL video YouTube yang valid.", "required": true } ] }, { "title": "YTMP3 Audio", "summary": "YouTube to MP3.", "description": "Mengonversi dan mengunduh audio YouTube dalam format MP3 menggunakan layanan YTMP3.mobi.", "method": "POST", "path": "/api/downloader/ytmp3", "responseType": "json", "example": "async function downloadMp3() {\n const res = await fetch('/api/downloader/ytmp3', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"url\": \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\" })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL Video YouTube yang ingin diunduh.", "required": true } ] } ], "main": [ { "title": "Server Ping", "summary": "Memeriksa status server.", "description": "Endpoint ini mengembalikan status sukses beserta timestamp untuk memverifikasi bahwa server aktif dan merespons.", "method": "GET", "path": "/api/main/ping", "responseType": "json", "params": [ { "name": "echo", "in": "query", "type": "string", "description": "Teks opsional yang akan dikembalikan dalam respons.", "required": false } ] } ], "meme": [ { "title": "Lahelu Feed", "summary": "Get Fresh Memes.", "description": "Mengambil feed meme terbaru (Fresh) dari Lahelu. Mendukung paginasi menggunakan cursor.", "method": "GET", "path": "/api/meme/lahelu", "responseType": "json", "example": "async function getMemes() {\n const res = await fetch('/api/meme/lahelu');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "page", "in": "query", "type": "number", "description": "Cursor halaman (integer). Default: 0. Gunakan 'nextCursor' dari respons sebelumnya untuk halaman berikutnya.", "required": false } ] }, { "title": "Ubur Ubur", "summary": "Generator Video Meme.", "description": "Membuat video meme promosi/lucu dengan latar belakang kustom, karakter manusia, dan teks. Endpoint ini menggunakan Server-Sent Events (SSE) karena proses rendering video membutuhkan waktu. Hasil akhir diunggah ke penyimpanan sementara.", "method": "POST", "path": "/api/meme/uburubur", "responseType": "json", "example": "async function generateMeme() {\n const res = await fetch('/api/meme/uburubur', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n \"bgUrl\": \"https://www.puruboy.kozow.com/favicon.jpg\",\n \"humanUrl\": \"https://png.pngtree.com/png-clipart/20240412/original/pngtree-prabowo-subianto-png-image_14789437.png\",\n \"brand\": \"INFO PENTING\",\n \"title\": \"UBUR UBUR\",\n \"slogan\": \"Ikan hiu makan tomat.\",\n \"promo\": \"Makan nasi | Rp5.000\\nMakan angin | Gratis\",\n \"wm\": \"@PuruBoy-API\"\n })\n });\n \n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n console.log(decoder.decode(value));\n }\n }", "params": [ { "name": "bgUrl", "in": "body", "type": "string", "description": "URL gambar background.", "required": true }, { "name": "humanUrl", "in": "body", "type": "string", "description": "URL gambar karakter manusia (transparan disarankan).", "required": true }, { "name": "brand", "in": "body", "type": "string", "description": "Teks brand/merk (atas).", "required": true }, { "name": "title", "in": "body", "type": "string", "description": "Judul utama.", "required": true }, { "name": "slogan", "in": "body", "type": "string", "description": "Slogan di bawah judul.", "required": true }, { "name": "promo", "in": "body", "type": "string", "description": "Detail teks/daftar harga (mendukung newline).", "required": true }, { "name": "wm", "in": "body", "type": "string", "description": "Teks watermark (kanan bawah).", "required": true } ] } ], "play": [ { "title": "SoundCloud Play", "summary": "Play SoundCloud Audio.", "description": "Mencari lagu di SoundCloud, memfilter durasi (1-10 menit), dan mengambil URL download langsung. Menggabungkan fungsi pencarian dan pengunduhan dalam satu request untuk mendapatkan audio yang bisa diputar/diunduh.", "method": "GET", "path": "/api/play/soundcloud", "responseType": "json", "example": "async function play() {\n const res = await fetch('/api/play/soundcloud?q=dj+ya+odna');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Judul lagu atau kata kunci pencarian.", "required": true } ] } ], "search": [ { "title": "Lahelu Search", "summary": "Cari Meme Lahelu.", "description": "Mencari meme di Lahelu berdasarkan kata kunci.", "method": "GET", "path": "/api/search/lahelu", "responseType": "json", "example": "async function searchMemes() {\n const res = await fetch('/api/search/lahelu?q=kucing');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Kata kunci pencarian.", "required": true }, { "name": "page", "in": "query", "type": "number", "description": "Cursor halaman (integer). Default: 0.", "required": false } ] }, { "title": "Lyrics Search", "summary": "Search Song Lyrics.", "description": "Mencari lirik lagu berdasarkan judul atau artis menggunakan LRCLIB. Mengembalikan lirik biasa (plain) dan tersinkronisasi (synced/LRC) jika tersedia.", "method": "GET", "path": "/api/search/lyrics", "responseType": "json", "example": "async function getLyrics() {\n const res = await fetch('/api/search/lyrics?q=Alan Walker Faded');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Judul lagu atau nama artis.", "required": true } ] }, { "title": "Pinterest Search", "summary": "Search Pinterest Pins.", "description": "Mencari gambar atau pin di Pinterest berdasarkan kata kunci. Mengambil sesi dan token secara otomatis untuk mengakses API internal Pinterest.", "method": "GET", "path": "/api/search/pinterest", "responseType": "json", "example": "async function pinterestSearch() {\n try {\n const res = await fetch('/api/search/pinterest?q=Anime Wallpaper');\n const data = await res.json();\n console.log(data);\n } catch (e) {\n console.error(e);\n }\n }", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Kata kunci pencarian (contoh: \"Anime Wallpaper\").", "required": true } ] }, { "title": "SoundCloud Search", "summary": "Search SoundCloud Tracks.", "description": "Melakukan pencarian lagu di SoundCloud berdasarkan kata kunci. Endpoint ini mengembalikan daftar lagu yang cocok beserta metadata seperti durasi dan jumlah pemutaran.", "method": "GET", "path": "/api/search/soundcloud", "responseType": "json", "example": "// Contoh penggunaan\n async function searchSoundCloud() {\n try {\n const response = await fetch('/api/search/soundcloud?q=lofi&limit=5');\n const data = await response.json();\n console.log(data);\n } catch (error) {\n console.error('Error:', error);\n }\n }\n \n searchSoundCloud();", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Kata kunci pencarian (judul lagu/artis).", "required": true }, { "name": "limit", "in": "query", "type": "string", "description": "Batas jumlah hasil yang ditampilkan (default: 10).", "required": false } ] }, { "title": "YouTube Search", "summary": "Search YouTube Videos.", "description": "Mencari video di YouTube berdasarkan kata kunci menggunakan provider pihak ketiga. Mengembalikan judul, link video, channel, durasi, dan thumbnail.", "method": "GET", "path": "/api/search/youtube", "responseType": "json", "example": "async function searchYouTube() {\n const res = await fetch('/api/search/youtube?q=DJ ya odna');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Kata kunci pencarian.", "required": true } ] } ], "tools": [ { "title": "Brat Generator", "summary": "Brat Generator (Text to Image).", "description": "Membuat meme teks gaya \"Brat\" berdasarkan input teks menggunakan API eksternal yang cepat. Mengembalikan URL gambar hasil (PNG) yang sudah diproses menjadi URL publik.", "method": "POST", "path": "/api/tools/brat", "responseType": "json", "example": "async function createBrat() {\n const res = await fetch('/api/tools/brat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"text\": \"hai kamu siapa sih😈\" })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "text", "in": "body", "type": "string", "description": "Teks yang akan ditampilkan pada gambar.", "required": true } ] }, { "title": "Ghibli Style", "summary": "Transform Image to Ghibli Style.", "description": "Mengubah foto menjadi gaya seni anime Studio Ghibli. Endpoint ini menggunakan Server-Sent Events (SSE).", "method": "POST", "path": "/api/tools/ghibli", "responseType": "json", "example": "// Contoh penggunaan SSE\n async function ghibliTransform() {\n const response = await fetch('/api/tools/ghibli', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"url\": \"https://puruboy-api.vercel.app/example.jpg\",\n \"prompt\": \"Jadikan ghibli\"\n })\n });\n \n const reader = response.body.getReader();\n // Read stream...\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL gambar sumber.", "required": true }, { "name": "prompt", "in": "body", "type": "string", "description": "Prompt kustom (opsional).", "required": false } ] }, { "title": "ImgBB Uploader", "summary": "Upload Gambar ke ImgBB.", "description": "Mengupload gambar ke ImgBB dan mendapatkan direct link secara gratis. Mendukung format JPG, PNG, BMP, GIF, TIF, WEBP, HEIC, PDF.", "method": "POST", "path": "/api/tools/imgbb", "responseType": "json", "example": "// Contoh penggunaan dengan FormData (Browser)\n const formData = new FormData();\n formData.append('image', fileInput.files[0]);\n \n const res = await fetch('/api/tools/imgbb', {\n method: 'POST',\n body: formData\n });\n \n const data = await res.json();\n console.log(data);", "params": [ { "name": "image", "in": "formData", "type": "file", "description": "File gambar yang akan diupload.", "required": true } ] }, { "title": "MLBB Region Checker", "summary": "Cek Region & Nickname MLBB.", "description": "Mengecek region ID, nickname, dan metadata akun Mobile Legends: Bang Bang berdasarkan User ID dan Zone ID menggunakan layanan PizzoShop.", "method": "POST", "path": "/api/tools/mlbb", "responseType": "json", "example": "async function checkML() {\n const res = await fetch('/api/tools/mlbb', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"userId\": \"2002113712\", \n \"zoneId\": \"19417\" \n })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "userId", "in": "body", "type": "string", "description": "User ID Mobile Legends.", "required": true }, { "name": "zoneId", "in": "body", "type": "string", "description": "Zone ID Mobile Legends.", "required": true } ] }, { "title": "MP4 to MP3 Converter", "summary": "Konversi Video MP4 ke Audio MP3.", "description": "Mengekstrak audio dari file video MP4 dan mengubahnya menjadi format MP3. Endpoint ini menggunakan Server-Sent Events (SSE) untuk memberikan update status proses konversi secara real-time.", "method": "POST", "path": "/api/tools/mp4tomp3", "responseType": "json", "example": "async function convert() {\n const res = await fetch('/api/tools/mp4tomp3', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"url\": \"https://files.catbox.moe/1w27hq.mp4\" })\n });\n \n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n console.log(decoder.decode(value));\n }\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL publik file MP4 yang ingin dikonversi.", "required": true } ] }, { "title": "OnePage Host", "summary": "Buat halaman web instan.", "description": "Membuat dan meng-host halaman HTML statis secara gratis menggunakan layanan 1page. Berguna untuk membuat landing page sementara atau berbagi kode HTML hasil render.", "method": "POST", "path": "/api/tools/onepage", "responseType": "json", "example": "async function createPage() {\n const res = await fetch('/api/tools/onepage', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"name\": \"promo-today\", \n \"html\": \"

Selamat Datang

Ini halaman otomatis.

\" \n })\n });\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "name", "in": "body", "type": "string", "description": "Nama atau slug halaman (contoh: 'halaman-saya').", "required": true }, { "name": "html", "in": "body", "type": "string", "description": "Konten kode HTML lengkap.", "required": true } ] }, { "title": "Al-Quran Digital", "summary": "Al-Quran Digital Kemenag.", "description": "Mengambil data ayat-ayat suci Al-Quran beserta terjemahan dan teks latin langsung dari sumber web-api Kemenag. Respons telah dirapikan dan dibersihkan dari properti bernilai null untuk efisiensi data.", "method": "GET", "path": "/api/tools/quran", "responseType": "json", "example": "async function getQuran() {\n const res = await fetch('/api/tools/quran?surah=10&ayah=1,2');\n const data = await res.json();\n console.log(data.result.data);\n }", "params": [ { "name": "surah", "in": "query", "type": "string", "description": "Nomor surah (1-114).", "required": true }, { "name": "ayah", "in": "query", "type": "string", "description": "Nomor ayat spesifik atau daftar ayat dipisah koma (contoh: \"1,2,3\"). Default: \"all\".", "required": false } ] }, { "title": "Remove BG", "summary": "Hapus Background Gambar.", "description": "Menghapus latar belakang gambar menggunakan API Pixelcut dan mengupload hasilnya ke penyimpanan sementara. Mengembalikan URL gambar hasil (PNG).", "method": "POST", "path": "/api/tools/removebg", "responseType": "json", "example": "// Contoh penggunaan\n async function removeBg() {\n try {\n const response = await fetch('/api/tools/removebg', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"url\": \"https://puruboy-api.vercel.app/example.jpg\" \n })\n });\n \n const data = await response.json();\n console.log(data); \n // Output: { status: 'success', url: 'https://domain.com/api/media/...' }\n } catch (error) {\n console.error('Error:', error.message);\n }\n }\n \n removeBg();", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL publik dari gambar yang ingin diproses.", "required": true } ] }, { "title": "Remove BG V2", "summary": "Hapus Background V2 (ILoveIMG).", "description": "Menghapus latar belakang gambar menggunakan layanan ILoveIMG. Alternatif handal untuk menghapus background dengan presisi tinggi.", "method": "POST", "path": "/api/tools/removebg-v2", "responseType": "json", "example": "// Contoh penggunaan\n async function removeBg() {\n try {\n const response = await fetch('/api/tools/removebg-v2', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"url\": \"https://puruboy-api.vercel.app/example.jpg\" \n })\n });\n \n const data = await response.json();\n console.log(data); \n } catch (error) {\n console.error('Error:', error.message);\n }\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL publik dari gambar yang ingin diproses.", "required": true } ] }, { "title": "Colorize Image", "summary": "Colorize Image (Kolorize).", "description": "Mewarnai gambar hitam putih menggunakan AI Kolorize. Endpoint ini menggunakan Server-Sent Events (SSE). Hasil akhir disimpan sementara dalam database selama 30 menit dan URL pengambilan data dikirim melalui stream.", "method": "POST", "path": "/api/tools/reviva", "responseType": "json", "example": "// Contoh penggunaan (Membaca stream SSE di client)\n async function colorizeImage() {\n const response = await fetch('/api/tools/reviva', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n \"url\": \"https://puruboy-api.vercel.app/example.jpg\" \n })\n });\n \n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n \n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n const text = decoder.decode(value);\n console.log(\"Received:\", text);\n \n // Cek sinyal sukses\n if(text.includes('[true]')) {\n const retrieveUrl = text.replace('[true]', '').trim();\n console.log(\"Data tersedia di:\", retrieveUrl);\n // fetch(retrieveUrl)...\n } else if (text.includes('[false]')) {\n const errorMsg = text.replace('[false]', '').trim();\n console.error(\"Error:\", errorMsg);\n }\n }\n }\n \n colorizeImage();", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL gambar (hitam putih) yang ingin diwarnai.", "required": true } ] }, { "title": "Jadwal Sholat", "summary": "Jadwal Sholat Bulanan.", "description": "Mengambil jadwal sholat bulanan berdasarkan nama kota di Indonesia. Dilengkapi dengan algoritma similarity untuk menangani kesalahan penulisan (tyo) nama kota.", "method": "GET", "path": "/api/tools/sholat", "responseType": "json", "example": "async function getSholat() {\n const res = await fetch('/api/tools/sholat?q=jakarta');\n const data = await res.json();\n console.log(data);\n }", "params": [ { "name": "q", "in": "query", "type": "string", "description": "Nama kota (contoh: \"Jakarta\", \"Bandung\", \"Subang\").", "required": true } ] }, { "title": "AI Upscale", "summary": "AI Image Upscale.", "description": "Meningkatkan resolusi dan kualitas gambar menggunakan AI (via Cloudinary). Endpoint ini menggunakan Server-Sent Events (SSE).", "method": "POST", "path": "/api/tools/upscale", "responseType": "json", "example": "// Contoh penggunaan SSE\n async function upscaleImage() {\n const response = await fetch('/api/tools/upscale', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \"url\": \"https://puruboy-api.vercel.app/example.jpg\" })\n });\n \n const reader = response.body.getReader();\n // Read stream...\n }", "params": [ { "name": "url", "in": "body", "type": "string", "description": "URL gambar yang ingin di-upscale.", "required": true } ] } ] } --- // FILE: public/admin.html Admin Console
🔐

Admin Access

Masukkan kredensial untuk melanjutkan

--- // FILE: lib/ytsearch.js const axios = require('axios'); /** * Fungsi untuk mencari lagu di devers-en-geste.fr dan menampilkan Link YouTube * @param {string} query - Kata kunci pencarian */ async function search(query) { if (!query) throw new Error("Query is required."); const baseURL = 'https://www.devers-en-geste.fr/search'; try { const response = await axios.get(baseURL, { params: { q: query }, headers: { 'Accept': 'application/json, text/javascript, */*; q=0.01', 'X-Requested-With': 'XMLHttpRequest', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', 'Referer': 'https://www.devers-en-geste.fr/' } }); const data = response.data; if (!data.items) return []; return data.items.map(item => ({ title: item.title, url: `https://www.youtube.com/watch?v=${item.id}`, videoId: item.id, channel: item.channelTitle, duration: item.duration, size: item.size, thumbnail: `https://i.ytimg.com/vi/${item.id}/hqdefault.jpg` })); } catch (error) { throw new Error(error.message); } } module.exports = { search }; --- // FILE: lib/ytmp3.js const axios = require('axios'); const vm = require('vm'); // ========================================== // MOCK DOM (Minimalist) // ========================================== function createMockDOM() { const noop = () => {}; const mockElement = { style: {}, setAttribute: noop, getAttribute: () => '', appendChild: () => mockElement, innerHTML: '', value: '', click: noop }; return { window: {}, document: { getElementById: () => mockElement, createElement: () => mockElement, querySelector: () => mockElement, querySelectorAll: () => [mockElement], cookie: '', body: mockElement, head: mockElement, location: { href: 'https://id.ytmp3.mobi/' } }, navigator: { userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/121.0.0.0 Safari/537.36', serviceWorker: { register: () => Promise.resolve() } }, location: { href: 'https://id.ytmp3.mobi/' }, console: { log: noop, error: noop }, String: String, Math: Math, Date: Date, parseInt: parseInt, setTimeout: (cb) => cb(), setInterval: noop, clearTimeout: noop }; } // ========================================== // CONFIG FETCHER // ========================================== async function getFreshConfig() { try { const homeRes = await axios.get('https://id.ytmp3.mobi/v1/'); const jsMatch = homeRes.data.match(/src="(\/js\/ytmp3\.js\?t=[0-9]+)"/); if (!jsMatch) throw new Error('JS File not found'); const jsUrl = `https://id.ytmp3.mobi${jsMatch[1]}`; const jsRes = await axios.get(jsUrl); const code = jsRes.data; // --- STEP 1: VM Execution --- const sandbox = createMockDOM(); sandbox.window = sandbox; const context = vm.createContext(sandbox); try { vm.runInContext(code, context); } catch (e) {} let backend = sandbox.backend; // --- STEP 2: FIX BACKEND --- if (!backend || backend === '.ymcdn.org' || backend.startsWith('https:.') || backend.startsWith('.')) { const subMatch = code.match(/['"](https:\/\/[a-z])['"]/); if (subMatch) { backend = `${subMatch[1]}.ymcdn.org`; } else { backend = 'https://d.ymcdn.org'; } } else { if (backend.startsWith('//')) backend = 'https:' + backend; if (!backend.startsWith('http')) backend = 'https://' + backend; } // --- STEP 3: DECODE INIT PARAMS --- let initQuery = 'it?p=y&23='; let initToken = '1llum1n471'; const decoderMatch = code.match(/var\s+(_0x[a-f0-9]+)\s*=\s*_0x[a-f0-9]+;/); if (decoderMatch) { const decoder = sandbox[decoderMatch[1]]; if (typeof decoder === 'function') { for (let i = 0; i < 800; i++) { try { const val = decoder(i); if (val && typeof val === 'string') { if (val.includes('it?p=')) initQuery = val; if (val.length === 10 && /\d.*[a-z]/.test(val)) initToken = val; } } catch (e) {} } } } return { BASE_DOMAIN: backend, INIT_QUERY: initQuery, INIT_TOKEN: initToken }; } catch (error) { return { BASE_DOMAIN: 'https://d.ymcdn.org', INIT_QUERY: 'it?p=y&23=', INIT_TOKEN: '1llum1n471' }; } } const HEADERS = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/121.0.0.0 Safari/537.36', 'Referer': 'https://id.ytmp3.mobi/', 'Origin': 'https://id.ytmp3.mobi' }; const getRandom = () => Math.random().toString(); async function download(url) { if (!url) throw new Error("URL wajib diisi."); // Extract Video ID (Support standard & short links) const idMatch = url.match(/(?:v=|\/)([0-9A-Za-z_-]{11})/); if (!idMatch) throw new Error("URL YouTube tidak valid."); const videoId = idMatch[1]; try { // 1. Config const config = await getFreshConfig(); // 2. Init const cleanQuery = config.INIT_QUERY.replace('it?', 'init?').replace('/api/v1/', ''); const initUrl = `${config.BASE_DOMAIN}/api/v1/${cleanQuery}${config.INIT_TOKEN}&_=${getRandom()}`; const initRes = await axios.get(initUrl, { headers: HEADERS }); if (initRes.data.error) throw new Error(initRes.data.error); // 3. Convert const doConvert = async (targetUrl) => { const prefix = targetUrl.includes('?') ? '&' : '?'; const res = await axios.get(`${targetUrl}${prefix}v=${videoId}&f=mp3&_=${getRandom()}`, { headers: HEADERS }); if (res.data.redirectURL) return doConvert(res.data.redirectURL); return res.data; }; const convertData = await doConvert(initRes.data.convertURL); // 4. Progress let result = null; for (let i = 0; i < 40; i++) { const res = await axios.get(`${convertData.progressURL}&_=${getRandom()}`, { headers: HEADERS }); if (res.data.progress == 3) { result = res.data; break; } await new Promise(r => setTimeout(r, 1500)); } if (!result) throw new Error('Timeout saat konversi.'); return { title: result.title, download_url: convertData.downloadURL, source: 'ytmp3.mobi' }; } catch (e) { throw new Error(e.message || "Gagal mengunduh MP3."); } } module.exports = { download }; --- // FILE: lib/ytdown.js const axios = require('axios'); const qs = require('qs'); /** * YTDown.to Automation Fix * Berdasarkan hasil intercept AJAX & HAR Terbaru */ class YTDown { constructor() { this.baseUrl = 'https://app.ytdown.to'; this.session = axios.create({ baseURL: this.baseUrl, headers: { 'authority': 'app.ytdown.to', 'accept': '*/*', 'accept-language': 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7', 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 'origin': this.baseUrl, 'referer': `${this.baseUrl}/id2/`, 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', 'x-requested-with': 'XMLHttpRequest' }, withCredentials: true }); this.cookie = ""; } async download(youtubeUrl) { try { // --- STEP 1: INITIAL VISIT (Get Session Cookie) --- const init = await this.session.get('/id2/'); this.cookie = init.headers['set-cookie'] ? init.headers['set-cookie'][0].split(';')[0] : ""; // Update header dengan cookie yang didapat const headers = { 'Cookie': this.cookie }; // --- STEP 2: COOLDOWN CHECK (Handshake) --- const check = await this.session.post('/cooldown.php', qs.stringify({ action: 'check' }), { headers }); if (!check.data.can_download) { throw new Error("Server Cooldown: Silakan tunggu beberapa saat."); } // --- STEP 3: GET VIDEO INFO & FORMATS --- const info = await this.session.post('/proxy.php', qs.stringify({ url: youtubeUrl }), { headers }); if (!info.data.api || info.data.api.status !== 'ok') { throw new Error("Gagal mengambil info video. Pastikan URL benar."); } const videoData = info.data.api; // Pilih kualitas (Default: HD/720p atau pertama tersedia) const selectedMedia = videoData.mediaItems.find(m => m.mediaQuality === 'HD') || videoData.mediaItems[0]; // --- STEP 4: RECORD ACTION --- await this.session.post('/cooldown.php', qs.stringify({ action: 'record' }), { headers }); // --- STEP 5: POLLING CONVERSION --- let isReady = false; let downloadLink = ""; let attempts = 0; while (!isReady && attempts < 30) { const convert = await this.session.post('/proxy.php', qs.stringify({ url: selectedMedia.mediaUrl }), { headers }); const result = convert.data.api; if (result.status === 'completed') { isReady = true; downloadLink = result.fileUrl; return { success: true, title: videoData.title, quality: selectedMedia.mediaQuality, size: result.fileSize, downloadUrl: downloadLink, thumbnail: videoData.imagePreviewUrl }; } else if (result.status === 'queued' || result.status === 'processing') { attempts++; await new Promise(r => setTimeout(r, 3000)); // Tunggu 3 detik } else { throw new Error("Terjadi kesalahan saat konversi."); } } throw new Error("Timeout: Proses terlalu lama."); } catch (err) { throw new Error(err.message); } } } module.exports = new YTDown(); --- // FILE: lib/xdownloader.js const axios = require('axios'); const cheerio = require('cheerio'); /** * X/Twitter Video Downloader for xsaver.io * @param {string} twitterUrl - URL video dari X (Twitter) */ async function getXVideoInfo(twitterUrl) { try { const baseUrl = 'https://www.xsaver.io/x-downloader/'; const targetUrl = `${baseUrl}download.php?url=${encodeURIComponent(twitterUrl)}`; const response = await axios.get(targetUrl, { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Referer': 'https://www.xsaver.io/x-downloader/id/', 'Accept-Language': 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7' } }); const $ = cheerio.load(response.data); const results = []; // 1. Ambil Judul Video const title = $('.video-title').text().trim(); // 2. Iterasi setiap item media yang ditemukan $('.media-item').each((index, element) => { const thumb = $(element).find('.media-thumb img').attr('src'); // Mencari link download video (save-url.php) const downloadLinkRaw = $(element).find('a[href^="save-url.php"]').attr('href'); if (downloadLinkRaw) { // Ekstraksi URL asli dari parameter query 'url' const urlParams = new URLSearchParams(downloadLinkRaw.split('?')[1]); const directVideoUrl = urlParams.get('url'); results.push({ id: index + 1, type: 'video', thumbnail: thumb, url: directVideoUrl, proxy_link: baseUrl + downloadLinkRaw }); } }); return { success: true, title: title || 'X Video', results: results }; } catch (error) { return { success: false, message: error.message }; } } module.exports = { getXVideoInfo }; --- // FILE: lib/upscale.js const axios = require('axios'); const FormData = require('form-data'); const { uploadToTmp } = require('./uploader'); // --- KONFIGURASI CONSTANTS --- const TARGET_URL = 'https://cloudinary.com/tools/image-upscale'; const SIGNER_URL = 'https://cloudinary-tools.netlify.app/.netlify/functions/sign-upload-params'; // --- FALLBACK CONFIG --- const FALLBACK_CONFIG = { cloudName: 'dtz0urit6', apiKey: '985946268373735', uploadPreset: 'cloudinary-tools' }; const client = axios.create({ headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Referer': TARGET_URL } }); /** * 1. DYNAMIC CONFIG EXTRACTOR */ async function getDynamicConfig() { try { const htmlParams = await client.get(TARGET_URL); const scriptMatch = htmlParams.data.match(/src="([^"]*\/app\.js[^"]*)"/); if (!scriptMatch) throw new Error("Path app.js tidak ditemukan."); const appJsUrl = new URL(scriptMatch[1], TARGET_URL).href; const jsParams = await client.get(appJsUrl); const jsContent = jsParams.data; const cloudNameMatch = jsContent.match(/cloudName\s*=\s*\(isLocal\)\s*\?\s*'[^']+'\s*:\s*'([^']+)'/); const apiKeyMatch = jsContent.match(/api_key\s*=\s*\(isLocal\)\s*\?\s*'[^']+'\s*:\s*'([^']+)'/); const presetMatch = jsContent.match(/uploadPreset\s*=\s*\(isLocal\)\s*\?\s*'[^']+'\s*:\s*'([^']+)'/); if (cloudNameMatch && apiKeyMatch && presetMatch) { return { cloudName: cloudNameMatch[1], apiKey: apiKeyMatch[1], uploadPreset: presetMatch[1] }; } throw new Error("Gagal regex config."); } catch (error) { return FALLBACK_CONFIG; } } /** * 2. SIGNATURE GENERATOR */ async function getSignature(config, timestamp) { try { const payload = { paramsToSign: { source: 'uw', timestamp: timestamp, upload_preset: config.uploadPreset } }; const response = await client.post(SIGNER_URL, payload, { headers: { 'Content-Type': 'application/json' } }); if (!response.data.signature) throw new Error("Signature kosong."); return response.data.signature; } catch (error) { throw new Error(`Gagal get signature: ${error.message}`); } } /** * 3. UPLOADER (Buffer Support) */ async function uploadImage(config, signature, timestamp, imageBuffer) { const form = new FormData(); form.append('file', imageBuffer, { filename: 'input.jpg' }); form.append('api_key', config.apiKey); form.append('timestamp', timestamp); form.append('upload_preset', config.uploadPreset); form.append('signature', signature); form.append('source', 'uw'); const uploadUrl = `https://api.cloudinary.com/v1_1/${config.cloudName}/auto/upload`; try { const response = await client.post(uploadUrl, form, { headers: { ...form.getHeaders() } }); return response.data; } catch (error) { throw new Error(`Upload gagal: ${error.response?.data?.error?.message || error.message}`); } } const upscale = { process: async (url) => { try { // 1. Download source image const imgRes = await axios.get(url, { responseType: 'arraybuffer' }); const imgBuffer = Buffer.from(imgRes.data); // 2. Get Config const config = await getDynamicConfig(); // 3. Auth const timestamp = Math.floor(Date.now() / 1000); const signature = await getSignature(config, timestamp); // 4. Upload to Cloudinary const uploadResult = await uploadImage(config, signature, timestamp, imgBuffer); // 5. Construct URL // Parameter Transformasi Cloudinary: e_upscale, q_auto, f_auto const transformation = 'e_upscale,q_auto,f_auto'; const cloudinaryUrl = `https://res.cloudinary.com/${config.cloudName}/image/upload/${transformation}/${uploadResult.public_id}`; // 6. Download Result const resultRes = await axios.get(cloudinaryUrl, { responseType: 'arraybuffer' }); const resultBuffer = Buffer.from(resultRes.data); // 7. Upload to Public Server (Puruh2o / tmp) const publicUrl = await uploadToTmp(resultBuffer, `upscale-${Date.now()}.jpg`); return { success: true, image: publicUrl }; } catch (error) { return { success: false, error: error.message }; } } }; module.exports = { upscale }; --- // FILE: lib/uploader.js const axios = require('axios'); const FormData = require('form-data'); const { encrypt } = require('./crypto'); /** * Upload file ke layanan sementara (tmpfiles.org). * Mengembalikan URL Proxy terenkripsi (/api/media/...). */ async function uploadToTmp(buffer, filename = 'image.png') { if (!Buffer.isBuffer(buffer)) { throw new Error('Input harus berupa Buffer.'); } const form = new FormData(); form.append("file", buffer, filename); try { const response = await axios.post("https://tmpfiles.org/api/v1/upload", form, { headers: { ...form.getHeaders(), 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36' } }); if (response.data.status !== 'success') { throw new Error('Gagal mengupload ke tmpfiles.org'); } const rawUrl = response.data.data.url; // Perbaikan Regex: Pastikan menyisipkan /dl/ tepat setelah domain tmpfiles.org // Mendukung variasi http/https dan www. const realUrl = rawUrl.replace(/https?:\/\/(www\.)?tmpfiles\.org\//, 'https://tmpfiles.org/dl/'); // Encrypt URL dan kembalikan Path Proxy relatif const encrypted = encrypt(realUrl); const proxyUrl = `/api/media/${encrypted}`; return proxyUrl; } catch (error) { if (error.response) { throw new Error(`Uploader Error: Upload failed with status ${error.response.status}`); } throw new Error(`Uploader Error: ${error.message}`); } } module.exports = { uploadToTmp }; --- // FILE: lib/unlimited.js const axios = require('axios'); const { v4: uuidv4 } = require('uuid'); const TARGET_URL = 'https://app.unlimitedai.chat/'; const ACTION_ID = '40713570958bf1accf30e8d3ddb17e7948e6c379fa'; // ID Fungsi Server const CHAT_MODEL = 'chat-model-reasoning'; // Model default function parseNextJsStream(chunk) { const lines = chunk.toString().split('\n'); let cleanText = ''; for (const line of lines) { if (line.includes('"diff":[0,')) { try { const jsonStartIndex = line.indexOf('{'); if (jsonStartIndex !== -1) { const jsonStr = line.substring(jsonStartIndex); const data = JSON.parse(jsonStr); if (data.diff && Array.isArray(data.diff) && data.diff[0] === 0) { cleanText += data.diff[1]; } } } catch (e) { // Abaikan error parsing } } } return cleanText; } async function* chatStream(message) { const HEADERS = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Content-Type': 'text/plain;charset=UTF-8', 'Next-Action': ACTION_ID, 'Next-Router-State-Tree': '%5B%22%22%2C%7B%22children%22%3A%5B%22(chat)%22%2C%7B%22children%22%3A%5B%22page%22%2C%7B%7D%5D%7D%5D%7D%2Cnull%2Cnull%2Ctrue%5D', 'Origin': 'https://app.unlimitedai.chat', 'Referer': 'https://app.unlimitedai.chat/', }; const chatId = uuidv4(); const messageId = uuidv4(); const now = new Date(); const messages = [ { id: messageId, role: "user", content: message, parts: [{ type: "text", text: message }], createdAt: now } ]; const payloadArg = { chatId: chatId, messages: messages, selectedChatModel: CHAT_MODEL, selectedCharacter: null, selectedStory: null, turnstileToken: undefined }; const payload = JSON.stringify([payloadArg]); try { const response = await axios.post(TARGET_URL, payload, { headers: HEADERS, responseType: 'stream' }); for await (const chunk of response.data) { const text = parseNextJsStream(chunk); if (text) yield text; } } catch (error) { throw new Error(error.response?.data ? 'API Unlimited Error' : error.message); } } module.exports = { chatStream }; --- // FILE: lib/tsundere.js const axios = require('axios'); function generateFakeIP() { return Array.from({ length: 4 }, () => Math.floor(Math.random() * 255)).join('.'); } async function generateTsundereTTS(text) { const url = 'https://api.screenapp.io/v2/proxy/google/tts'; const fakeIP = generateFakeIP(); const payload = { "input": text, "model": "gemini-2.5-flash-tts", "voice": "Kore", "language_code": "id-ID", "response_format": "mp3", "speaking_rate": 1.1, "pitch": 2.5, "volume_gain_db": 0 }; const headers = { 'authority': 'api.screenapp.io', 'accept': '*/*', 'content-type': 'application/json', 'origin': 'https://screenapp.io', 'referer': 'https://screenapp.io/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36', 'x-forwarded-for': fakeIP, 'client-ip': fakeIP, 'via': '1.1 google', }; try { const response = await axios({ method: 'post', url: url, data: payload, headers: headers, responseType: 'arraybuffer' }); return Buffer.from(response.data); } catch (error) { throw new Error(error.response?.data ? `TTS Error: ${error.response.status}` : error.message); } } module.exports = { generateTsundereTTS }; --- // FILE: lib/tiktokV2.js /*** *** ᠁᠁᠁᠁᠁᠁᠁᠁᠁᠁᠁᠁᠁ *** - TikTok Downloader *** - Base URL: https://tikdownloader.io *** - Note: Jangan lupa install cloudscraper *** *** - Dev: 𝖸𝖺𝖻𝖾𝗌 *** - Contact: t.me/Yabes_Desu *** - Gmail: yabeskun@gmail.com *** ᠁᠁᠁᠁᠁᠁᠁᠁᠁᠁᠁᠁᠁ ***/ const cloudscraper = require('cloudscraper'); const tiktokDL = async (url, retries = 5) => { if (!url?.trim()) return { success: false, result: 'URL kosong' }; const req = async (opts) => { for (let i = 0; i < retries; i++) { try { const r = await cloudscraper({ ...opts, cloudflareTimeout: 7000, followAllRedirects: true }); return typeof r === 'string' ? JSON.parse(r) : r; } catch (e) { if (i === retries - 1) throw e; await new Promise(r => setTimeout(r, 2 ** i * 1000)); } } }; try { const { status, data, statusCode, msg } = await req({ uri: 'https://tikdownloader.io/api/ajaxSearch', method: 'POST', form: { q: url } }); if (statusCode === 326) return { success: false, result: msg || 'Link invalid' }; if (status !== 'ok' || !data) return { success: false, result: 'Gagal ambil data' }; const html = data.replace(/&(?:amp|lt|gt|quot|#x27|#39|#x2F|nbsp|#xA0|#160|#(\d+)|#x([0-9a-fA-F]+));/gi, (_, dec, hex) => dec ? String.fromCharCode(dec) : hex ? String.fromCharCode(parseInt(hex, 16)) : { '&':'&','<':'<','>':'>','"':'"',''':"'",''':"'",'/':'/',' ':' ',' ':' ',' ':' ' }[_] || _); const $ = s => (html.match(s) || [])[1]?.trim(); const isPhoto = html.includes('photo-list'); const downloads = isPhoto ? [...html.matchAll(/href="([^"]+)"[^>]*btn-premium[^>]*>[\s\S]*?Download Image/g)].map((m, i) => ({ type: `Image ${i+1}`, url: m[1] })) .concat((html.match(/href="([^"]+dl\.snapcdn\.app[^"]+)".*?Download MP3/) || []).slice(1).map(u => ({ type: 'MP3', url: u }))) : [...html.matchAll(/href="([^"]+)"[^>]*tik-button-dl[^>]*>([\s\S]*?)<\/a>/g)].map(m => ({ type: m[2].replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim(), url: m[1] })); if (!downloads.length) return { success: false, result: 'Tidak ada link download' }; return { success: true, result: { type: isPhoto ? 'photo' : 'video', title: $(/]*>([^<]+)<\/h3>/), thumbnail: $(/]*(?:class="[^"]*image-tik[^"]*"|)/), downloads } }; } catch (e) { return { success: false, result: e.message }; } }; module.exports = { tiktokDL }; --- // FILE: lib/tiktok.js // Memindahkan file dari server/api/lib/tiktok.js ke lib/tiktok.js const axios = require('axios'); const TIKTOK_API_BASE = 'https://www.tikwm.com'; const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); async function download(url) { if (!url || typeof url !== 'string') { throw new Error('URL TikTok tidak valid.'); } const submitResponse = await axios.post(`${TIKTOK_API_BASE}/api/video/task/submit`, new URLSearchParams({ url: url, web: '1' }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } }); if (submitResponse.data.code !== 0 || !submitResponse.data.data.task_id) { throw new Error(`Gagal memulai tugas unduhan: ${submitResponse.data.msg || 'Respons tidak valid'}`); } const taskId = submitResponse.data.data.task_id; const maxAttempts = 15; for (let i = 0; i < maxAttempts; i++) { await sleep(1000); const resultResponse = await axios.get(`${TIKTOK_API_BASE}/api/video/task/result`, { params: { task_id: taskId } }); const resultData = resultResponse.data; if (resultData.code !== 0) { continue; } if (resultData.data && resultData.data.status === 2) { return resultData.data; } if (resultData.data && resultData.data.status > 2) { throw new Error(`Proses unduhan gagal dengan status: ${resultData.data.msg || 'Tidak diketahui'}`); } } throw new Error('Gagal mendapatkan hasil unduhan setelah beberapa kali percobaan (timeout).'); } module.exports = { download }; --- // FILE: lib/tempService.js const pool = require('./db'); const { v4: uuidv4 } = require('uuid'); // Ensure table exists const ensureTable = async () => { const query = ` CREATE TABLE IF NOT EXISTS temp_store ( id UUID PRIMARY KEY, data JSONB NOT NULL, expires_at TIMESTAMPTZ NOT NULL ); `; await pool.query(query); }; const tempService = { save: async (data, ttlMinutes = 30) => { await ensureTable(); const id = uuidv4(); // Set expiry time const expiresAt = new Date(Date.now() + ttlMinutes * 60000); const query = 'INSERT INTO temp_store (id, data, expires_at) VALUES ($1, $2, $3)'; await pool.query(query, [id, data, expiresAt]); return id; }, get: async (id) => { await ensureTable(); // Fetch only if not expired const query = 'SELECT data FROM temp_store WHERE id = $1 AND expires_at > NOW()'; const result = await pool.query(query, [id]); if (result.rows.length === 0) return null; return result.rows[0].data; } }; module.exports = tempService; --- // FILE: lib/svara.js // Memindahkan file dari server/api/lib/svara.js ke lib/svara.js // Credit: Daffa dari nbscript (https://whatsapp.com/channel/0029VbBmAXAHAdNWOpWN531c) const axios = require('axios'); const svara = { api: { base: 'https://svara.aculix.net', endpoint: { generate: '/generate-speech', }, }, headers: { 'user-agent': 'NB Android/1.0.0', 'accept-encoding': 'gzip', 'content-type': 'application/json', }, cid: new Uint8Array([ 0x24, 0x52, 0x43, 0x41, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x49, 0x44, 0x3a, 0x31, 0x33, 0x65, 0x38, 0x37, 0x35, 0x33, 0x61, 0x65, 0x36, 0x31, 0x39, 0x34, 0x63, 0x37, 0x62, 0x39, 0x32, 0x37, 0x33, 0x32, 0x64, 0x36, 0x36, 0x64, 0x37, 0x30, 0x32, 0x33, 0x30, 0x37, 0x32 ]), auth: new Uint8Array([ 0x77, 0x76, 0x65, 0x62, 0x6e, 0x79, 0x75, 0x36, 0x36, 0x36, 0x38, 0x37, 0x35, 0x36, 0x68, 0x34, 0x35, 0x67, 0x66, 0x65, 0x63, 0x64, 0x66, 0x65, 0x67, 0x6e, 0x68, 0x6d, 0x75, 0x36, 0x6b, 0x6a, 0x35, 0x68, 0x36, 0x34, 0x67, 0x35, 0x33, 0x66, 0x76, 0x72, 0x62, 0x67, 0x6e, 0x79, 0x35 ]), voiceX: { 'alloy': 'af_alloy', 'aoede': 'af_aoede', 'bella': 'af_bella', 'heart': 'af_heart', 'jessica': 'af_jessica', 'kore': 'af_kore', 'nicole': 'af_nicole', 'nova': 'af_nova', 'river': 'af_river', 'sarah': 'af_sarah', 'sky': 'af_sky', 'adam': 'am_adam', 'echo': 'am_echo', 'eric': 'am_eric', 'fenrir': 'am_fenrir', 'liam': 'am_liam', 'michael': 'am_michael', 'onyx': 'am_onyx', 'puck': 'am_puck', 'santa': 'am_santa', 'alice': 'bf_alice', 'emma': 'bf_emma', 'isabella': 'bf_isabella', 'lily': 'bf_lily', 'daniel': 'bm_daniel', 'fable': 'bm_fable', 'george': 'bm_george', 'lewis': 'bm_lewis', 'anaya': 'hf_alpha', 'riya': 'hf_beta', 'arjun': 'hm_omega', 'kabir': 'hm_psi', 'dora': 'ef_dora', 'santiago': 'em_alex', 'noel': 'em_santa', 'siwis': 'ff_siwis', 'aiko': 'jf_alpha', 'gongitsune': 'jf_gongitsune', 'nezumi': 'jf_nezumi', 'tebukuro': 'jf_tebukuro', 'kumo': 'jm_kumo', 'sara': 'if_sara', 'nicola': 'im_nicola', 'doras': 'pf_dora', 'alex': 'pm_alex', 'antonio': 'pm_santa', 'xiaobei': 'zf_xiaobei', 'xiaoni': 'zf_xiaoni', 'xiaoxiao': 'zf_xiaoxiao', 'xiaoyi': 'zf_xiaoyi', 'yunjian': 'zm_yunjian', 'yunxi': 'zm_yunxi', 'yunxia': 'zm_yunxia', 'yunyang': 'zm_yunyang' }, getVoiceId: function(vn) { const i = vn.toLowerCase().trim(); return this.voiceX[i]; }, generate: async function(text, vn) { if (!text?.trim()) { return { success: false, code: 400, author: 'PuruBoy x Daffa (nbscript)', result: { error: 'Parameter `text` tidak boleh kosong.' }, }; } if (text.length > 300) { return { success: false, code: 413, author: 'PuruBoy x Daffa (nbscript)', result: { error: 'Panjang `text` maksimal 300 karakter.' }, }; } const voiceId = this.getVoiceId(vn); if (!voiceId) { const av = Object.keys(this.voiceX).join(', '); return { success: false, code: 422, author: 'PuruBoy x Daffa (nbscript)', result: { error: `Nama voice "${vn}" tidak valid. Pilih salah satu dari: ${av}` }, }; } const decoder = new TextDecoder(); const ciu = decoder.decode(this.cid); const toket = decoder.decode(this.auth); const body = { customerId: ciu, text: text, voice: voiceId, }; try { const res = await axios.post( `${this.api.base}${this.api.endpoint.generate}`, body, { headers: { ...this.headers, authorization: toket } } ); const { outputUrl } = res.data; return { success: true, code: 200, author: 'PuruBoy x Daffa (nbscript)', result: { audio: outputUrl, voice: voiceId, text_length: text.length, }, }; } catch (err) { return { success: false, code: err.response?.status || 500, author: 'PuruBoy x Daffa (nbscript)', result: { error: err.message || 'Terjadi kesalahan internal.', }, }; } }, }; module.exports = { svara }; --- // FILE: lib/soundcloudSearch.js const axios = require("axios"); const qs = require("querystring"); let cachedID = null; // Step 1: Ambil client_id dengan cara modern async function getClientID() { if (cachedID) return cachedID; const homepage = await axios.get("https://soundcloud.com"); const scriptUrls = [...homepage.data.matchAll(/