const { fileTypeFromBuffer } = require("file-type"); const twit = require("../lib/twt") const { ttt } = require("../lib/skrep"); const { soundcloud } = require("../lib/soundcloud"); const ig = require("../lib/ig"); const { spotifyTrack, spotifyPlaylist } = require("../lib/spotify"); const yt = require("../lib/ytdl"); const kwaii = require("../lib/kuaishou"); const qq = require("../lib/qqm"); const fesnuk = require("../lib/fb"); const IGr = /^(https?:\/\/)?(www\.)?instagram\.com\/.*$/i; const SCr = /^(https?:\/\/)?(www\.|m\.)?(on\.|)soundcloud\.com\/[^\s]+$/i; const TTr = /https?:\/\/(www\.|v(t|m)\.|t\.)?tiktok\.com/i; const Sr = /https?:\/\/open\.spotify\.com\/track\/([a-zA-Z0-9]+)(\?.*)?/i; const Ser = /https?:\/\/open\.spotify\.com\/playlist\/([a-zA-Z0-9]+)(\?.*)?/i; const YTr = /(?:http(?:s|):\/\/|)(?:(?:www\.|)?(?:music\.)?youtube(?:-nocookie|)\.com\/(?:shorts\/)?(?:watch\?.*(?:|&)v=|embed\/|v\/)?|youtu\.be\/)([-_0-9A-Za-z]{11})/i; const Kr = /^https?:\/\/v\.kuaishou\.com\/[a-zA-Z0-9]+$/i; const QQMr = /^https:\/\/c6\.y\.qq\.com\/base\/fcgi-bin\/u\?__=[a-zA-Z0-9]+$/; const TwTr = /^https?:\/\/(www\.)?(twitter|x)\.com\/[^\/]+\/status\/\d+\/?$/i; // Daftar domain yang diperbolehkan untuk Facebook const allowX = [ "x.com", "www.x.com", "twitter.com", "www.twitter.com" ] const allowedFacebookHosts = [ "facebook.com", "www.facebook.com", "m.facebook.com", "fb.com" ]; /** * @param {string} response * @returns {Promise<{ success: boolean, challenge_ts: string, hostname: string, score: number, action: string, "error-codes": ("missing-input-secret"|"invalid-input-secret"|"missing-input-response"|"invalid-input-response"|"bad-request"|"timeout-or-duplicate")[] }>} */ async function checkCaptcha(response) { const url = new URL("https://www.google.com/recaptcha/api/siteverify"); url.searchParams.set("secret", "6Ldr6_cqAAAAAApmQtOImEUOVLq8cAIFUZuuRSrM"); url.searchParams.set("response", response); const res = await fetch(url, { method: "POST" }); return await res.json(); } /** @type {Map} */ const yt_info = new Map(); module.exports = async function(req, res) { const { url } = req.body; //const ip = req._ip; if(!url) { return res.status(400).json({ error: "URL diperlukan." }); } let parsedUrl; try { parsedUrl = new URL(url); } catch (error) { return res.status(400).json({ error: "URL tidak valid." }); } /*const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith("Bearer ")) { return res.status(401).json({ message: "Unauthorized: Token is missing or invalid" }); } const token = authHeader.split(" ")[1]; const { success: isValid, "error-codes": errors } = await checkCaptcha(token); if (!isValid) { return res.status(400).send({ message: "Invalid captcha", errors }); }*/ console.log(parsedUrl); let ress; try { if(IGr.test(url)) { ress = await ig(url); ress.type = "instagram"; } else if(SCr.test(url)) { ress = await soundcloud(url); ress.type = "soundcloud"; } else if(Ser.test(url)) { ress = await spotifyPlaylist(url); ress.type = "spotifyPlaylist"; } else if(TTr.test(url)) { ress = await ttt(url); ress.type = "tiktok"; } else if(Sr.test(url)) { ress = await spotifyTrack(url); ress.type = "spotify"; } else if(QQMr.test(url)) { ress = await qq(url); ress.type = "qq"; } else if(allowedFacebookHosts.includes(parsedUrl.hostname)) { ress = await fesnuk(url); ress.type = "facebook" } else if(allowX.includes(parsedUrl.hostname)) { ress = await twit(url); ress.type = "twitter" } else if(YTr.test(url)) { const format = String( req.headers["x-selected-format"] || "" ).trim(); const [, id] = YTr.exec(url); if(!format) { ress = ( yt_info.has(id) ? yt_info.get(id) : await yt.getInfo(url) ); yt_info.set(id, ress); ress.type = "yt_info"; } else { const type = ( format === "audio" ? "Audio" : "Video" ); ress = await yt[`get${type}`](url, format); } } else if(Kr.test(url)) { ress = await kwaii(url); ress.type = "kwaii"; } else { ress = { status: 400, message: "failed request" }; } } catch (e) { console.log(e); ress = { status: 404, message: e.message }; } if(Buffer.isBuffer(ress)) { const { mime } = await fileTypeFromBuffer(ress); res.setHeader("Content-Type", mime); res.setHeader("Content-Length", ress.length); } return res.status(ress.status || 200).send(ress.data || ress); };