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
JavaScript
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 };