|
const express = require('express'); |
|
const puppeteer = require('puppeteer-extra'); |
|
const StealthPlugin = require('puppeteer-extra-plugin-stealth'); |
|
const AnonymizeUA = require('puppeteer-extra-plugin-anonymize-ua'); |
|
var jimp = require("jimp"); |
|
var qrCode = 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 /') |
|
console.log('IP => ' + req.headers['x-real-ip']) |
|
console.log('User Agent => ' + req.headers['user-agent']) |
|
res.send({message: 'halo kontol'}) |
|
}) |
|
app.post('/screenshot', async (req, res) => { |
|
console.log('request to /screenshot') |
|
console.log('IP => ' + req.headers['x-real-ip']) |
|
console.log('User Agent => ' + req.headers['user-agent']) |
|
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)') |
|
console.log('IP => ' + req.headers['x-real-ip']) |
|
console.log('User Agent => ' + req.headers['user-agent']) |
|
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 |
|
}); |
|
}); |
|
|
|
async function processScreenshot(req, res, { |
|
ua, |
|
url, |
|
type, |
|
width, |
|
height, |
|
language, |
|
fullpage |
|
}) { |
|
|
|
console.log('process screenshot') |
|
const browser = await puppeteer.launch({ |
|
headless: "new", |
|
executablePath:"/usr/bin/chromium", |
|
protocolTimeout: 0, |
|
args: [ |
|
|
|
"--fast-start", |
|
|
|
"--disable-extensions", |
|
|
|
"--no-sandbox", |
|
|
|
"--disable-setuid-sandbox", |
|
|
|
"--no-gpu", |
|
|
|
"--disable-background-timer-throttling", |
|
|
|
"--disable-renderer-backgrounding", |
|
|
|
"--override-plugin-power-saver-for-testing=never", |
|
|
|
"--disable-extensions-http-throttling", |
|
|
|
"--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.3" |
|
|
|
] |
|
}); |
|
const page = await browser.newPage(); |
|
|
|
|
|
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', |
|
}); |
|
try { |
|
await page.goto(url); |
|
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,deviceScaleFactor: 2 |
|
}); |
|
} else if (type === 'mobile') { |
|
screenshotOptions = { |
|
fullPage: full, |
|
width: 375, |
|
height: 667 |
|
}; |
|
await page.setViewport({ |
|
width: 375, |
|
height: 667,deviceScaleFactor: 2 |
|
}); |
|
} else if (type === 'tablet') { |
|
screenshotOptions = { |
|
fullPage: full, |
|
width: 768, |
|
height: 1024 |
|
}; |
|
await page.setViewport({ |
|
width: 768, |
|
height: 1024,deviceScaleFactor: 2 |
|
}); |
|
} else if (type === 'iphone') { |
|
screenshotOptions = { |
|
fullPage: full, |
|
width: 375, |
|
height: 667 |
|
}; |
|
await page.setViewport({ |
|
width: 375, |
|
height: 667,deviceScaleFactor: 2 |
|
}); |
|
} else if (type === 'custom') { |
|
if (width && height > 4096) { |
|
await browser.close(); |
|
return res.json({ |
|
"status": 400, |
|
"message": "Width and height values should not exceed 4096 pixels." |
|
}); |
|
} |
|
if (width && height < 90) { |
|
await browser.close(); |
|
return res.json({ |
|
"status": 400, |
|
"message": "Width and height values should not be less than 90 pixels." |
|
}); |
|
} |
|
screenshotOptions = { |
|
fullPage: full, |
|
width: width || 375, |
|
height: height || 667 |
|
}; |
|
await page.setViewport({ |
|
width: Number(width) || 375, |
|
height: Number(height) || 667,deviceScaleFactor: 2 |
|
}); |
|
} |
|
|
|
|
|
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('screenshot successfully') |
|
await browser.close(); |
|
} catch (e) { |
|
console.log(e) |
|
await browser.close(); |
|
return res.json({ |
|
status: 400, |
|
message: 'error when take a screenshot' |
|
}) |
|
} |
|
} |
|
|
|
const PORT = process.env.PORT || 7860 |
|
function restartSpace() { |
|
const { SPACE_ID, HF_TOKEN } = process.env |
|
return fetch(`https://huggingface.co/api/spaces/${SPACE_ID}/restart`, { |
|
method: 'POST', |
|
headers: { Authorization: `Bearer ${HF_TOKEN}` } |
|
}) |
|
} |
|
|
|
function keepAlive() { |
|
var url = `https://${process.env.SPACE_HOST}` |
|
if (/(\/\/|\.)undefined\./.test(url)) return |
|
setInterval(() => { |
|
fetch(url, { headers: { Authorization: "Bearer " + process.env.HF_TOKEN}}) |
|
.then(response => { |
|
if (!response.ok) { |
|
restartSpace().catch(console.error) |
|
} |
|
}) |
|
.catch(console.error) |
|
}, 5 * 1000 * 60) |
|
} |
|
app.get("/qrcode", async (req, res) => { |
|
if (!req.query.url) return res.send({status: 400}) |
|
if (!req.query.mode) return res.send({status: 400}) |
|
const readQRCode = async (buffer) => { |
|
try { |
|
const img = await jimp.read(buffer); |
|
const qr = new qrCode(); |
|
const value = await new Promise((resolve, reject) => { |
|
qr.callback = (err, v) => err != null ? reject(err) : resolve(v); |
|
qr.decode(img.bitmap); |
|
}); |
|
return value.result; |
|
} catch (error) { |
|
return error.message |
|
} |
|
} |
|
|
|
if (req.query.mode == "scan") { |
|
let rts = await fetch(req.query.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' |
|
}) |
|
return res.send({ result: await readQRCode(await rts.arrayBuffer()) || null }) |
|
} else { |
|
var { toDataURL } = require("qrcode"); |
|
let me = await toDataURL(req.query.url); |
|
res.type('png').send(Buffer.from(me.split("base64,")[1], "base64")); |
|
} |
|
}) |
|
app.listen(PORT, async () => { |
|
console.log('App running on port', PORT) |
|
console.log(fetch) |
|
console.log(process.env['HF_TOKEN']) |
|
|
|
keepAlive() |
|
}) |