Create app.js
Browse files
app.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const express = require('express');
|
| 2 |
+
const { chromium } = require('playwright');
|
| 3 |
+
const cors = require('cors');
|
| 4 |
+
const dotenv = require('dotenv');
|
| 5 |
+
const os = require('os');
|
| 6 |
+
|
| 7 |
+
dotenv.config();
|
| 8 |
+
|
| 9 |
+
const config = {
|
| 10 |
+
maxTextLength: 100,
|
| 11 |
+
viewport: { width: 1920, height: 1080 },
|
| 12 |
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
| 13 |
+
};
|
| 14 |
+
|
| 15 |
+
let browser, page;
|
| 16 |
+
let totalRequests = 0;
|
| 17 |
+
|
| 18 |
+
function formatUptime(seconds) {
|
| 19 |
+
const years = Math.floor(seconds / (365 * 24 * 3600));
|
| 20 |
+
const days = Math.floor((seconds % (365 * 24 * 3600)) / (24 * 3600));
|
| 21 |
+
const hours = Math.floor((seconds % (24 * 3600)) / 3600);
|
| 22 |
+
const minutes = Math.floor((seconds % 3600) / 60);
|
| 23 |
+
const secs = Math.floor(seconds % 60);
|
| 24 |
+
|
| 25 |
+
return `${years}y ${days}d ${hours}h ${minutes}m ${secs}s`;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
const utils = {
|
| 29 |
+
async initialize() {
|
| 30 |
+
if (!browser) {
|
| 31 |
+
browser = await chromium.launch({ headless: true });
|
| 32 |
+
const context = await browser.newContext({
|
| 33 |
+
viewport: config.viewport,
|
| 34 |
+
userAgent: config.userAgent
|
| 35 |
+
});
|
| 36 |
+
|
| 37 |
+
await context.route('**/*', (route) => {
|
| 38 |
+
const url = route.request().url();
|
| 39 |
+
if (url.endsWith('.png') || url.endsWith('.jpg') || url.includes('google-analytics')) {
|
| 40 |
+
return route.abort();
|
| 41 |
+
}
|
| 42 |
+
route.continue();
|
| 43 |
+
});
|
| 44 |
+
|
| 45 |
+
page = await context.newPage();
|
| 46 |
+
await page.goto('https://www.bratgenerator.com/', { waitUntil: 'domcontentloaded', timeout: 10000 });
|
| 47 |
+
|
| 48 |
+
try {
|
| 49 |
+
await page.click('#onetrust-accept-btn-handler', { timeout: 2000 });
|
| 50 |
+
} catch { }
|
| 51 |
+
|
| 52 |
+
await page.evaluate(() => setupTheme('white'));
|
| 53 |
+
}
|
| 54 |
+
},
|
| 55 |
+
|
| 56 |
+
async generateBrat(text) {
|
| 57 |
+
await page.fill('#textInput', text);
|
| 58 |
+
const overlay = page.locator('#textOverlay');
|
| 59 |
+
return overlay.screenshot({ timeout: 3000 });
|
| 60 |
+
},
|
| 61 |
+
|
| 62 |
+
async close() {
|
| 63 |
+
if (browser) await browser.close();
|
| 64 |
+
}
|
| 65 |
+
};
|
| 66 |
+
|
| 67 |
+
const app = express();
|
| 68 |
+
app.use(express.json());
|
| 69 |
+
app.use(cors());
|
| 70 |
+
app.set('json spaces', 3);
|
| 71 |
+
|
| 72 |
+
app.get('*', async (req, res) => {
|
| 73 |
+
try {
|
| 74 |
+
const { q } = req.query;
|
| 75 |
+
if (!q) {
|
| 76 |
+
return res.status(200).json({
|
| 77 |
+
name: 'HD Bart Generator API',
|
| 78 |
+
group: 'https://chat.whatsapp.com/ETZ8r7CLypfAPH93q0gC0y',
|
| 79 |
+
channel: 'https://whatsapp.com/channel/0029VaJYWMb7oQhareT7F40V',
|
| 80 |
+
message: 'Parameter q di perlukan',
|
| 81 |
+
version: '2.1.0',
|
| 82 |
+
runtime: {
|
| 83 |
+
os: {
|
| 84 |
+
type: os.type(),
|
| 85 |
+
platform: os.platform(),
|
| 86 |
+
release: os.release(),
|
| 87 |
+
architecture: os.arch(),
|
| 88 |
+
uptime: formatUptime(os.uptime())
|
| 89 |
+
},
|
| 90 |
+
cpu: {
|
| 91 |
+
count: os.cpus().length,
|
| 92 |
+
model: os.cpus()[0].model,
|
| 93 |
+
speed: `${os.cpus()[0].speed} MHz`
|
| 94 |
+
},
|
| 95 |
+
memory: {
|
| 96 |
+
total: `${(os.totalmem() / 1024 / 1024 / 1024).toFixed(2)} GB`,
|
| 97 |
+
used: `${((os.totalmem() - os.freemem()) / 1024 / 1024 / 1024).toFixed(2)} GB`,
|
| 98 |
+
free: `${(os.freemem() / 1024 / 1024 / 1024).toFixed(2)} GB`
|
| 99 |
+
},
|
| 100 |
+
loadAverage: os.platform() === 'linux' || os.platform() === 'darwin' ? os.loadavg().map(n => n.toFixed(2)) : 'N/A',
|
| 101 |
+
totalRequests: totalRequests
|
| 102 |
+
}
|
| 103 |
+
});
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
totalRequests++;
|
| 107 |
+
const imageBuffer = await utils.generateBrat(q);
|
| 108 |
+
res.set('Content-Type', 'image/png');
|
| 109 |
+
res.send(imageBuffer);
|
| 110 |
+
} catch (error) {
|
| 111 |
+
console.error(error);
|
| 112 |
+
res.status(500).json({
|
| 113 |
+
status: false,
|
| 114 |
+
message: 'Error generating image',
|
| 115 |
+
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
| 116 |
+
});
|
| 117 |
+
}
|
| 118 |
+
});
|
| 119 |
+
|
| 120 |
+
const PORT = process.env.PORT || 7860;
|
| 121 |
+
|
| 122 |
+
app.listen(PORT, async () => {
|
| 123 |
+
console.log(`Server running on port ${PORT}`);
|
| 124 |
+
await utils.initialize();
|
| 125 |
+
});
|
| 126 |
+
|
| 127 |
+
process.on('SIGINT', async () => {
|
| 128 |
+
await utils.close();
|
| 129 |
+
process.exit(0);
|
| 130 |
+
});
|