const axios = require('axios'); const crypto = require('crypto'); const HttpProxyAgent = require('http-proxy-agent'); const HttpsProxyAgent = require('https-proxy-agent'); async function getRandomProxy() { try { const response = await axios.get('https://raw.githubusercontent.com/proxifly/free-proxy-list/refs/heads/main/proxies/protocols/https/data.json'); const proxies = response.data; if (proxies.length === 0) return null; return proxies[Math.floor(Math.random() * proxies.length)].proxy; } catch (err) { return null; } } const aiMu = { api: { base: 'https://aimu.1010diy.com', endpoint: { credits: '/and/getUserActualCredits', musicAI: '/music/MusicAI', taskStatus: '/music/getTaskStatus', generateList: '/and/data/generateList', options: '/and/home/index', }, }, headers: { 'user-agent': 'NB Android/1.0.0', 'accept-encoding': 'gzip', 'x-version-code': '27', 'x-token': '', }, sid: null, setDeviceId: (id) => { aiMu.sid = id; }, getDeviceId: () => { if (!aiMu.sid) { aiMu.sid = crypto.randomBytes(8).toString('hex'); } return aiMu.sid; }, opts: async () => { try { const proxyUrl = await getRandomProxy(); const axiosConfig = { headers: { ...aiMu.headers, 'x-device-id': aiMu.getDeviceId() } }; if (proxyUrl) { axiosConfig.httpAgent = new HttpProxyAgent(proxyUrl); axiosConfig.httpsAgent = new HttpsProxyAgent(proxyUrl); } const res = await axios.get( `${aiMu.api.base}${aiMu.api.endpoint.options}`, axiosConfig ); const { code, msg, data } = res.data; if (code !== 200) { return { success: false, code, author: 'Daffa ~', team: 'NB Team', result: { error: { msg } } }; } const moods = [...(data.mood?.default || []), ...(data.mood?.more || [])].map(m => m.text); const genres = [...(data.genre?.default || []), ...(data.genre?.more || [])].map(g => g.text); const voices = ['female', 'male', 'random']; return { success: true, code: 200, author: 'Daffa ~', team: 'NB Team', result: { moods, genres, voices } }; } catch (err) { return { success: false, code: err.response?.status || 500, author: 'Daffa ~', team: 'NB Team', result: { error: err.message } }; } }, getCredits: async () => { try { const proxyUrl = await getRandomProxy(); const axiosConfig = { headers: { ...aiMu.headers, 'x-device-id': aiMu.getDeviceId() } }; if (proxyUrl) { axiosConfig.httpAgent = new HttpProxyAgent(proxyUrl); axiosConfig.httpsAgent = new HttpsProxyAgent(proxyUrl); } const res = await axios.get( `${aiMu.api.base}${aiMu.api.endpoint.credits}`, axiosConfig ); const { code, msg, data } = res.data; if (code === 200) { return { success: true, code: 200, author: 'Daffa ~', team: 'NB Team', result: { ...data } }; } return { success: false, code, author: 'Daffa ~', team: 'NB Team', result: { error: msg } }; } catch (err) { return { success: false, code: err.response?.status || 500, author: 'Daffa ~', team: 'NB Team', result: { error: err.message } }; } }, generate: async (params) => { let make_instrumental = params.make_instrumental ? 1 : 0; let vocal_only = params.vocal_only ? 1 : 0; if (make_instrumental === 1) vocal_only = 0; const { lyrics = '', prompt = '' } = params; if (!lyrics.trim() && !prompt.trim()) { return { success: false, code: 400, author: 'Daffa ~', team: 'NB Team', result: { error: 'Lu bisa pilih Lyric atau Prompt bree' } }; } if (prompt && prompt.length > 1000) { return { success: false, code: 400, author: 'Daffa ~', team: 'NB Team', result: { error: 'Promptnya kepanjangan yak, max 1k karakter aja.. ' } }; } const payload = { make_instrumental, vocal_only, lyrics, prompt, ...params }; try { const proxyUrl = await getRandomProxy(); const axiosConfig = { headers: { ...aiMu.headers, 'content-type': 'application/json', 'x-device-id': aiMu.getDeviceId(), }, }; if (proxyUrl) { axiosConfig.httpAgent = new HttpProxyAgent(proxyUrl); axiosConfig.httpsAgent = new HttpsProxyAgent(proxyUrl); } const res = await axios.post( `${aiMu.api.base}${aiMu.api.endpoint.musicAI}`, payload, axiosConfig ); const { code, msg, data } = res.data; if (code === 200) { return { success: true, code: 200, author: 'Daffa ~', team: 'NB Team', result: { taskId: data?.task_id, inputType: prompt ? 'prompt' : 'lyrics', inputValue: prompt || lyrics } }; } return { success: false, code, author: 'Daffa ~', team: 'NB Team', result: { error: msg } }; } catch (err) { return { success: false, code: err.response?.status || 500, author: 'Daffa ~', team: 'NB Team', result: { error: err.message } }; } }, polling: async (taskId) => { if (!String(taskId)?.trim()) { return { success: false, code: 400, author: 'Daffa ~', team: 'NB Team', result: { error: 'Task IDnya kagak boleh kosong bree... ' } }; } try { const proxyUrl = await getRandomProxy(); const axiosConfig = { params: { task_id: taskId }, headers: { ...aiMu.headers, 'x-device-id': aiMu.getDeviceId() }, }; if (proxyUrl) { axiosConfig.httpAgent = new HttpProxyAgent(proxyUrl); axiosConfig.httpsAgent = new HttpsProxyAgent(proxyUrl); } const res = await axios.get( `${aiMu.api.base}${aiMu.api.endpoint.taskStatus}`, axiosConfig ); const { code, msg, data } = res.data; if (code === 200) { return { success: true, code: 200, author: 'Daffa ~', team: 'NB Team', result: { status: data?.status, } }; } return { success: false, code, author: 'Daffa ~', team: 'NB Team', result: { error: msg } }; } catch (err) { return { success: false, code: err.response?.status || 500, author: 'Daffa ~', team: 'NB Team', result: { error: err.message } }; } }, getGenerateList: async () => { try { const proxyUrl = await getRandomProxy(); const axiosConfig = { headers: { ...aiMu.headers, 'x-device-id': aiMu.getDeviceId() } }; if (proxyUrl) { axiosConfig.httpAgent = new HttpProxyAgent(proxyUrl); axiosConfig.httpsAgent = new HttpsProxyAgent(proxyUrl); } const res = await axios.get( `${aiMu.api.base}${aiMu.api.endpoint.generateList}`, axiosConfig ); const { code, msg, data } = res.data; if (code === 200) { const results = (data || []).map((item) => ({ taskId: item.task_id, title: item.title, duration: item.duration, mp3: item.conversion_path, cover: item.album_cover_path, input: item.lyrics, created_at: item.created_at, updated_at: item.updated_at, })); return { success: true, code: 200, author: 'Daffa ~', team: 'NB Team', result: { results } }; } return { success: false, code, author: 'Daffa ~', team: 'NB Team', result: { error: msg } }; } catch (err) { return { success: false, code: err.response?.status || 500, author: 'Daffa ~', team: 'NB Team', result: { error: err.message } }; } }, task: async (taskId, inputType, inputValue, intervalMs = 5000) => { if (!String(taskId)?.trim()) { return { success: false, code: 400, author: 'Daffa ~', team: 'NB Team', result: { error: 'Task IDnya kagak boleh kosong bree... ' } }; } while (true) { const resx = await aiMu.polling(taskId); if (!resx.success) return resx; if (resx.result.status === 'complete') { const re = await aiMu.getGenerateList(); if (!re.success) return re; const tracks = re.result.results.filter((r) => String(r.taskId) === String(taskId)); const avr = tracks.every((t) => t.mp3.includes('vocal-remover.s3.us-west-2.amazonaws.com')); if (tracks.length > 0 && avr) { return { success: true, code: 200, author: 'Daffa ~', team: 'NB Team', result: { taskId: String(taskId), count: tracks.length, tracks: tracks.map((t) => ({ title: t.title, duration: t.duration, audio: t.mp3, cover: t.cover, [inputType]: t.input, created_at: t.created_at, updated_at: t.updated_at, })), inputValue } }; } } await new Promise((r) => setTimeout(r, intervalMs)); } }, }; const handler = async (req, res) => { try { const { prompt, lyrics, mood, genre, voice, key } = req.query; if (!prompt && !lyrics) { return res.status(400).json({ success: false, error: 'Missing required parameter: prompt or lyrics' }); } const params = { prompt: prompt || '', lyrics: lyrics || '', mood: mood || '', genre: genre || '', voice: voice || 'random', make_instrumental: 0, vocal_only: 0 }; const genResult = await aiMu.generate(params); if (!genResult.success) { return res.status(400).json(genResult); } const taskId = genResult.result.taskId; const inputType = genResult.result.inputType; const inputValue = genResult.result.inputValue; const taskResult = await aiMu.task(taskId, inputType, inputValue); res.json(taskResult); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }; module.exports = { name: 'Sunov4 Music Generator', description: 'Generate music using AiMu AI model', type: 'GET', routes: ['api/AI/suno4'], tags: ['ai', 'music', 'aimu', 'suno'], main: ['AI'], parameters: ['prompt', 'lyrics', 'mood', 'genre', 'voice', 'key'], enabled: true, limit: 18, handler };