const cheerio = require("cheerio"); const cron = require("node-cron"); const axios = require("axios"); const { chromium } = require("playwright"); const fs = require("fs"); const discordWebhook = "https://discord.com/api/webhooks/1439286509390921749/t2Hb8XloF6zhDRYD1yh_QlkHHa9eHUyXvd9TxZRHwqR_b_OxxbnwDgsm4em8TwA9NQIa"; const priceSelectors = { miodowamydlarnia: ".projector_prices__price", greentouch: ".main-price", amazon: "#corePrice_feature_div .a-price .a-offscreen", soxo: "#projector_price_value span", empik: '[data-ta-section="priceMainContainer"] [data-ta="price"]', notino: "#pd-price", }; const excludePage = ["allegro", "homla.com.pl", "home-you.com"]; function sendMessage(message) { axios.post(discordWebhook, { content: message, }); } 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.link === product.link ); if (oldProduct && oldProduct.price !== product.price) { diffProducts.push({ name: product.name, newPrice: product.price, oldPrice: oldProduct.price, link: product.link, }); } } for (const product of diffProducts) { sendMessage( `Zmiana ceny **${product.name}**:\nCena: ${product.oldPrice} -> ${product.newPrice}\nLink: ${product.link}` ); } if (diffProducts.length === 0) { sendMessage("Brak zmian w cenach"); } fs.writeFileSync( "productsPrice.json", JSON.stringify(productsPrice, null, 2) ); } async function getProducts() { const products = await axios .get( "https://db.maciaszek.ovh/api/collections/gifts_items/records?fields=title,link" ) .then((response) => response.data.items); return products .filter((product) => product.link !== "") .filter( (product) => !excludePage.some((page) => product.link.includes(page)) ); } async function init() { const productsWithLinks = await getProducts(); const productsWithBrowser = []; const productsPrice = []; const selectors = Object.keys(priceSelectors); console.log("Zaczynam sprawdzać ceny"); for (const product of productsWithLinks) { if (product.link === "") continue; try { const { data } = await axios.get(product.link, { headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36", }, }); const $ = cheerio.load(data); const selector = selectors.find((selector) => product.link.includes(selector) ); const price = $(priceSelectors[selector]).text(); productsPrice.push({ name: product.title, price: price, link: product.link, }); } catch { productsWithBrowser.push(product); } } if (productsWithBrowser.length > 0) { const browser = await chromium.launch(); const context = await browser.newContext({ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36", }); const page = await context.newPage(); for (const product of productsWithBrowser) { await page.goto(product.link); const selector = selectors.find((selector) => product.link.includes(selector) ); const element = await page.$(priceSelectors[selector]); if (!element) continue; const price = await element.textContent(); productsPrice.push({ name: product.title, price: price, link: product.link, }); } await browser.close(); } await compareAndSave(productsPrice); console.log("Sprawdzone! Aktualne ceny zapisane w productsPrice.json"); } sendMessage("Zaczynam monitoring cen"); const task = cron.schedule("0 6,9,12,15,18,21 * * *", init, { timezone: "Europe/Warsaw", }); task.execute();