UNPKG

almtools

Version:

Tools Downloader For WhatsApp Bot

455 lines (394 loc) 13.2 kB
const axios = require("axios") const FormData = require("form-data"); const cheerio = require("cheerio"); async function getTokenAndCookie() { const res = await axios.get('https://tmate.cc', { headers: { 'User-Agent': 'Mozilla/5.0' } }) const cookie = res.headers['set-cookie']?.map(c => c.split(';')[0]).join('; ') || '' const tokenMatch = res.data.match(/<input[^>]+name="token"[^>]+value="([^"]+)"/i) const token = tokenMatch?.[1] if (!token) throw new Error('token ga ada') return { token, cookie } } async function getBuffer(url) { const res = await axios.get(url, { responseType: 'arraybuffer' }) return Buffer.from(res.data) } async function tiktok(tiktokUrl) { const { token, cookie } = await getTokenAndCookie(); const params = new URLSearchParams(); params.append('url', tiktokUrl); params.append('token', token); const res = await axios.post('https://tmate.cc/action', params.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'Mozilla/5.0', 'Referer': 'https://tmate.cc/id', 'Origin': 'https://tmate.cc', 'Cookie': cookie } }); const html = res.data?.data; if (!html) throw new Error('ga ada data'); const titleMatch = html.match(/<h1[^>]*>(.*?)<\/h1>/i); const title = titleMatch?.[1]?.replace(/<[^>]+>/g, '').trim() || 'Tanpa Judul'; // === STEP 1: Coba ambil gambar dari dlpanda.com === const dlpandaRes = await axios.get(`https://dlpanda.com/id?token=hy5EGGKC&url=${encodeURIComponent(tiktokUrl)}`, { headers: { 'User-Agent': 'Mozilla/5.0' } }); const $ = cheerio.load(dlpandaRes.data); const imageUrls = []; $('.col-md-12.col-lg-6 img').each((i, el) => { const src = $(el).attr('src'); if (src && src.startsWith('http')) { imageUrls.push(src); } }); if (imageUrls.length > 0) { const audioMatch = html.match(/<a[^>]+href="(https:\/\/[^"]+)"[^>]*>\s*<span>\s*<span>Download MP3 Audio<\/span><\/span><\/a>/i); const mp3Link = audioMatch?.[1]; return { status: true, result: { mediatype: 'image', media: imageUrls, title, audio: mp3Link } }; } // === STEP 2: Jika tidak ada gambar, fallback ke video === const matches = [...html.matchAll(/<a[^>]+href="(https:\/\/[^"]+)"[^>]*>\s*<span>\s*<span>([^<]*)<\/span><\/span><\/a>/gi)]; const seen = new Set(); const links = matches .map(([_, href, label]) => ({ href, label: label.trim() })) .filter(({ href }) => !href.includes('play.google.com') && !seen.has(href) && seen.add(href)); const mp4Link = links.find(v => /download without watermark/i.test(v.label))?.href; const mp4HdLink = links.find(v => /download hd/i.test(v.label))?.href || mp4Link; const mp3Link = links.find(v => /download mp3 audio/i.test(v.label))?.href; if (mp4Link) { return { status: true, result: { mediatype: 'video', media: mp4Link, mediaHd: mp4HdLink, title, audio: mp3Link } }; } throw new Error('ga ada respon, mungkin link salah'); } async function instagram(url) { try { if (!url.match(/https?:\/\/(www\.)?(instagram\.com|facebook\.com)/i)) { throw 'URL yang Anda masukkan tidak valid!'; } const { data } = await axios.post( 'https://yt1s.io/api/ajaxSearch', new URLSearchParams({ p: 'home', q: url, w: '', lang: 'en' }), { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', } } ); if (data.status !== 'ok') throw 'Gagal mendapatkan data dari server!'; const $ = cheerio.load(data.data); const downloads = $('a.abutton.is-success.is-fullwidth.btn-premium') .map((_, el) => ({ title: $(el).attr('title'), url: $(el).attr('href'), })) .get(); if (!downloads || downloads.length === 0) { throw 'Tidak dapat menemukan media untuk diunduh!'; } const media = []; for (const dl of downloads) { try { const head = await axios.head(dl.url); const mimeType = head.headers['content-type']; if (dl.title == "Download Thumbnail") continue if (mimeType.includes('image')) { media.push({ mediatype: 'image', url: dl.url }); } else if (mimeType.includes('video')) { media.push({ mediatype: 'video', url: dl.url }); } else { continue; } } catch (err) { console.error('Failed to get content type:', err.message); } } const result = { status: true, media }; if (media.length === 0) { throw 'No valid media found.'; } return result } catch (error) { console.error(error); return { status: false, error: error } } }; async function douyin(url) { try { const { data } = await axios.get( "https://dlpanda.com/id?token=hy5EGGKC&url=" + encodeURIComponent(url) ); const $ = cheerio.load(data); const imageUrls = []; $('.single-popular-domain .card-body img').each((_, el) => { const src = $(el).attr('src'); if (src) imageUrls.push(src); }); const video = $('video source').attr('src'); if (imageUrls.length > 0) { return { status: true, result: { mediatype: "image", media: imageUrls } }; } else { return { status: true, result: { mediatype: "video", media: video?.startsWith("//") ? "https:" + video : video } }; } } catch (error) { return { status: false, error }; } } const fb = { tokens: async () => { const { data: a } = await axios.get("https://fbdown.me/"); const $ = cheerio.load(a); return $('#token') .val(); }, dl: async (urls) => { const tokens = await fb.tokens(); const d = new FormData(); d.append("url", urls); d.append("token", tokens); const headers = { headers: { ...d.getHeaders() } }; const { data: s } = await axios.post( "https://fbdown.me/wp-json/aio-dl/video-data", d, headers); return { status: true, result: s } } }; class SpotMate { constructor() { this._cookie = null; this._token = null; } async _visit() { try { const response = await axios.get('https://spotmate.online/en', { headers: { 'user-agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36', }, }); const setCookieHeader = response.headers['set-cookie']; if (setCookieHeader) { this._cookie = setCookieHeader .map((cookie) => cookie.split(';')[0]) .join('; '); } const $ = cheerio.load(response.data); this._token = $('meta[name="csrf-token"]').attr('content'); if (!this._token) { throw new Error('Token CSRF tidak ditemukan.'); } console.log('Berhasil mendapatkan cookie dan token.'); } catch (error) { throw new Error(`Gagal mengunjungi halaman: ${error.message}`); } } async info(spotifyUrl) { if (!this._cookie || !this._token) { await this._visit(); } try { const response = await axios.post( 'https://spotmate.online/getTrackData', { spotify_url: spotifyUrl }, { headers: this._getHeaders(), } ); return response.data; } catch (error) { throw new Error(`Gagal mendapatkan info track: ${error.message}`); } } async convert(spotifyUrl) { if (!this._cookie || !this._token) { await this._visit(); } try { const response = await axios.post( 'https://spotmate.online/convert', { urls: spotifyUrl }, { headers: this._getHeaders(), } ); return response.data; } catch (error) { throw new Error(`Gagal mengonversi track: ${error.message}`); } } clear() { this._cookie = null; this._token = null; console.log('Cookie dan token telah dihapus.'); } _getHeaders() { return { 'authority': 'spotmate.online', 'accept': '*/*', 'accept-language': 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7', 'content-type': 'application/json', 'cookie': this._cookie, 'origin': 'https://spotmate.online', 'referer': 'https://spotmate.online/en', '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', 'user-agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36', 'x-csrf-token': this._token, }; } } async function contol(url) { try { let spotMate = new SpotMate(); let info = await spotMate.info(url); let track = await spotMate.convert(url); if (track.error) throw "Error While Downloading Audio"; let artists = [] let artist = info?.artists.forEach((i) => artists.push(i.name)) || null; let data = { title: info?.name || null, album: info?.album.name || null, thumbnail: info?.album.images || null, artists: artists.filter(_ => _), duration: info.duration_ms || null, url: track.url } return { status: true, result: data } } catch (e) { throw e } } async function snack(url) { const res = await fetch(url); const body = await res.text(); const $ = cheerio.load(body); const video = $("div.video-box").find("a-video-player"); const author = $("div.author-info"); const attr = $("div.action"); const data = { title: $(author).find("div.author-desc > span").children("span").eq(0).text().trim(), thumbnail: $(video).parent().siblings("div.background-mask").children("img").attr("src"), media: $(video).attr("src"), author: $("div.author-name").text().trim(), authorImage: $(attr).find("div.avatar > img").attr("src"), like: $(attr).find("div.common").eq(0).text().trim(), comment: $(attr).find("div.common").eq(1).text().trim(), share: $(attr).find("div.common").eq(2).text().trim(), }; return { status: true, result: data } } async function twitter(link) { try { const apiUrl = "https://www.twitterdown.com/api/parse"; const headers = { "Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, seperti Gecko) Chrome/134.0.0.0 Mobile Safari/537.36", "Referer": `https://www.twitterdown.com/${link.split("/").slice(-2).join("/")}`, }; const postData = { url: link }; const response = await axios.post(apiUrl, postData, { headers }); if (!response.data || !response.data.resolutions) { throw new Error("Gagal mengambil data dari TwitterDown."); } const thumbnail = response.data.thumbnail || null; const text = response.data.text || null; const username = response.data.username || null; const statusId = response.data.statusId || null; const downloadLinks = response.data.resolutions.reduce((acc, media) => { acc[media.resolution] = media.url; return acc; }, {}); let sta = { username, statusId, title: text, thumbnail, url: downloadLinks, } return { status: true, result: sta } } catch (error) { throw error } } async function capcut(url) { if (!url) throw new Error('URL cannot be empty'); const response = await axios.get(url); const data = response.data; const $ = cheerio.load(data); return { url: $("video").attr("src") || null, description: $('meta[name="keywords"]').attr("content") || null }; } module.exports = { facebook: fb.dl, instagram, tiktok, douyin, spotify: contol, snackvideo: snack, twitter, capcut }