UNPKG

reel-downloader

Version:

Download videos from Instagram, Facebook, Twitter, Youtube seamlessly and quick with videos-downloader apis.

187 lines (132 loc) 6.42 kB
import puppeteer from "puppeteer"; import * as cheerio from 'cheerio'; import fs from 'fs'; // Instagram credentials const INSTAGRAM_USERNAME = process.env.INSTAGRAM_USERNAME; const INSTAGRAM_PASSWORD = process.env.INSTAGRAM_PASSWORD; // File to store the cookies const COOKIES_FILE_PATH = './instagram_cookies.json'; // Function to login and get new cookies async function resetCookies(page) { try { console.log('Logging into Instagram...'); await page.goto('https://www.instagram.com/accounts/login/', { waitUntil: 'networkidle2' }); // Fill the login form await page.type('input[name="username"]', INSTAGRAM_USERNAME, { delay: 100 }); await page.type('input[name="password"]', INSTAGRAM_PASSWORD, { delay: 100 }); // Submit the form and wait for navigation await Promise.all([ page.click('button[type="submit"]'), page.waitForNavigation({ waitUntil: 'networkidle2' }) ]); // Save cookies after successful login const cookies = await page.cookies(); fs.writeFileSync(COOKIES_FILE_PATH, JSON.stringify(cookies, null, 2), { encoding: 'utf8' }); return cookies; } catch (error) { console.log(error.message, error, 'from resetCookies'); return null } } // Function to load cookies from file async function loadCookies(page) { try { const cookieData = fs.readFileSync(COOKIES_FILE_PATH, { encoding: 'utf-8' }); if (cookieData.trim()) { // Check if the file has non-empty content const cookies = JSON.parse(cookieData); // Parse the cookies console.log('Cookies loaded from file.'); await page.setCookie(...cookies); // Set the cookies in Puppeteer } else { console.log('Cookies file is empty. resetting cookies'); await resetCookies(page); } } catch (error) { console.error('Error loading cookies:', error.message); } } async function getPostPageHtml(page, inputUrl) { if (inputUrl.includes('/reel/')) { inputUrl = `https://www.instagram.com/reel/${inputUrl.split('/reel/')[1].slice(0, 11)}` } console.log('getting post page html of', inputUrl) try { await page.goto(inputUrl, { waitUntil: ['networkidle2', 'domcontentloaded'] }); const text = await page.$eval('*', el => el.innerText); // console.log(text); const isModal = text.includes('View story'); if (isModal) { console.log("Detected 'View Story' modal, attempting to click..."); await page.evaluate(() => { const storyButton = Array.from(document.querySelectorAll('div[role="button"]')) .find(div => div.textContent.includes('View story')); console.log('storyButton', storyButton); if (storyButton) storyButton.click(); }); } console.log('isModal', isModal); await page.waitForFunction(() => ( document.querySelectorAll('script[type][data-content-len][data-sjs]').length > 0 )); return await page.content(); } catch (error) { console.log('Error fetching page HTML:', error); return null; } } export default function instagram(inputUrl) { return new Promise(async (resolve, reject) => { console.log('inputUrl', inputUrl) let browser; browser = await puppeteer.launch({ headless: false, }); try { const page = await browser.newPage(); if (!inputUrl) { reject({ error: 'Please enter a valid Instagram URL', status: 400 }); browser.close(); return; } if (!inputUrl.includes('/reel/')) { reject({ error: 'Please enter a valid Reel URL', status: 400 }); browser.close(); return; } await loadCookies(page); const htmlContent = await getPostPageHtml(page, inputUrl); const $ = cheerio.load(htmlContent.toString()); let downloadUrl; console.log('finding videos just for you...'); const urlAvailable = $('script[type][data-content-len][data-sjs]').toArray().find((el) => el.children[0].data.includes('.mp4')); if (urlAvailable) { console.log('Download URL found in the HTML content'); const parsed = JSON.parse(urlAvailable.children[0].data); downloadUrl = parsed.require[0][3][0].__bbox.require[0][3][1].__bbox.result.data.xdt_api__v1__media__shortcode__web_info.items[0].video_versions } if (!urlAvailable) { console.log('No video URL found trying again...'); const cookies = await resetCookies(page); await loadCookies(page); const htmlContent = await getPostPageHtml(page, inputUrl); const $ = cheerio.load(htmlContent.toString()); const isUrl = $('script[type][data-content-len][data-sjs]').toArray().find((el) => el.children[0].data.includes('.mp4')); if (!isUrl) { reject({ error: 'No video URL found', status: 404 }); } const parsed = JSON.parse(isUrl.children[0].data); downloadUrl = parsed.require[0][3][0].__bbox.require[0][3][1].__bbox.result.data.xdt_api__v1__media__shortcode__web_info.items[0].video_versions } await browser.close(); console.log('downloadUrl', downloadUrl); if (downloadUrl) { resolve({ status: 200, downloadUrl }); } else { reject({ error: 'No video URL found', status: 404 }); } } catch (error) { console.log('Error:', error); if (browser) await browser.close(); reject({ error: error.message, status: 500 }); } }) }