| const axios = require('axios'); | |
| class YesChatMusicGenerator { | |
| constructor() { | |
| this.userAgent = "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36"; | |
| } | |
| async getBypassToken() { | |
| try { | |
| const response = await axios.get('https://anabot.my.id/api/tools/bypass', { | |
| params: { | |
| url: 'https://www.yeschat.ai/', | |
| siteKey: '0x4AAAAAAATOXAtQtziH-Rwq', | |
| type: 'turnstile-min', | |
| apikey: 'freeApikey' | |
| }, | |
| headers: { | |
| 'accept': '*/*' | |
| } | |
| }); | |
| if (response.data.success && response.data.data?.result?.token) { | |
| return response.data.data.result.token; | |
| } | |
| throw new Error('Failed to get token from response'); | |
| } catch (error) { | |
| throw new Error(`Failed to get bypass token: ${error.message}`); | |
| } | |
| } | |
| async generateSongLyrics({ | |
| prompt, | |
| title = "Tanpa Judul", | |
| style = "Happy", | |
| instrumental = false, | |
| customMode = true, | |
| }) { | |
| const token = await this.getBypassToken(); | |
| if (!token || typeof token !== "string") { | |
| throw new Error("Failed to get bypass token."); | |
| } | |
| const res = await axios.post( | |
| "https://aiarticle.erweima.ai/api/v1/secondary-page/api/create", | |
| { | |
| prompt, | |
| channel: "MUSIC", | |
| id: 1018, | |
| type: "features", | |
| source: "yeschat.ai", | |
| style, | |
| title, | |
| customMode, | |
| instrumental, | |
| }, | |
| { | |
| headers: { | |
| authority: "aiarticle.erweima.ai", | |
| accept: "application/json, text/plain, */*", | |
| "accept-language": "ms-MY,ms;q=0.9,en-US;q=0.8,en;q=0.7,id;q=0.6", | |
| origin: "https://www.yeschat.ai", | |
| referer: "https://www.yeschat.ai/", | |
| "sec-ch-ua": '"Not A(Brand";v="8", "Chromium";v="132"', | |
| "sec-ch-ua-mobile": "?1", | |
| "sec-ch-ua-platform": '"Android"', | |
| "sec-fetch-dest": "empty", | |
| "sec-fetch-mode": "cors", | |
| "sec-fetch-site": "cross-site", | |
| "user-agent": this.userAgent, | |
| uniqueid: Date.now(), | |
| verify: token, | |
| }, | |
| } | |
| ); | |
| if (res.data.code !== 200) { | |
| throw new Error(res.data.msg || "Failed to generate lyrics"); | |
| } | |
| const recordId = res.data?.data?.recordId; | |
| return this.pollGeneratedResult(recordId); | |
| } | |
| pollGeneratedResult(recordId, interval = 5000) { | |
| return new Promise((resolve, reject) => { | |
| const url = `https://aiarticle.erweima.ai/api/v1/secondary-page/api/${recordId}`; | |
| const timer = setInterval(async () => { | |
| try { | |
| const { data } = await axios.get(url, { | |
| headers: { | |
| authority: "aiarticle.erweima.ai", | |
| accept: "application/json, text/plain, */*", | |
| "accept-language": "ms-MY,ms;q=0.9,en-US;q=0.8,en;q=0.7,id;q=0.6", | |
| origin: "https://www.yeschat.ai", | |
| referer: "https://www.yeschat.ai/", | |
| "sec-ch-ua": '"Not A(Brand";v="8", "Chromium";v="132"', | |
| "sec-ch-ua-mobile": "?1", | |
| "sec-ch-ua-platform": '"Android"', | |
| "sec-fetch-dest": "empty", | |
| "sec-fetch-mode": "cors", | |
| "sec-fetch-site": "cross-site", | |
| "user-agent": this.userAgent, | |
| }, | |
| }); | |
| if (data.code !== 200) { | |
| clearInterval(timer); | |
| return reject(new Error(data.msg || "Unexpected error")); | |
| } | |
| if (data.data?.failCode && data.data?.failMsg) { | |
| clearInterval(timer); | |
| return reject(new Error(data.data.failMsg)); | |
| } | |
| if (data.data?.state && data.data.completeData) { | |
| clearInterval(timer); | |
| return resolve(JSON.parse(data.data.completeData)); | |
| } | |
| } catch (err) { | |
| clearInterval(timer); | |
| return reject(err); | |
| } | |
| }, interval); | |
| }); | |
| } | |
| } | |
| const handler = async (req, res) => { | |
| try { | |
| const { mode, prompt, lyrics, title, style, instrumental } = req.query; | |
| if (!mode) { | |
| return res.status(400).json({ | |
| success: false, | |
| error: 'Missing required parameter: mode (custom/ai)' | |
| }); | |
| } | |
| const modeNormalized = mode.toLowerCase(); | |
| if (modeNormalized !== 'custom' && modeNormalized !== 'ai') { | |
| return res.status(400).json({ | |
| success: false, | |
| error: 'Invalid mode. Use "custom" for Custom Lyrics or "ai" for AI Lyrics' | |
| }); | |
| } | |
| let finalPrompt; | |
| let customMode; | |
| if (modeNormalized === 'custom') { | |
| if (!lyrics) { | |
| return res.status(400).json({ | |
| success: false, | |
| error: 'Missing required parameter: lyrics (required for Custom Lyrics mode)' | |
| }); | |
| } | |
| finalPrompt = lyrics; | |
| customMode = true; | |
| } else { | |
| if (!prompt) { | |
| return res.status(400).json({ | |
| success: false, | |
| error: 'Missing required parameter: prompt (required for AI Lyrics mode)' | |
| }); | |
| } | |
| finalPrompt = prompt; | |
| customMode = false; | |
| } | |
| const generator = new YesChatMusicGenerator(); | |
| const result = await generator.generateSongLyrics({ | |
| prompt: finalPrompt, | |
| title: title || "Tanpa Judul", | |
| style: style || "Happy", | |
| instrumental: instrumental === 'true', | |
| customMode: customMode | |
| }); | |
| res.json({ | |
| author: "Herza", | |
| success: true, | |
| mode: modeNormalized === 'custom' ? 'Custom Lyrics' : 'AI Lyrics', | |
| result: result | |
| }); | |
| } catch (error) { | |
| res.status(500).json({ | |
| success: false, | |
| error: error.message | |
| }); | |
| } | |
| }; | |
| module.exports = { | |
| name: 'SunoV2 Music Generator', | |
| type: 'GET', | |
| routes: ['api/AI/sunov2'], | |
| tags: ['ai', 'music', 'generator'], | |
| main: ['AI'], | |
| limit: 12, | |
| parameters: ['mode', 'prompt', 'lyrics', 'title', 'style', 'instrumental', 'key'], | |
| enabled: true, | |
| handler | |
| }; |