UNPKG

@aidarkezio/main-func

Version:
190 lines (180 loc) • 7.17 kB
import cheerio from 'cheerio' import got from 'got' import { randomBytes } from 'crypto' import { ScraperError, decodeSnapApp, getEncodedSnapApp } from '../utils.js' import { FacebookDownloaderArgsSchema, FacebookDownloaderSchema, FacebookDownloader, FacebookDownloaderV2Schema, FacebookDownloaderV2, FacebookDownloaderV3Schema, FacebookDownloaderV3 } from './types.js' interface Ires { size?: string; ext: string; url: string; quality?: string; vcodec?: string; fid: string; } // only support download video yet export async function facebookdl (url: string): Promise<FacebookDownloader> { FacebookDownloaderArgsSchema.parse(arguments) /* eslint no-mixed-spaces-and-tabs: ["error", "smart-tabs"] */ const { data: { id, thumbnail, duration, a, av, v } }: { data: { id: string; thumbnail: string; duration: number; a: Ires[]; av: Ires[]; v: Ires[]; }; } = await got('https://youtube4kdownloader.com/ajax/getLinks.php', { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' }, searchParams: { video: url, rand: JSON.stringify(randomBytes(13)) } }).json() const result: FacebookDownloader['result'] = (a || []) .concat(av) .concat(v) .map(({ size, ext, url, quality, vcodec, fid }) => { const isVideo = ext === 'mp4' const isWebm = ext === 'webm' return { size, ext, url, quality, vcodec, fid, isVideo: isVideo || isWebm, isAudio: /audio/i.test(quality || '') || (isVideo && !isWebm) } // ext webm video without audio }) if (!result.length) throw new ScraperError(`Can't download!\n${JSON.stringify({ id, thumbnail, duration, a, av, v }, null, 2)}`) const res = { id, thumbnail, duration, result } return FacebookDownloaderSchema.parse(res) } export async function facebookdlv2 (url: string): Promise<FacebookDownloaderV2> { FacebookDownloaderArgsSchema.parse(arguments) const params: { url: string } = { url: encodeURI(url) } const res = await got .post('https://snapsave.app/action.php', { headers: { accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'en-US,en;q=0.9', 'content-type': 'application/x-www-form-urlencoded', origin: 'https://snapsave.app', referer: 'https://snapsave.app/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/96.0.4664.110 Safari/537.36' }, form: params }).text() const decodeParams = getEncodedSnapApp(res) let html: string if (!Array.isArray(decodeParams) || decodeParams.length !== 6) html = (typeof res === 'string' ? JSON.parse(res) : res)?.data else { const decode = decodeSnapApp(...decodeParams) // console.debug(decode) html = decode?.split('("download-section").innerHTML = "')[1] ?.split('; parent.document.getElementById("inputData").remove();')[0] ?.split('</style><section class=')[1].split('"> ') ?.slice(1)?.map(v => (v + '">').trim()).join() ?.split('</section><div class=')[0]?.replace(/\\(\\)?/g, '') } if (!html) throw new ScraperError(`Can't parse encode params!\n${res}`) const result: FacebookDownloaderV2['result'] = [] const $ = cheerio.load(html) $('table.table > tbody > tr').each(function () { const el = $(this).find('td') if (/tidak|no/i.test(el.eq(1).text())) { const quality = el.eq(0).text().split('(')?.[0]?.trim() const url = el.eq(2).find('a[href]').attr('href') if (url) result.push({ quality, url }) } }) if (!result.length) throw new ScraperError(`Can't download!\n${$.html()}`) const data = { id: $('div.media-content > div.content > p > strong') .text() .split('#')?.[1] ?.trim() || '', title: $('div.media-content > div.content > p > strong').text(), description: $('div.media-content > div.content > p > span.video-des').text(), thumbnail: $('figure > p.image > img[src]').attr('src') as string, result } return FacebookDownloaderV2Schema.parse(data) } export async function facebookdlv3 (url: string): Promise<FacebookDownloaderV3> { FacebookDownloaderArgsSchema.parse(arguments) const payload = { url } const text = await got('https://www.getfvid.com/downloader', { method: 'POST', headers: { accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'en-US,en;q=0.9', 'content-type': 'application/x-www-form-urlencoded', cookie: '_ga=GA1.2.887753826.1642391325; _gid=GA1.2.2022692773.1642391325; __gads=ID=4ea88e3817c8d71b-22332defffcf0045:T=1642391326:RT=1642391326:S=ALNI_MY3oJyiEG_b8KXZBJ7RqvN2Mn8wbw; XSRF-TOKEN=eyJpdiI6ImdNUElWWU83S01jOTdZeitCUWdkWXc9PSIsInZhbHVlIjoiTGxnaE9oRVJTKzA5NDBncUtBa0xEdCtqNHBJXC9ZMVFPR1U2RnBSYUFzZHltWElZS2VtVUltUTJ2TjB5V3pEeTYzRUNMcENjMURGSkhBXC9OUitpcjMrZz09IiwibWFjIjoiMTViZTNjZDI3ZTZmOTk2ZWRjOWM1NTA5MTU2NDFhYWFlMjIxNTQxZTJlYjliMjJiMzE3YzlkNGMxODc2NjhmMCJ9; laravel_session=eyJpdiI6IjhZbElIRmpLSkVqZGZpQXJoK2MzVHc9PSIsInZhbHVlIjoianBSSFhPb2t0RFY4Q1wvYkk1S3pxMUNxXC82b0U1NHZROTVpS1Z4dGhES3ZTYTNsenJUSXpwcWNMVDkwWFk4OUY1TitGNmlDK1RXbTVyREVzcHVoRnRidz09IiwibWFjIjoiY2U1YzI2ODZlYWI2NzFkZDU1NTQ5Zjk0M2NmMDc2MTZhY2M3ODQxYjljZGUzMDQwMTYxZGQwZGYxMDM3NDMyZSJ9; __cf_bm=ephRNXRqwgrTB4SmHlsudy886EfsR2Ns2KtXVBnph4I-1642392732-0-AXtTUW5HRNQUeUcTJPhJTOPlMcjBFmMyoLKYOnxrDZ6Fa06XaJ4pMNW9arLg4zco/ef+ji00IV8NZb0nGOAKgfg=; _gat=1; __atuvc=6%7C3; __atuvs=61e4e71d2b803588005; __atssc=google%3B3', origin: 'https://www.getfvid.com', referer: 'https://www.getfvid.com/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36' }, form: payload }).text() const $ = cheerio.load(text) const row = $('div.card > div.row > div') const thumbnail: string | undefined = /background-image: url\((.*?)\);/i.exec( row.eq(0).find('a[href]').attr('style') as string )?.[1] const result: FacebookDownloaderV3['result'] = [] row.find('.btns-download > p > a[href]').each(function () { const el = $(this) const url = el.attr('href') const info = el.text().trim() const isAudio = /audio/i.test(info) const quality = isAudio ? 'audio' : /Download in (\w+) Quality/i.exec(info)?.[1] const isVideo = quality !== 'audio' if (url) { result.push({ url, quality, isAudio, isVideo }) } }) if (!result.length) throw new ScraperError(`Can't download!\n${$.html()}`) const res = { title: $('#title_video').val() as string, thumbnail, result } return FacebookDownloaderV3Schema.parse(res) }