UNPKG

notmebotz-tools

Version:

Sebuah Tools yang berfungsi untuk mendownload Video atau Foto dari media sosial, serta sebagai tools yang berguna untuk aplikasi kamu seperti untuk BOT

625 lines (548 loc) 16.8 kB
const axios = require('axios'); const crypto = require('crypto'); const fetch = require('node-fetch'); const ogmp3 = { api: { base: "https://api3.apiapi.lat", endpoints: { a: "https://api5.apiapi.lat", b: "https://api.apiapi.lat", c: "https://api3.apiapi.lat" } }, headers: { 'authority': 'api.apiapi.lat', 'content-type': 'application/json', 'origin': 'https://ogmp3.lat', 'referer': 'https://ogmp3.lat/', 'user-agent': 'Postify/1.0.0' }, formats: { video: ['240', '360', '480', '720', '1080'], audio: ['64', '96', '128', '192', '256', '320'] }, default_fmt: { video: '720', audio: '320' }, restrictedTimezones: new Set(["-330", "-420", "-480", "-540"]), utils: { hash: () => { const array = new Uint8Array(16); crypto.getRandomValues(array); return Array.from(array, byte => byte.toString(16).padStart(2, "0")).join(""); }, encoded: (str) => { let result = ""; for (let i = 0; i < str.length; i++) { result += String.fromCharCode(str.charCodeAt(i) ^ 1); } return result; }, enc_url: (url, separator = ",") => { const codes = []; for (let i = 0; i < url.length; i++) { codes.push(url.charCodeAt(i)); } return codes.join(separator).split(separator).reverse().join(separator); } }, isUrl: str => { try { const url = new URL(str); const hostname = url.hostname.toLowerCase(); const b = [/^(.+\.)?youtube\.com$/, /^(.+\.)?youtube-nocookie\.com$/, /^youtu\.be$/]; return b.some(a => a.test(hostname)) && !url.searchParams.has("playlist"); } catch (_) { return false; } }, youtube: url => { if (!url) return null; const b = [ /youtube\.com\/watch\?v=([a-zA-Z0-9_-]{11})/, /youtube\.com\/embed\/([a-zA-Z0-9_-]{11})/, /youtube\.com\/v\/([a-zA-Z0-9_-]{11})/, /youtube\.com\/shorts\/([a-zA-Z0-9_-]{11})/, /youtu\.be\/([a-zA-Z0-9_-]{11})/ ]; for (let a of b) { if (a.test(url)) return url.match(a)[1]; } return null; }, request: async (endpoint, data = {}, method = 'post') => { try { const ae = Object.values(ogmp3.api.endpoints); const be = ae[Math.floor(Math.random() * ae.length)]; const fe = endpoint.startsWith('http') ? endpoint : `${be}${endpoint}`; const { data: response } = await axios({ method, url: fe, data: method === 'post' ? data : undefined, headers: ogmp3.headers }); return { status: true, code: 200, data: response }; } catch (error) { return { status: false, code: error.response?.status || 500, error: error.message }; } }, async checkStatus(id) { try { const c = this.utils.hash(); const d = this.utils.hash(); const endpoint = `/${c}/status/${this.utils.encoded(id)}/${d}/`; const response = await this.request(endpoint, { data: id }); return response; } catch (error) { return { status: false, code: 500, error: error.message }; } }, async checkProgress(data) { try { let attempts = 0; let maxAttempts = 300; while (attempts < maxAttempts) { attempts++; const res = await this.checkStatus(data.i); if (!res.status) { await new Promise(resolve => setTimeout(resolve, 2000)); continue; } const stat = res.data; if (stat.s === "C") { return stat; } if (stat.s === "P") { await new Promise(resolve => setTimeout(resolve, 2000)); continue; } return null; } return null; } catch (error) { return null; } }, download: async (link, format, type = 'video') => { if (!link) { return { status: false, code: 400, error: "Niat mau download apa kagak? Input link nya manaaaaaa 🗿" }; } if (!ogmp3.isUrl(link)) { return { status: false, code: 400, error: "Link yang lu masukin kagak valid bree.. Yang bener aje luuu 🗿" }; } if (type !== 'video' && type !== 'audio') { return { status: false, code: 400, error: "Tipenya cuman ada 2 bree, 'video' ama 'audio'\nJadi pilih salah satunya yak.. " }; } if (!format) { format = type === 'audio' ? ogmp3.default_fmt.audio : ogmp3.default_fmt.video; } const valid_fmt = type === 'audio' ? ogmp3.formats.audio : ogmp3.formats.video; if (!valid_fmt.includes(format)) { return { status: false, code: 400, error: `Format ${format} tuh kagak valid bree kalo buat ${type} mah, tapi lu bisa pilih dah nih salah satunyaa yak: ${valid_fmt.join(', ')}` }; } const id = ogmp3.youtube(link); if (!id) { return { status: false, code: 400, error: "IDnya mana dah? kagak bisa diekstrak bree..." }; } try { let retries = 0; const maxRetries = 20; while (retries < maxRetries) { retries++; const c = ogmp3.utils.hash(); const d = ogmp3.utils.hash(); const req = { data: ogmp3.utils.encoded(link), format: type === 'audio' ? "0" : "1", referer: "https://ogmp3.cc", mp3Quality: type === 'audio' ? format : null, mp4Quality: type === 'video' ? format : null, userTimeZone: new Date().getTimezoneOffset().toString() }; const resx = await ogmp3.request( `/${c}/init/${ogmp3.utils.enc_url(link)}/${d}/`, req ); if (!resx.status) { if (retries === maxRetries) return resx; continue; } const data = resx.data; if (data.le) { return { status: false, code: 400, error: "Durasi videonya kepanjangan bree, maksimalnya 3 jam yak.. gak boleh lebih, paham kagak? 👍🏻" }; } if (data.i === "blacklisted") { const limit = ogmp3.restrictedTimezones.has(new Date().getTimezoneOffset().toString()) ? 5 : 100; return { status: false, code: 429, error: `Limit Download harian (${limit}) udah habis bree, coba lagi nanti aja yak..` }; } if (data.e || data.i === "invalid") { return { status: false, code: 400, error: "Videonya kagak ada bree, entah karena dihapus atau kena batasan dari youtubenya... idk 🤷🏻" }; } if (data.s === "C") { return { status: true, code: 200, result: { title: data.t || "Kagak tau", type: type, format: format, thumbnail: `https://i.ytimg.com/vi/${id}/maxresdefault.jpg`, download: `${ogmp3.api.base}/${ogmp3.utils.hash()}/download/${ogmp3.utils.encoded(data.i)}/${ogmp3.utils.hash()}/`, id: id, quality: format } }; } const prod = await ogmp3.checkProgress(data); if (prod && prod.s === "C") { return { status: true, code: 200, result: { title: prod.t || "Kagak tau", type: type, format: format, thumbnail: `https://i.ytimg.com/vi/${id}/maxresdefault.jpg`, download: `${ogmp3.api.base}/${ogmp3.utils.hash()}/download/${ogmp3.utils.encoded(prod.i)}/${ogmp3.utils.hash()}/`, id: id, quality: format } }; } } return { status: false, code: 500, error: "Dah capek bree... udah nyoba request berkali2 tetap gagal terus, dah lah reqnya nanti lagi aja yak 😂" }; } catch (error) { return { status: false, code: 500, error: error.message }; } } }; const savetube = { api: { base: "https://media.savetube.me/api", cdn: "/random-cdn", info: "/v2/info", download: "/download" }, headers: { 'accept': '*/*', 'content-type': 'application/json', 'origin': 'https://yt.savetube.me', 'referer': 'https://yt.savetube.me/', 'user-agent': 'Postify/1.0.0' }, formats: ['144', '240', '360', '480', '720', '1080', 'mp3'], crypto: { hexToBuffer: (hexString) => { const matches = hexString.match(/.{1,2}/g); return Buffer.from(matches.join(''), 'hex'); }, decrypt: async (enc) => { try { const secretKey = 'C5D58EF67A7584E4A29F6C35BBC4EB12'; const data = Buffer.from(enc, 'base64'); const iv = data.slice(0, 16); const content = data.slice(16); const key = savetube.crypto.hexToBuffer(secretKey); const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv); let decrypted = decipher.update(content); decrypted = Buffer.concat([decrypted, decipher.final()]); return JSON.parse(decrypted.toString()); } catch (error) { throw new Error(`${error.message}`); } } }, isUrl: str => { try { new URL(str); return true; } catch (_) { return false; } }, youtube: url => { if (!url) return null; const a = [ /youtube\.com\/watch\?v=([a-zA-Z0-9_-]{11})/, /youtube\.com\/embed\/([a-zA-Z0-9_-]{11})/, /youtube\.com\/v\/([a-zA-Z0-9_-]{11})/, /youtube\.com\/shorts\/([a-zA-Z0-9_-]{11})/, /youtu\.be\/([a-zA-Z0-9_-]{11})/ ]; for (let b of a) { if (b.test(url)) return url.match(b)[1]; } return null; }, request: async (endpoint, data = {}, method = 'post') => { try { const { data: response } = await axios({ method, url: `${endpoint.startsWith('http') ? '' : savetube.api.base}${endpoint}`, data: method === 'post' ? data : undefined, params: method === 'get' ? data : undefined, headers: savetube.headers }); return { status: true, code: 200, data: response }; } catch (error) { return { status: false, code: error.response?.status || 500, error: error.message }; } }, getCDN: async () => { const response = await savetube.request(savetube.api.cdn, {}, 'get'); if (!response.status) return response; return { status: true, code: 200, data: response.data.cdn }; }, download: async (link, format) => { if (!link) { return { status: false, code: 400, error: "Linknya mana? Yakali download kagak ada linknya 🗿" }; } if (!savetube.isUrl(link)) { return { status: false, code: 400, error: "Lu masukin link apaan sih 🗿 Link Youtube aja bree, kan lu mau download youtube 👍🏻" }; } if (!format || !savetube.formats.includes(format)) { return { status: false, code: 400, error: "Formatnya kagak ada bree, pilih yang udah disediain aja yak, jangan nyari yang gak ada 🗿", available_fmt: savetube.formats }; } const id = savetube.youtube(link); if (!id) { return { status: false, code: 400, error: "Kagak bisa ekstrak link youtubenya nih, btw link youtubenya yang bener yak.. biar kagak kejadian begini lagi 😂" }; } try { const cdnx = await savetube.getCDN(); if (!cdnx.status) return cdnx; const cdn = cdnx.data; const result = await savetube.request(`https://${cdn}${savetube.api.info}`, { url: `https://www.youtube.com/watch?v=${id}` }); if (!result.status) return result; const decrypted = await savetube.crypto.decrypt(result.data.data); const dl = await savetube.request(`https://${cdn}${savetube.api.download}`, { id: id, downloadType: format === 'mp3' ? 'audio' : 'video', quality: format, key: decrypted.key }); return { status: true, code: 200, result: { title: decrypted.title || "Gak tau 🤷🏻", type: format === 'mp3' ? 'audio' : 'video', format: format, thumbnail: decrypted.thumbnail || `https://i.ytimg.com/vi/${id}/maxresdefault.jpg`, download: dl.data.data.downloadUrl, id: id, key: decrypted.key, duration: decrypted.duration, quality: format, downloaded: dl.data.data.downloaded || false } }; } catch (error) { return { status: false, code: 500, error: error.message }; } } }; async function ytmobi(url, type = 'video') { if (!url.match(/youtu\.be|youtube\.com/i)) return { error: 'URL YouTube tidak valid' }; if (type === 'audio') { return { error: 'ytmobi hanya mendukung format video (MP4), gunakan server lain untuk format audio' }; } try { const headers = { "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": "cross-site", "Referer": "https://id.ytmp3.mobi/", "Referrer-Policy": "strict-origin-when-cross-origin" }; const initial = await fetch(`https://d.ymcdn.org/api/v1/init?p=y&23=1llum1n471&_=${Math.random()}`, { headers }); const init = await initial.json(); const id = url.match(/(?:youtu\.be\/|youtube\.com\/(?:.*v=|.*\/|.*embed\/))([^&?/]+)/)?.[1]; if (!id) throw new Error('Gagal mendapatkan ID video'); const convertURL = init.convertURL + `&v=${id}&f=mp4&_=${Math.random()}`; const converts = await fetch(convertURL, { headers }); const convert = await converts.json(); let info = {}; for (let i = 0; i < 5; i++) { await new Promise(resolve => setTimeout(resolve, 2000)); const progressRes = await fetch(convert.progressURL, { headers }); info = await progressRes.json(); if (info.progress === 3) break; } if (!info.title || !convert.downloadURL) throw new Error('Konversi gagal'); return { videoUrl: convert.downloadURL, title: info.title }; } catch (error) { console.error(error); return { error: error.message }; } } async function ytdl4(url, server = 1, type = 'video', resolution = '') { if (![1, 2, 3].includes(server)) { return { author: "Herza", Status: 404, error: "Server tidak valid. Pilih 1 (ogmp3), 2 (savetube), atau 3 (ytmobi)" }; } if (!url) { return { author: "Herza", Status: 404, error: "URL tidak boleh kosong" }; } if (!resolution) { if (server === 1) { resolution = type === 'video' ? '720' : '320'; } else if (server === 2) { resolution = type === 'video' ? '720' : 'mp3'; } } try { let result; if (server === 1) { result = await ogmp3.download(url, resolution, type); } else if (server === 2) { result = await savetube.download(url, resolution); } else if (server === 3) { const ytMobiResult = await ytmobi(url, type); if (ytMobiResult.error) { return { author: "Herza", Status: 404, error: ytMobiResult.error }; } const idMatch = url.match(/(?:youtu\.be\/|youtube\.com\/(?:.*v=|.*\/|.*embed\/))([^&?/]+)/); const id = idMatch ? idMatch[1] : null; result = { status: true, code: 200, result: { title: ytMobiResult.title || "Tidak diketahui", type: 'video', format: 'mp4', thumbnail: id ? `https://i.ytimg.com/vi/${id}/maxresdefault.jpg` : null, download: ytMobiResult.videoUrl, id: id } }; } if (result.status && result.code === 200) { return { author: "Herza", Status: 200, Results: result.result }; } else { return { author: "Herza", Status: 404, error: result.error || "Terjadi kesalahan saat mengunduh video" }; } } catch (error) { return { author: "Herza", Status: 404, error: error.message || "Terjadi kesalahan saat mengunduh video" }; } } module.exports = { ytdl4 };