const express = require("express"); const { chromium } = require("playwright-core"); const { execSync } = require("child_process"); const app = express(); const PORT = process.env.PORT || 7860; async function getChromiumPath() { try { return execSync("which chromium-browser || which google-chrome || which chromium") .toString() .trim(); } catch { return null; } } app.get("/search", async (req, res) => { const movieName = req.query.movie; if (!movieName) { return res.status(400).json({ error: "Missing 'movie' query parameter" }); } const chromiumPath = await getChromiumPath(); console.log(`Chromium Path: ${chromiumPath || "Using Playwright's default"}`); const browser = await chromium.launch({ headless: true, executablePath: chromiumPath || undefined, args: ["--no-sandbox", "--disable-blink-features=AutomationControlled", "--disable-dev-shm-usage"] }); const context = await browser.newContext({ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36" }); const page = await context.newPage(); try { console.log(`Searching for: ${movieName}`); await page.goto("https://www.fzmovies.net/csearch.php", { waitUntil: "domcontentloaded", timeout: 60000 }); await page.fill("#searchname", movieName); await Promise.all([ page.click('input[type="submit"][name="Search"]'), page.waitForNavigation({ waitUntil: "domcontentloaded", timeout: 60000 }) ]); // Step 1: Get first movie result link const movieData = await page.evaluate(() => { const firstResult = document.querySelector(".mainbox a"); return firstResult ? { title: firstResult.innerText.trim(), link: firstResult.href } : null; }); if (!movieData) { console.log("No movie found!"); await browser.close(); return res.status(404).json({ error: "Movie not found" }); } console.log(`Movie Found: ${movieData.title}`); await page.goto(movieData.link, { waitUntil: "domcontentloaded", timeout: 60000 }); // Step 2: Extract the LAST download1.php link const downloadPageLink = await page.evaluate(() => { const baseURL = "https://www.fzmovies.net/"; const links = document.querySelectorAll('a[href*="download1.php?downloadoptionskey="]'); return links.length ? baseURL + links[links.length - 1].getAttribute("href") : null; }); if (!downloadPageLink) { await browser.close(); return res.status(404).json({ error: "Download link not found" }); } await page.goto(downloadPageLink, { waitUntil: "domcontentloaded", timeout: 60000 }); // Step 3: Extract "download.php" page link (LAST one) const finalDownloadPage = await page.evaluate(() => { const baseURL = "https://www.fzmovies.net/"; const links = document.querySelectorAll('a[href*="download.php?downloadkey="]'); return links.length ? baseURL + links[links.length - 1].getAttribute("href") : null; }); if (!finalDownloadPage) { await browser.close(); return res.status(404).json({ error: "Final download page not found" }); } await page.goto(finalDownloadPage, { waitUntil: "domcontentloaded", timeout: 60000 }); // Step 4: Extract LAST redirection link (dlink.php) const redirectedDownloadLink = await page.evaluate(() => { const links = document.querySelectorAll('a[href*="dlink.php?id="]'); return links.length ? links[links.length - 1].href : null; }); if (!redirectedDownloadLink) { await browser.close(); return res.status(404).json({ error: "Redirected download link not found" }); } console.log(`Redirecting to final download page: ${redirectedDownloadLink}`); // Step 5: Follow the redirection, intercept network requests, and extract the REAL file URL const downloadPage = await context.newPage(); let finalDownloadURL = null; // Capture the final URL using network interception downloadPage.on("response", async (response) => { const url = response.url(); if (url.match(/\.(mp4|mkv|avi|mov)$/i)) { console.log(`Final File Found: ${url}`); finalDownloadURL = url; } }); await downloadPage.goto(redirectedDownloadLink, { waitUntil: "domcontentloaded", timeout: 60000 }); // If no final URL is found, check the current page URL (sometimes it's a direct link) if (!finalDownloadURL) { finalDownloadURL = downloadPage.url(); } await downloadPage.close(); if (!finalDownloadURL) { await browser.close(); return res.status(500).json({ error: "Failed to retrieve final download link" }); } // Extract movie name from filename in URL let cleanedMovieTitle = movieData.title .replace(/[_\.-]/g, " ") // Replace underscores and hyphens with spaces .replace(/\b(BluRay|HD|720p|1080p|480p|fzmovies|net|mp4|mkv|avi|mov)\b/gi, "") // Remove extra words .replace(/\(\s*\)/g, "") // Remove empty parentheses .replace(/\s+/g, " ") // Remove extra spaces .replace(/\b[a-f0-9]{32}\b/, "") // Remove hash codes .trim(); console.log(`Movie Title: ${cleanedMovieTitle}`); console.log(`Final Download Link: ${finalDownloadURL}`); await browser.close(); return res.json({ movieTitle: cleanedMovieTitle, downloadLink: finalDownloadURL }); } catch (error) { console.error("Error:", error.message); await browser.close(); return res.status(500).json({ error: "Internal server error", details: error.message }); } }); // Start the Express server app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));