const axios = require("axios"); const { v4: uuidv4 } = require("uuid"); function randomHex(length) { const chars = "abcdef0123456789"; return Array.from({ length }, () => chars[Math.floor(Math.random() * chars.length)]).join(""); } function gieneticTrace() { return `${randomHex(32)}-${randomHex(16)}`; } async function login(deviceId) { const res = await axios.post( "https://api.sunora.mavtao.com/api/auth/login", { device_id: deviceId }, { headers: { "user-agent": "Dart/3.4 (gienetic_build)", "version": "2.2.2", "accept-encoding": "gzip", "content-type": "application/json", "buildnumber": "105", "platform": "android", "sentry-trace": gieneticTrace() } } ); return res.data?.data?.token || null; } async function polllll(xAuth, maxAttempts = 30, delayMs = 30000) { for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { const res = await axios.get( "https://api.sunora.mavtao.com/api/music/music_page?page=1&pagesize=50", { headers: { "user-agent": "Dart/3.4 (gienetic_build)", "version": "2.2.2", "accept-encoding": "gzip", "x-auth": xAuth, "buildnumber": "105", "platform": "android", "sentry-trace": gieneticTrace() } } ); const records = res.data?.data?.records || []; const doneSongs = records.filter(r => r.status === "complete"); if (doneSongs.length > 0) { return doneSongs.map(r => ({ id: r.song_id, title: r.title || "Sniff By: Gienetic", tags: r.meta_tags, prompt: r.meta_prompt, audioUrl: r.audio_url, videoUrl: r.video_url, imageUrl: r.image_url, model: r.model_name })); } } catch (err) { console.error("⚠️ Polling error:", err.response?.data || err.message); } await new Promise(r => setTimeout(r, delayMs)); } return []; } async function generateNormal(description) { const deviceId = uuidv4(); const token = await login(deviceId); if (!token) throw new Error("⚠️ Error: gagal login (makanya tag author ny kalau recode :v)"); await axios.post( "https://api.sunora.mavtao.com/api/music/advanced_custom_generate", { continue_at: null, continue_clip_id: null, mv: null, description, title: "", mood: "", music_style: "", instrumental_only: false }, { headers: { "user-agent": "Dart/3.4 (gienetic_build)", "version": "2.2.2", "accept-encoding": "gzip", "x-auth": token, "content-type": "application/json", "buildnumber": "105", "platform": "android", "sentry-trace": gieneticTrace() } } ); return await polllll(token); } async function generateCustom({ title, style, lyrics }) { const deviceId = uuidv4(); const token = await login(deviceId); if (!token) throw new Error("⚠️ Error: gagal login (makanya tag author ny kalau recode :v)"); await axios.post( "https://api.sunora.mavtao.com/api/music/custom_generate", { continue_at: null, continue_clip_id: null, mv: null, prompt: lyrics, title, tags: style }, { headers: { "user-agent": "Dart/3.4 (gienetic_build)", "version": "2.2.2", "accept-encoding": "gzip", "x-auth": token, "content-type": "application/json", "buildnumber": "105", "platform": "android", "sentry-trace": gieneticTrace() } } ); return await polllll(token); } async function generateInstrumental(description) { const deviceId = uuidv4(); const token = await login(deviceId); if (!token) throw new Error("⚠️ Error: gagal login (makanya tag author ny kalau recode :v)"); await axios.post( "https://api.sunora.mavtao.com/api/music/advanced_custom_generate", { continue_at: null, continue_clip_id: null, mv: null, description, title: "", mood: "", music_style: "", instrumental_only: true }, { headers: { "user-agent": "Dart/3.4 (gienetic_build)", "version": "2.2.2", "accept-encoding": "gzip", "x-auth": token, "content-type": "application/json", "buildnumber": "105", "platform": "android", "sentry-trace": gieneticTrace() } } ); return await polllll(token); } const handler = async (req, res) => { try { const { mode, description, title, style, lyrics } = req.query; if (!mode) { return res.status(400).json({ success: false, error: 'Missing required parameter: mode (normal/custom/instrumental)' }); } const modeNormalized = mode.toLowerCase(); if (!['normal', 'custom', 'instrumental'].includes(modeNormalized)) { return res.status(400).json({ success: false, error: 'Invalid mode. Use "normal", "custom", or "instrumental"' }); } let result; if (modeNormalized === 'normal') { if (!description) { return res.status(400).json({ success: false, error: 'Missing required parameter: description (required for normal mode)' }); } result = await generateNormal(description); } else if (modeNormalized === 'custom') { if (!title || !style || !lyrics) { return res.status(400).json({ success: false, error: 'Missing required parameters: title, style, lyrics (required for custom mode)' }); } result = await generateCustom({ title, style, lyrics }); } else if (modeNormalized === 'instrumental') { if (!description) { return res.status(400).json({ success: false, error: 'Missing required parameter: description (required for instrumental mode)' }); } result = await generateInstrumental(description); } if (!result || result.length === 0) { return res.status(500).json({ success: false, error: 'Failed to generate music or timeout' }); } res.json({ author: "Herza", success: true, mode: modeNormalized, result: result }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }; module.exports = { name: 'Suno V3 Music Generator', description: 'Generate music using Suno V3 AI with multiple modes', type: 'GET', routes: ['api/AI/sunov3'], tags: ['ai', 'music', 'suno', 'generator'], main: ['AI'], parameters: ['mode', 'description', 'title', 'style', 'lyrics', 'key'], enabled: true, limit: 15, handler };