const express = require('express'); const { chromium } = require('playwright'); const QRCode = require('qrcode'); const Jimp = require('jimp'); const QrCodeReader = require('qrcode-reader'); //const fetch = require('node-fetch'); const app = express(); const port = 7860; app.use(express.json()); app.get('/', (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') { 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)) { const rts = await fetch(url); if (!rts.ok || rts.status !== 200) return res.send({ status: 400, message: 'Can\'t buffer url' }); if (!/image/.test(rts.headers.get('content-type'))) return res.send({ status: 400, message: 'Only image type' }); const buffer = Buffer.from(await rts.arrayBuffer()); const image = await Jimp.read(buffer); image.grayscale().contrast(1).normalize(); 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 chromium.launch({ headless: true, args: ["--no-sandbox", "--disable-setuid-sandbox"] }); const context = await browser.newContext({ userAgent: ua || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', viewport: { width: width || 1280, height: height || 800 }, deviceScaleFactor: 2 }); const page = await context.newPage(); if (language) { await page.emulateMedia({ colorScheme: language }); } await page.goto(url, { waitUntil: 'networkidle' }); // Handle JavaScript challenges await page.waitForLoadState('networkidle'); // Example to handle JavaScript challenge // This is a placeholder, replace with actual challenge handling if needed // await page.evaluate(() => { // // Solve any inline JavaScript challenges // }); let screenshotOptions = { fullPage: fullpage == 1 ? true : false, type: 'png', omitBackground: false }; if (type === 'desktop') { await page.setViewportSize({ width: 1920, height: 1080, }); } else if (type === 'mobile') { await page.setViewportSize({ width: 375, height: 667, }); } else if (type === 'tablet') { await page.setViewportSize({ width: 768, height: 1024, }); } else if (type === 'iphone') { await page.setViewportSize({ 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(); } await page.setViewportSize({ width: Number(width) || 375, height: Number(height) || 667, }); } await page.waitForTimeout(5000); 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) { console.error(e); return res.json({ status: 400, message: 'error when take a screenshot' }); } } app.listen(port, () => { console.log(`Server is running on port ${port}`); });