| const puppeteer = require('puppeteer'); |
| const axios = require('axios'); |
| const Jimp = require('jimp'); |
| const FormData = require('form-data'); |
|
|
| const UPLOAD_API = 'https://cdnme.idnet.my.id/upload'; |
|
|
| async function generateBrat(text) { |
| const browser = await puppeteer.launch({ |
| headless: true, |
| args: [ |
| '--no-sandbox', |
| '--disable-setuid-sandbox', |
| '--disable-dev-shm-usage', |
| '--disable-accelerated-2d-canvas', |
| '--disable-gpu' |
| ] |
| }); |
|
|
| try { |
| const page = await browser.newPage(); |
| |
| await page.setViewport({ |
| width: 392, |
| height: 745, |
| deviceScaleFactor: 2.75 |
| }); |
|
|
| await page.setUserAgent('Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36'); |
|
|
| await page.goto('https://www.bratgenerator.com/', { |
| waitUntil: 'domcontentloaded', |
| timeout: 30000 |
| }); |
|
|
| await page.waitForSelector('#textInput'); |
| await page.click('#toggleButtonWhite'); |
| await new Promise(resolve => setTimeout(resolve, 300)); |
| |
| await page.evaluate((txt) => { |
| document.getElementById('textInput').value = txt; |
| const event = new Event('input', { bubbles: true }); |
| document.getElementById('textInput').dispatchEvent(event); |
| }, text); |
|
|
| await new Promise(resolve => setTimeout(resolve, 1500)); |
|
|
| const screenshot = await page.screenshot({ |
| type: 'png', |
| encoding: 'base64' |
| }); |
|
|
| await browser.close(); |
| |
| return screenshot; |
| |
| } catch (error) { |
| await browser.close(); |
| throw error; |
| } |
| } |
|
|
| async function processImage(base64Data) { |
| const imageBuffer = Buffer.from(base64Data, 'base64'); |
| const image = await Jimp.read(imageBuffer); |
| |
| const width = image.getWidth(); |
| const height = image.getHeight(); |
| const size = Math.min(width, height); |
| const x = Math.floor((width - size) / 2); |
| const y = Math.floor((height - size) / 2); |
| |
| image.crop(x, y, size, size); |
| image.resize(1080, 1080); |
| |
| return await image.getBufferAsync(Jimp.MIME_PNG); |
| } |
|
|
| async function uploadImage(imageBuffer) { |
| const form = new FormData(); |
| form.append('file', imageBuffer, { |
| filename: `brat-${Date.now()}.png`, |
| contentType: 'image/png' |
| }); |
|
|
| const response = await axios.post(UPLOAD_API, form, { |
| headers: form.getHeaders(), |
| timeout: 30000 |
| }); |
|
|
| if (!response.data.success) { |
| throw new Error('Failed to upload image'); |
| } |
|
|
| return response.data.url; |
| } |
|
|
| const handler = async (req, res) => { |
| try { |
| const { text, key } = req.query; |
|
|
| if (!text) { |
| return res.status(400).json({ |
| success: false, |
| error: 'Missing required parameter: text' |
| }); |
| } |
|
|
| const base64Screenshot = await generateBrat(text); |
| const processedImage = await processImage(base64Screenshot); |
| const imageUrl = await uploadImage(processedImage); |
|
|
| return res.json({ |
| author: "Herza", |
| success: true, |
| data: { |
| text: text, |
| url: imageUrl, |
| size: "1080x1080" |
| } |
| }); |
|
|
| } catch (error) { |
| res.status(500).json({ |
| success: false, |
| error: error.message, |
| timestamp: new Date().toISOString() |
| }); |
| } |
| }; |
|
|
| module.exports = { |
| name: 'Brat Generator', |
| description: 'Generate brat style images with custom text', |
| type: 'GET', |
| routes: ['api/maker/brat'], |
| tags: ['maker'], |
| parameters: ['text', 'key'], |
| limit: 5, |
| enabled: true, |
| main: ['maker'], |
| handler |
| }; |