import puppeteer from "puppeteer"; import process from "node:process"; import axios from "axios"; import "dotenv/config"; const contas = { bpi2040: { url: "https://www.bancobpi.pt/particulares/poupar-investir/ppr/bpi-destino-ppr-2040", ghostfolioName: "BPI Destino PPR 2040", }, bpi2050: { url: "https://www.bancobpi.pt/particulares/poupar-investir/ppr/bpi-destino-ppr-2050", ghostfolioName: "BPI Destino PPR 2050", }, }; async function parseLogRocketBlogHome(conta) { // Launch the browser const browser = await puppeteer.launch({ args: ["--no-sandbox"], timeout: 10000, }); // Open a new tab const page = await browser.newPage(); // Visit the page and wait until network connections are completed await page.goto(conta.url, { waitUntil: "networkidle2" }); // Interact with the DOM to retrieve the titles const [price, date] = await page.evaluate(() => { const spanTags = document.getElementsByTagName("span"); const priceSearchText = "ÚLTIMA COTAÇÃO:"; const dateSearchText = "DATA COTAÇÃO:"; let priceElementFound; let dateElementFound; for (let i = 0; i < spanTags.length; i++) { if (spanTags[i].textContent.trim() == priceSearchText) { priceElementFound = spanTags[i]; console.log(`Found ${priceSearchText}.`); if (priceElementFound && dateElementFound) break; } if (spanTags[i].textContent.trim() == dateSearchText) { dateElementFound = spanTags[i]; console.log(`Found ${dateSearchText}.`); if (priceElementFound && dateElementFound) break; } } return [ priceElementFound.nextSibling.innerHTML, dateElementFound.nextSibling.innerHTML, ]; }); // Don't forget to close the browser instance to clean up the memory await browser.close(); const marketPrice = parseFloat( price.replace("€", "").trim().replace(",", "."), ); // Print the results console.log(decodeURIComponent(conta.ghostfolioName)); console.log(`Current price: € ${marketPrice}`); console.log(`Date: ${date}`); const bearerTokenResponse = await axios.post( `${process.env.GHOSTFOLIO_HOST}/api/v1/auth/anonymous`, { accessToken: process.env.GHOSTFOLIO_SECURITY_TOKEN, }, ); const response = await axios .post( `${process.env.GHOSTFOLIO_HOST}/api/v1/market-data/MANUAL/${conta.ghostfolioName}`, { marketData: [ { date, marketPrice, }, ], }, { headers: { Authorization: `Bearer ${bearerTokenResponse.data.authToken}`, }, }, ) .catch(console.error); console.log(response.status); } await Promise.all([ parseLogRocketBlogHome(contas.bpi2040), parseLogRocketBlogHome(contas.bpi2050), ]); process.exit(0);