const express = require('express'); const puppeteer = require('puppeteer-extra'); const StealthPlugin = require('puppeteer-extra-plugin-stealth'); const AnonymizeUA = require('puppeteer-extra-plugin-anonymize-ua'); const QRCode = require('qrcode'); const Jimp = require('jimp'); const QrCodeReader = require('qrcode-reader'); puppeteer.use(StealthPlugin()); puppeteer.use(AnonymizeUA()); const app = express(); const port = 5000; app.use(express.json()); app.get('/', async (req, res) => { console.log('request to /') res.send('halo kontol') }) app.post('/screenshot', async (req, res) => { console.log('request to /screenshot') const { ua, url, type, width, height, language, fullpage } = req.body; if (!url) return res.send('please input url') await processScreenshot(req, res, { ua, url, type, width, height, language, fullpage }); }); app.get('/screenshot', async (req, res) => { console.log('request to /screenshot (get)') const { ua, url, type, width, height, language, fullpage } = req.query; if (!url) return res.send('please input url') await processScreenshot(req, res, { ua, url, type, width, height, language, fullpage }); }); app.get('/qrcode', async (req, res) => { try { const { mode, url } = req.query; if (!mode || !url) { return res.status(400).send('what?'); } if (mode === 'create') { // Generate a QR code QRCode.toDataURL(url, (err, src) => { if (err) return res.send({ error: 'Error generating QR code' }); res.type('png').send(Buffer.from(src.split(",")[1], "base64")); }); } else if (['read', 'scan'].includes(mode)) { // Fetch the image and read the QR code const response = await fetch(url); const buffer = await response.buffer(); const image = await Jimp.read(buffer); // Preprocess the image to enhance QR code readability image .grayscale() // Convert to grayscale .contrast(1) // Increase contrast .normalize(); // Normalize the image const qrCodeReader = new QrCodeReader(); qrCodeReader.callback = (err, value) => { if (err) return res.send({ error: 'Error reading QR code' }); res.json({ result: value.result }); }; const bitmap = image.bitmap; qrCodeReader.decode({ width: bitmap.width, height: bitmap.height, data: bitmap.data }); } else { QRCode.toDataURL(url, (err, src) => { if (err) return res.send({ error: 'Error generating QR code' }); res.type('png').send(Buffer.from(src.split(",")[1], "base64")); }); } } catch (error) { console.error(error); res.send({ error: 'Internal Server Error' }); } }); async function processScreenshot(req, res, { ua, url, type, width, height, language, fullpage }) { try { console.log('process screenshot') const browser = await puppeteer.launch({ headless: "new", args: ["--aggressive-tab-discard", "--disable-accelerated-2d-canvas", "--disable-application-cache", "--disable-cache", "--disable-dev-shm-usage", "--disable-gpu", "--disable-offline-load-stale-cache", "--disable-setuid-sandbox", "--disable-setuid-sandbox", "--disk-cache-size=0", "--ignore-certificate-errors", "--no-first-run", "--no-sandbox", "--no-zygote" ] }); const page = await browser.newPage(); // Set language and user agent await page.setExtraHTTPHeaders({ 'Accept-Language': language || 'id-ID', 'User-Agent': ua || 'Mozilla/5.0 (Linux; Android 13; Pixel Build/RPB1.210523.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36', }); await page.goto(url, { waitUntil: 'networkidle2', }); let full = fullpage == 1 ? true : false let screenshotOptions = { fullPage: true }; if (type === 'desktop') { screenshotOptions = { fullPage: full, width: 1280, height: 800 }; await page.setViewport({ width: 1280, height: 800, }); } else if (type === 'mobile') { screenshotOptions = { fullPage: full, width: 375, height: 667 }; await page.setViewport({ width: 375, height: 667, }); } else if (type === 'tablet') { screenshotOptions = { fullPage: full, width: 768, height: 1024 }; await page.setViewport({ width: 768, height: 1024, }); } else if (type === 'iphone') { screenshotOptions = { fullPage: full, width: 375, height: 667 }; await page.setViewport({ width: 375, height: 667, }); } else if (type === 'custom') { if (width && height > 4096) { return res.json({ "status": 400, "message": "Width and height values should not exceed 4096 pixels." }); await browser.close(); } if (width && height < 400) { return res.json({ "status": 400, "message": "Width and height values should not be less than 400 pixels." }); await browser.close(); } screenshotOptions = { fullPage: full, width: width || 375, height: height || 667 }; await page.setViewport({ width: Number(width) || 375, height: Number(height) || 667, }); } // Wait for a few seconds to mimic more natural behavior await page.waitForTimeout(3000); const screenshot = await page.screenshot(screenshotOptions); res.writeHead(200, { 'Content-Type': 'image/png', 'Content-Length': screenshot.length, }); res.end(screenshot); console.log('process done') await browser.close(); } catch (e) { log(e) return res.json({ status: 400, message: 'error when take a screenshot' }) } } app.listen(port, () => { console.log(`Server is running on port ${port}`); });