const express = require("express"); const axios = require("axios"); const path = require("path"); const cheerio = require('cheerio'); const FormData = require('form-data'); const app = express(); app.set('json spaces', 4); const PORT = 7860; async function yt5sIo(url) { try { const form = new URLSearchParams(); form.append("q", url); form.append("vt", "home"); const response = await axios.post('https://yt5s.io/api/ajaxSearch', form, { headers: { "Accept": "application/json", "X-Requested-With": "XMLHttpRequest", "Content-Type": "application/x-www-form-urlencoded", }, }); if (response.data.status === "ok") { const $ = cheerio.load(response.data.data); if (/^(https?:\/\/)?(www\.)?(facebook\.com|fb\.watch)\/.+/i.test(url)) { const videoQualities = []; $('table tbody tr').each((index, element) => { const quality = $(element).find('.video-quality').text().trim(); const downloadLink = $(element).find('a.download-link-fb').attr("href"); if (quality && downloadLink) { videoQualities.push({ quality, downloadLink }); } }); // Prioritize HD quality, fallback to SD const hdVideo = videoQualities.find(v => v.quality.toLowerCase().includes('hd')); const sdVideo = videoQualities.find(v => v.quality.toLowerCase().includes('sd')); const videoUrl = hdVideo ? hdVideo.downloadLink : sdVideo ? sdVideo.downloadLink : null; if (!videoUrl) throw new Error("Tidak ada link download yang tersedia."); return { videoUrl }; } else { throw new Error("URL tidak valid. Harap masukkan URL Facebook atau Instagram."); } } else { throw new Error("Gagal mengambil video: " + response.data.message); } } catch (error) { throw error; } } const ytdl = async(url) => { const { data } = await axios.post('https://www.clipto.com/api/youtube', { url }, { headers: { 'accept': 'application/json, text/plain, */*', 'content-type': 'application/json', 'origin': 'https://www.clipto.com', 'referer': 'https://www.clipto.com/id/media-downloader/youtube-downloader', 'user-agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36' } } ); return data?.medias } const ttdl = async(url) => { const { data } = await axios.get('https://www.tikwm.com/api/?url=' + url + '&hd=1') return { play: data.data.play, hd: data.data.hdplay } } const snapinst = { async app(url) { const { data } = await axios.get('https://snapinst.app/'); const $ = cheerio.load(data); const form = new FormData(); form.append('url', url); form.append('action', 'post'); form.append('lang', ''); form.append('cf-turnstile-response', ''); form.append('token', $('input[name=token]').attr('value')); const headers = { ...form.getHeaders(), 'accept': '*/*', 'accept-language': 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7', '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': 'same-origin', 'Referer': 'https://snapinst.app/', 'Referrer-Policy': 'strict-origin-when-cross-origin' }; const jsbejad = await axios.post('https://snapinst.app/action2.php', form, { headers }); const ayok = new Function('callbuk', jsbejad.data.replace('eval', 'callbuk')); const html = await new Promise((resolve, reject) => { ayok(t=>{ const code = t.split(".innerHTML = ")[1].split("; document.")[0]; resolve(eval(code)); }); }); const _ = cheerio.load(html); const res = []; _('.row .download-item').each((i, e)=>{ res.push(_(e).find('.download-bottom a').attr('href')); }); return res }, }; const twitter = { extract: (url) => { const regex = /https?:\/\/?(?:mobile\.)?(?:www\.)?(?:twitter\.com|x\.com)\/(?:\w+\/status\/)?(\d+)/; if(!regex.test(url)) return "Invalid url"; const match = url.match(regex); return match ? match[1] : null; }, video: async(url) => { const id = twitter.extract(url) const res = (await axios.get(`https://tweeload.com/download/${id}`)).data const $ = cheerio.load(res); const section = $('section.content__section.download_result_section'); const link = section.find('a.btn').attr('href'); const name = section.find('.download__item__profile_pic span').first().text(); const username = section.find('.download__item__profile_pic span').last().text(); return { link } }, } app.all("/", async (req, res) => { const { url } = req.query || req.body; if(/^(https?:\/\/)?(www\.)?instagram\.com\/(p|reel)\/.+/i.test(url)) res.json(await snapinst.app(url)) // instagram if(/^(https?:\/\/)?(www\.)?(facebook\.com|fb\.watch)\/.+/i.test(url)) res.json(await yt5sIo(url)) // fesnuk if(/(?:https?:)?(?:\/\/)?(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\S*?[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/gim.test(url)) res.json(await ytdl(url)) // yt if(/https?:\/\/(?:www|m|vt)\.tiktok\.com\//gi.test(url)) res.json(await ttdl(url)) // tiktok if(/(?:https?:\/\/)?(?:mobile\.)?(?:www\.)?(?:twitter|x)\.com\/(?:@?(\w{1,15})\/)?status\/\d{10,20}/gim.test(url)) res.json(await twitter.video(url)) // twitter vid res.json({ service: ["facebook", "instagram", "youtube", "tiktok", "twitter"] }); }); app.listen(PORT, () => console.log(`Server berjalan di http://localhost:${PORT}`));