const puppeteer = require("puppeteer"); const axios = require("axios"); const luxon = require("luxon"); const { exit } = require("process"); const fs = require("fs"); const path = require("path"); const xlsx = require("xlsx"); const dotenv = require("dotenv").config({ path: __dirname + "/.env" }); const utils = require("./utils"); const emailUtils = require("./email-utils"); (async function () { console.log( `===========< STARTED ${utils.getPakistanStandardTime( luxon.DateTime.now() )} >=========` ); const syncDate = luxon.DateTime.now().toFormat("yyyy-MM-dd"); const screenshotDirectory = path.join(__dirname, `screenshots/${syncDate}`); if (!fs.existsSync(screenshotDirectory)) { fs.mkdirSync(screenshotDirectory, { recursive: true }); } /** * loading config data */ const config = JSON.parse(fs.readFileSync(__dirname + "/config.json")); const environment = process.env["ENVIRONMENT"]; const cryptoConfig = utils.getCryptoConfig(); const email = utils.decryptString( process.env["temu-email"], cryptoConfig.algo, cryptoConfig.key, cryptoConfig.iv ); const password = utils.decryptString( process.env["temu-password"], cryptoConfig.algo, cryptoConfig.key, cryptoConfig.iv ); /* * load cookies */ const loadPageCookies = async function (page) { const cookiesFileName = `cookies.json`; if (fs.existsSync(__dirname + `/cookies/${cookiesFileName}`)) { const cookiesStr = fs.readFileSync( __dirname + `/cookies/${cookiesFileName}` ); const cookies = JSON.parse(cookiesStr); await page.setCookie(...cookies); } }; // launch browser and open page const chromeProfilePath = path.resolve( __dirname, config[environment]["chrome_profile_path"] ); const browser = await puppeteer.launch( utils.getBrowserConfig(chromeProfilePath, environment) ); const page = await browser.newPage(); //await loadPageCookies(page); await page.setViewport({ width: 1600, height: 900, }); // Inject CSS to show the cursor await page.evaluate(() => { const style = document.createElement("style"); style.innerHTML = "* { cursor: auto !important; }"; document.head.appendChild(style); }); // save cookies on page load const cookiesFileName = `cookies.json`; page.on("load", async function () { // save cookies const cookies = await page.cookies(); fs.writeFileSync( __dirname + `/cookies/${cookiesFileName}`, JSON.stringify(cookies, null, 2) ); }); /* * configure download path of excel report */ const generateTheDownloadPath = async function (page, downloadPath) { // create client session for configuration const client = await page.target().createCDPSession(); // set the download path await client.send("Page.setDownloadBehavior", { behavior: "allow", downloadPath: downloadPath, // Change this to your desired download path. }); }; /* * goto login page */ const loginPage = config[environment]["temuLoginPage"]; await page.goto(loginPage, { waitUntil: ["domcontentloaded"], }); await utils.tryTemuLogin(page, email, password, loginPage); await new Promise((resolve) => setTimeout(resolve, 7000)); // goto orders request page const ordersRequestPage = config[environment]["temuOrderReportPage"]; await page.goto(ordersRequestPage, { waitUntil: ["domcontentloaded"], }); // generate json from excel mark it processed const unprocessedFolderPath = path.join( config[environment].temu_orders_path, "unprocessed" ); /* * request order report */ try { const orderRequestSelector = "div._3yOxLjm0._2pgGmJ7w.IoqjAtdZ.vbGE0cGC"; const element = await page.$(orderRequestSelector); if (element) { // wait for 5 sec await new Promise((resolve) => setTimeout(resolve, 5 * 1000)); await element.click(); console.log("Clicked on the Request Report btn"); // take screenshot let screenshotPath = path.join( screenshotDirectory, `${luxon.DateTime.now().toMillis()}.png` ); await page.screenshot({ path: screenshotPath, fullPage: true }); // wait 10 secs await new Promise((resolve) => setTimeout(resolve, 10 * 1000)); // take screenshot screenshotPath = path.join( screenshotDirectory, `${luxon.DateTime.now().toMillis()}.png` ); await page.screenshot({ path: screenshotPath, fullPage: true }); // wait 10 secs await new Promise((resolve) => setTimeout(resolve, 10 * 1000)); const confirmBtnSelector = "div._3yOxLjm0._2pgGmJ7w._1eT_m6dA"; const confirmBtnElement = await page.$(confirmBtnSelector); if (confirmBtnElement) { await new Promise((resolve) => setTimeout(resolve, 15 * 1000)); await confirmBtnElement.click(); console.log("Clicked on the Confirm Button"); // wait for 3 seconds then reload page await new Promise((resolve) => setTimeout(resolve, 5 * 1000)); // take screenshot screenshotPath = path.join( screenshotDirectory, `${luxon.DateTime.now().toMillis()}.png` ); await page.screenshot({ path: screenshotPath, fullPage: true }); } } else { console.log(" Request Btn doest exists"); } // wait for 5 mins for request to be processed await new Promise((resolve) => setTimeout(resolve, 5 * 60 * 1000)); await page.reload(); console.log("Page reloaded"); // wait for 5 mins for request to be processed await new Promise((resolve) => setTimeout(resolve, 5 * 60 * 1000)); // take screenshot var screenshotPath = path.join( screenshotDirectory, `${luxon.DateTime.now().toMillis()}.png` ); await page.screenshot({ path: screenshotPath, fullPage: true }); // download latest report await page.waitForSelector("div._2zs6hel0"); // Select all divs with the class _2zs6hel0 const divs = await page.$$("div._2zs6hel0"); console.log(`Found ${divs.length} Buttons`); const downloadFolderPath = path.resolve( config[environment].temu_orders_path, `unprocessed/` ); // download the latest report if (divs.length > 1) { generateTheDownloadPath(page, downloadFolderPath); console.log("Clicking On download Button"); await new Promise((resolve) => setTimeout(resolve, 10 * 1000)); // take screenshot var screenshotPath = path.join( screenshotDirectory, `${luxon.DateTime.now().toMillis()}.png` ); await page.screenshot({ path: screenshotPath, fullPage: true }); // wait 600 seconds await new Promise((resolve) => setTimeout(resolve, 60 * 1000)); await divs[0].click(); } // take screenshot var screenshotPath = path.join( screenshotDirectory, `${luxon.DateTime.now().toMillis()}.png` ); await page.screenshot({ path: screenshotPath, fullPage: true }); // wait 60 seconds await new Promise((resolve) => setTimeout(resolve, 30 * 1000)); } catch (e) { emailUtils.notify(`Sync Temu Orders`, e.message); } // Function to read Excel files and convert to JSON const convertExcelToJson = () => { fs.readdir(unprocessedFolderPath, (err, files) => { if (err) { console.error("Error reading the directory:", err); return; } // Filter Excel files (xlsx or xls) const excelFiles = files.filter( (file) => file.endsWith(".xlsx") || file.endsWith(".xls") || file.endsWith(".csv") ); // Process each Excel file excelFiles.forEach((file) => { const filePath = path.join(unprocessedFolderPath, file); const workbook = xlsx.readFile(filePath); const sheetName = workbook.SheetNames[0]; // Use the first sheet const worksheet = workbook.Sheets[sheetName]; // Convert the sheet to JSON let jsonData = xlsx.utils.sheet_to_json(worksheet); // Modify the column names by adding underscores jsonData = jsonData.map((row) => { const modifiedRow = {}; Object.keys(row).forEach((key) => { const newKey = key.replace(/\s+/g, "_").toLowerCase(); const value = row[key] === undefined || row[key] === "" || row[key] === null ? "" : row[key]; modifiedRow[newKey] = value; }); return modifiedRow; }); // write the JSON data to a file const outputFile = path.join( config[environment].temu_orders_path, "data/unprocessed", `${luxon.DateTime.now().toMillis()}.json` ); fs.writeFileSync(outputFile, JSON.stringify(jsonData, null, 2)); console.log(`Saved JSON to ${outputFile}`); console.log( `Move Excel file ${filePath} to ${config[environment].temu_orders_path}/processed` ); fs.renameSync( filePath, path.join(`${config[environment].temu_orders_path}/processed`, file) ); }); }); }; convertExcelToJson(); console.log( `==========< ENDED ${utils.getPakistanStandardTime( luxon.DateTime.now() )} >==========` ); await page.close(); await browser.close(); })();