const cheerio = require("cheerio"); const cron = require("node-cron"); const axios = require("axios"); const fs = require("fs"); const { chromium } = require("playwright"); const discordWebhook = "https://discord.com/api/webhooks/1439286509390921749/t2Hb8XloF6zhDRYD1yh_QlkHHa9eHUyXvd9TxZRHwqR_b_OxxbnwDgsm4em8TwA9NQIa"; function sendMessage(message) { axios.post(discordWebhook, { content: message, }); } let isFirstRun = true; async function compareAndSave(productsPrice) { if (!fs.existsSync("productsPrice.json")) { fs.writeFileSync("productsPrice.json", "[]"); } const productsPriceJson = fs.readFileSync("productsPrice.json", "utf8"); const oldProductsPrice = JSON.parse(productsPriceJson); const diffProducts = []; for (const product of productsPrice) { const oldProduct = oldProductsPrice.find( (oldProduct) => oldProduct.name === product.name ); if (oldProduct && oldProduct.price !== product.price) { diffProducts.push({ name: product.name, newPrice: product.price, oldPrice: oldProduct.price, link: product.link, shop: product.shop, }); } } for (const product of diffProducts) { sendMessage( `Zmiana ceny **${product.name}**: ${product.oldPrice} -> ${product.newPrice}\nLink: ${product.link}` ); } if (isFirstRun) { for (const product of productsPrice) { sendMessage(`Początkowa cena **${product.name}**: ${product.price}`); } isFirstRun = false; } fs.writeFileSync( "productsPrice.json", JSON.stringify(productsPrice, null, 2) ); } async function getProducts() { const products = fs.readFileSync("input.txt", "utf8"); const productsIds = products.split("\n"); return productsIds; } async function init() { const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", }); const page = await context.newPage(); const productsIds = await getProducts(); const products = []; for (const productId of productsIds) { try { await page.goto(`https://www.ceneo.pl/${productId}`, { waitUntil: "networkidle", timeout: 30000, }); // Wait for bot detection to pass and content to load await page .waitForSelector(".product-offer__container, .product-top", { timeout: 10000, }) .catch(() => { console.log(`Timeout waiting for content on ${productId}`); }); const html = await page.content(); const $ = cheerio.load(html); const items = $(".product-offer__container").first(); for (const item of items) { let name = $(item).data("productname"); let price = $(item).data("price"); let link = `https://www.ceneo.pl/${$(item).data("click-url")}`; const shop = $(item).data("shopurl") || "ceneo.pl"; if (!name || !price) { name = $(item).find(".short-name__txt").text(); price = $(item).find(".price").text(); link = `https://www.ceneo.pl/${productId}`; } if (!name || !price || !link) { continue; } products.push({ name, price, link, shop }); } } catch (error) { console.error(`Error fetching product ${productId}:`, error.message); } } await browser.close(); await compareAndSave(products); console.log("Aktualne ceny zapisane w productsPrice.json"); } sendMessage("Startuję monitoring cen"); const task = cron.schedule("*/15 7-23 * * *", init, { timezone: "Europe/Warsaw", }); cron.schedule("0 7 * * *", () => { const date = new Date().toLocaleDateString("pl-PL"); sendMessage(`Zaczynamy monitoring ${date}`); }); task.execute();