import express from 'express';
import { chromium } from 'playwright';
import cors from 'cors';
import dotenv from 'dotenv';
import os from 'os';
import axios from 'axios';
import fetch from 'node-fetch';
import sharp from 'sharp';
import { spawn } from 'child_process';
import path from 'path';
import { NodeVM } from "vm2";
import { CompileFile } from 've-compiler';
import { createRequire } from "module";
const require = createRequire(import.meta.url);
import EventEmitter from 'events';
import WebSocket from 'ws';
import crypto from 'crypto';
import pkg from 'axios-cookiejar-support';
const { wrapper } = pkg;
import { CookieJar } from 'tough-cookie';
import * as cheerio from 'cheerio';
import TurndownService from 'turndown';
import { Readable } from 'stream';
dotenv.config();
const config = {
maxTextLength: 100,
viewport: { width: 1920, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
};
let browser, page;
const utils = {
async initialize() {
if (!browser) {
browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: config.viewport,
userAgent: config.userAgent
});
await context.route('**/*', (route) => {
const url = route.request().url();
if (url.endsWith('.png') || url.endsWith('.jpg') || url.includes('google-analytics')) {
return route.abort();
}
route.continue();
});
page = await context.newPage();
await page.goto('https://www.bratgenerator.com/', { waitUntil: 'domcontentloaded', timeout: 10000 });
try {
await page.click('#onetrust-accept-btn-handler', { timeout: 2000 });
} catch { }
//await page.evaluate(() => setupTheme('white'));
}
},
async generateBrat(text) {
await page.fill('#textInput', text);
const overlay = page.locator('#textOverlay');
return overlay.screenshot({ timeout: 3000 });
},
async close() {
if (browser) await browser.close();
}
};
const app = express();
app.use(express.json());
app.use(cors());
app.get('/', (req, res) => {
res.send('
Welcome to the Web Scraping API
');
});
app.get('/brat', async (req, res) => {
try {
const { text: q } = req.query;
if (!q) {
return res.json({
name: 'HD Bart Generator API',
message: 'Parameter text di perlukan',
version: '2.1.0',
runtime: {
os: os.type(),
platform: os.platform(),
architecture: os.arch(),
cpuCount: os.cpus().length,
uptime: `${os.uptime()} seconds`,
memoryUsage: `${Math.round((os.totalmem() - os.freemem()) / 1024 / 1024)} MB used of ${Math.round(os.totalmem() / 1024 / 1024)} MB`
}
});
}
const imageBuffer = await utils.generateBrat(q);
res.set('Content-Type', 'image/png');
res.send(imageBuffer);
} catch (error) {
console.error(error);
res.status(500).json({
status: false,
message: 'Error generating image',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
});
app.get('/screenshot', async (req, res) => {
const { url } = req.query;
if (!url) {
return res.status(400).send('URL is required');
}
try {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(url);
const screenshotBuffer = await page.screenshot();
await browser.close();
res.type('image/png').send(screenshotBuffer);
} catch (error) {
res.status(500).send('Internal Server Error');
}
});
function generateRandomString(length) {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
class MicrosoftBingAutoLogin {
constructor(bing_account, bing_password) {
console.log('Initializing auto login for Microsoft Bing ...');
this.bing_account = bing_account;
this.bing_password = bing_password;
this.init();
}
async init() {
this.browser = await chromium.launch(); // Launch browser with Playwright
}
/** Login to Microsoft Bing */
async login() {
const sig = generateRandomString(32);
const CSRFToken = generateRandomString(8) + '-' + generateRandomString(4) + '-' + generateRandomString(4) + '-' + generateRandomString(4) + '-' + generateRandomString(12);
const loginUrl = `https://login.live.com/login.srf?wa=wsignin1.0&rpsnv=13&id=264960&wreply=https%3a%2f%2fwww.bing.com%2fsecure%2fPassport.aspx%3fedge_suppress_profile_switch%3d1%26requrl%3dhttps%253a%252f%252fwww.bing.com%252fsearch%253ftoWww%253d1%2526redig%253d9220EACAFFCA40508E4E7BD52023921B%2526q%253dBing%252bAI%2526showconv%253d1%2526wlexpsignin%253d1%26sig=${sig}&wp=MBI_SSL&lc=1028&CSRFToken=${CSRFToken}&aadredir=1`;
// Open Microsoft Bing login page
const page = await this.browser.newPage();
await page.goto(loginUrl);
// Enter the Bing account and password
const accountInput = await page.$('input[name="loginfmt"]');
await accountInput.type(this.bing_account);
const passwordInput = await page.$('input[name="passwd"]');
await passwordInput.type(this.bing_password);
// Submit login form
const submitButton = await page.$('input[type="submit"]');
await submitButton.click();
// Wait for login to complete (you can adjust the wait time or use a more sophisticated wait)
await page.waitForNavigation();
}
async getCookies() {
const page = await this.browser.newPage();
await page.goto('https://bing.com/chat'); // Navigate to Bing Chat to get the cookies
const cookies = await page.cookies();
return cookies;
}
}
// Create the API route for login
app.get('/login', async (req, res) => {
const { user, pass } = req.query;
if (!user || !pass) {
return res.status(400).send('Missing username or password.');
}
try {
const bingLogin = new MicrosoftBingAutoLogin(user, pass);
await bingLogin.login(); // Perform login
const cookies = await bingLogin.getCookies(); // Get cookies after login
res.json(cookies); // Send cookies as response
} catch (error) {
res.status(500).send('Error during login: ' + error.message);
}
});
app.get('/cookie', async (req, res) => {
const { url } = req.query;
if (!url) {
return res.status(400).send('URL is required');
}
try {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(url);
const cookies = await page.context().cookies();
await browser.close();
res.json(cookies);
} catch (error) {
res.status(500).send('Internal Server Error');
}
});
// const { chromium } = require('playwright'); // Pastikan Anda sudah mengimpor Playwright
app.get('/cookie/v2', async (req, res) => {
const { url } = req.query;
if (!url) {
return res.status(400).send('URL is required');
}
try {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(url);
// Mengambil cookies
const cookies = await page.context().cookies();
// Mengambil headers
const response = await page.waitForResponse(url);
const headers = response.headers();
await browser.close();
// Menggabungkan cookies dan headers dalam satu objek
res.json({ cookies, headers });
} catch (error) {
console.error(error); // Menambahkan log untuk debugging
res.status(500).send('Internal Server Error');
}
});
app.get('/welcome', async (req, res) => {
const { name, info, desc } = req.query;
// Ensure all required query parameters are present
if (!name || !info) {
return res.status(400).json({ error: 'Missing required parameters' });
}
// Construct HTML content dynamically based on query parameters
const html = `
Course Card UI Design - #094 of #100Days100Projects
`;
try {
const browser = await chromium.launch(); // Launch Playwright Chromium browser
const page = await browser.newPage();
await page.setContent(html);
const buffer = await page.screenshot({ type: 'png' });
await browser.close();
res.set('Content-Type', 'image/png');
return res.send(buffer);
} catch (error) {
console.error('Error generating PNG:', error);
res.status(500).json({ error: 'Failed to convert HTML to PNG' });
}
});
app.get('/youtube-videos', async (req, res) => {
const channelName = req.query.name || 'YasoobKhalid'; // Default to 'YasoobKhalid' if no name is provided
const url = `https://www.youtube.com/@${channelName}/videos`;
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto(url);
const channelTitle = "Title" || await page.locator('yt-formatted-string[class*="ytd-channel-name"]').textContent();
const handle = await page.locator('yt-formatted-string#channel-handle').textContent();
const subscriberCount = await page.locator('yt-formatted-string#subscriber-count').textContent();
let lastHeight = await page.evaluate(() => {
return document.documentElement.scrollHeight;
});
const WAIT_IN_SECONDS = 5;
while (true) {
await page.evaluate('window.scrollTo(0, document.documentElement.scrollHeight)');
await page.waitForTimeout(WAIT_IN_SECONDS * 1000); // convert seconds to milliseconds
const newHeight = await page.evaluate(() => {
return document.documentElement.scrollHeight;
});
if (newHeight === lastHeight) {
break;
}
lastHeight = newHeight;
}
const videoData = await page.evaluate(() => {
const thumbnails = Array.from(document.querySelectorAll('a#thumbnail yt-image img'));
const views = Array.from(document.querySelectorAll('div#metadata-line span:nth-child(1)'));
const titles = Array.from(document.querySelectorAll('#video-title'));
const links = Array.from(document.querySelectorAll('#video-title-link'));
return titles.map((title, index) => ({
title: title.textContent.trim(),
views: views[index]?.textContent.trim(),
thumbnail: thumbnails[index]?.src,
link: links[index]?.href,
}));
});
await browser.close();
res.json({
channelTitle,
handle,
subscriberCount,
videos: videoData,
});
});
// Define regex patterns
const Patterns = {
channel: {
name: /channelMetadataRenderer\":{\"title\":\"(.*?)\"/,
id: /channelId\":\"(.*?)\"/,
verified: /"label":"Verified"/,
check_live: /{"text":"LIVE"}/,
live: /thumbnailOverlays\":\[(.*?)]/,
video_id: /videoId\":\"(.*?)\"/,
uploads: /gridVideoRenderer\":{\"videoId\":\"(.*?)\"/,
subscribers: /\"subscriberCountText\":{\"accessibility\":(.*?),/,
views: /viewCountText\":{\"simpleText\":\"(.*?)\"}/,
creation: /{\"text\":\"Joined \"},{\"text\":\"(.*?)\"}/,
country: /country\":{\"simpleText\":\"(.*?)\"}/,
custom_url: /canonicalChannelUrl\":\"(.*?)\"/,
description: /{\"description\":{\"simpleText\":\"(.*?)\"}/,
avatar: /height\":88},{\"url\":\"(.*?)\"/,
banner: /width\":1280,\"height\":351},{\"url\":\"(.*?)\"/,
playlists: /{\"url\":\"\/playlist\?list=(.*?)\"/,
video_count: /videoCountText\":{\"runs\":\[{\"text\":(.*?)}\]/,
socials: /q=https%3A%2F%2F(.*?)\"/,
upload_ids: /videoId\":\"(.*?)\"/,
stream_ids: /videoId\":\"(.*?)\"/,
upload_chunk: /gridVideoRenderer\":{(.*?)\"navigationEndpoint/,
upload_chunk_fl_1: /simpleText\":\"Streamed/,
upload_chunk_fl_2: /default_live./,
upcoming_check: /\"title\":\"Upcoming live streams\"/,
upcoming: /gridVideoRenderer\":{\"videoId\":\"(.*?)\"/,
},
video: {
video_id: /videoId\":\"(.*?)\"/,
title: /title\":\"(.*?)\"/,
duration: /approxDurationMs\":\"(.*?)\"/,
upload_date: /uploadDate\":\"(.*?)\"/,
author_id: /channelIds\":\[\"(.*?)\"/,
description: /shortDescription\":\"(.*)\",\"isCrawlable/,
tags: //,
is_streamed: /simpleText\":\"Streamed live/,
is_premiered: /dateText\":{\"simpleText\":\"Premiered/,
views: /videoViewCountRenderer\":{\"viewCount\":{\"simpleText\":\"(.*?)\"/,
likes: /toggledText\":{\"accessibility\":{\"accessibilityData\":{\"label\":\"(.*?) /,
thumbnail: /playerMicroformatRenderer\":{\"thumbnail\":{\"thumbnails\":\[{\"url\":\"(.*?)\"/,
},
playlist: {
name: /{\"title\":\"(.*?)\"/,
video_count: /stats\":\[{\"runs\":\[{\"text\":\"(.*?)\"/,
video_id: /videoId\":\"(.*?)\"/,
thumbnail: /og:image\" content=\"(.*?)\?"/,
},
extra: {
video_id: /videoId\":\"(.*?)\"/,
},
query: {
channel_id: /channelId\":\"(.*?)\"/,
video_id: /videoId\":\"(.*?)\"/,
playlist_id: /playlistId\":\"(.*?)\"/,
},
};
// Utility function to match patterns
const matchPattern = (pattern, data) => {
const matches = [];
let match;
while ((match = pattern.exec(data)) !== null) {
matches.push(match[1] || match[0]);
}
return matches;
};
// Fetch YouTube channel data by name
const fetchChannelData = async (channelName) => {
try {
const url = `https://www.youtube.com/@${channelName}/videos`;
const response = await axios.get(url);
return response.data; // return raw HTML content for pattern matching
} catch (error) {
throw new Error('Error fetching YouTube channel data: ' + error.message);
}
};
// API Endpoint
app.get('/youtube-info', async (req, res) => {
const { name } = req.query; // Get channel name from query parameter
if (!name) {
return res.status(400).json({ error: 'Channel name is required' });
}
try {
const data = await fetchChannelData(name); // Fetch the page content from YouTube
const results = {};
// Apply patterns for channel data extraction
Object.keys(Patterns.channel).forEach((key) => {
const pattern = Patterns.channel[key];
results[key] = matchPattern(pattern, data);
});
res.json({ channelName: name, data: results });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
const playwright = {
avLang: ['javascript', 'python', 'java', 'csharp'],
request: async function(language = 'javascript', code) {
if (!this.avLang.includes(language.toLowerCase())) {
throw new Error(`Language "${language}" is not supported. Choose from available languages: ${this.avLang.join(', ')}`);
}
const url = 'https://try.playwright.tech/service/control/run';
const headers = {
'authority': 'try.playwright.tech',
'accept': '*/*',
'content-type': 'application/json',
'origin': 'https://try.playwright.tech',
'referer': 'https://try.playwright.tech/?l=playwright-test',
'user-agent': 'Postify/1.0.0',
};
const data = {
code: code,
language: language
};
try {
const response = await axios.post(url, data, { headers });
const { success, error, version, duration, output, files } = response.data;
return { success, error, version, duration, output, files };
} catch (error) {
if (error.response) {
const { success, error: errMsg, version, duration, output, files } = error.response.data;
return { success, error: errMsg, version, duration, output, files };
} else {
throw new Error(error.message);
}
}
}
};
app.get('/view', async (req, res) => {
const { url, count } = req.query;
if (!url || !count) {
return res.status(400).json({ error: 'Missing required parameters: url and count' });
}
const language = 'javascript';
const code = `
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
const targetUrl = '${url}';
for (let i = 0; i < ${count}; i++) {
await page.goto(targetUrl);
console.log(\`View \${i + 1}: \${targetUrl}\`);
await page.waitForTimeout(3000); // Delay for 3 seconds before next view
}
await browser.close();
})();
`;
try {
const data = await playwright.request(language, code);
return res.status(200).json(data);
} catch (error) {
console.error('Error:', error);
return res.status(500).json({ error: error.message });
}
})
const font = 'BlueArchive';
const crossBuffer = Buffer.from('');
const haloBuffer = Buffer.from('');
const splitText = (text) => {
if (Array.isArray(text)) return text;
if (text.includes(' ')) {
return text.split(' ').filter(i => i.trim());
} else if (text.match(/^[A-Z][a-z]*[A-Z][a-z]*$/)) {
return text.replace(/[A-Z]/g, t => ' ' + t).trim().split(' ');
} else {
const h = Math.floor(text.length / 2);
return [text.substring(0, h), text.substring(h)];
}
};
const baLogo = async (text, left = 0) => {
const [head, tail] = splitText(text);
if (!head || !tail) throw new Error('Invalid input text');
let width = 32, height = 260;
const top = 208;
const matrix = [[1, -0.35], [0, 1]];
const comps = [];
const headPart = sharp({
text: {
font,
text: `${head}`,
dpi: 72,
rgba: true,
}
}).affine(matrix, {
background: '#fff0',
interpolator: sharp.interpolators.nohalo
}).png();
const headMeta = await headPart.metadata();
const w = width + headMeta.width - 162;
const dl = w < 0 ? 0 : w + left;
const tailPart = sharp({
text: {
font,
text: `${head}${tail}`,
dpi: 72,
rgba: true,
}
}).affine(matrix, {
background: '#fff0',
interpolator: sharp.interpolators.nohalo
}).png();
const tailMeta = await tailPart.metadata();
comps.push({
input: await tailPart.toBuffer(),
left: width,
top,
});
comps.push({
input: crossBuffer,
left: dl + 4,
top: 4,
});
width += (tailMeta.width < 256 ? 256 : tailMeta.width ) + 64;
height += 144;
if (width < 500) width = 500;
return sharp({
create: {
width, height,
channels: 4,
background: '#fff',
},
}).composite(comps).png();
};
app.get('/balogo', async (req, res) => {
try {
const { text, text2 } = req.query;
if (!text) return res.status(400).send('Text is required');
const logoImage = await baLogo(text);
res.set('Content-Type', 'image/png');
res.send(await logoImage.toBuffer());
} catch (error) {
res.status(500).send('Error generating logo: ' + error.message);
}
});
async function baLogov2(textL = "蔚蓝", textR = "档案", x = "-15", y = "0", tp = false) {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
});
const page = await context.newPage();
await page.goto('https://symbolon.pages.dev/');
await page.waitForSelector('#canvas');
await page.fill('#textL', textL);
await page.fill('#textR', textR);
await page.fill('#graphX', x);
await page.fill('#graphY', y);
await page.waitForTimeout(500);
const imageBuffer = await page.$eval('#canvas', (canvas) => {
return canvas.toDataURL('image/png').split(',')[1];
});
const buffer = Buffer.from(imageBuffer, 'base64');
await browser.close();
return buffer;
}
app.get('/balogo/v2', async (req, res) => {
try {
const { textL = "蔚蓝", textR = "档案", x = "-15", y = "0", tp = "false" } = req.query;
const tpBool = tp === "true";
const imageBuffer = await baLogov2(textL, textR, x, y, tpBool);
res.setHeader('Content-Type', 'image/png');
res.send(imageBuffer);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Error generating logo" });
}
});
async function baLogov3(textL = "蔚蓝", textR = "档案") {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
});
const page = await context.newPage();
await page.goto('https://appleneko2001-bluearchive-logo.vercel.app/');
try {
await page.waitForSelector('#canvas', { timeout: 30000 });
} catch (err) {
console.error('Canvas tidak ditemukan:', err);
}
try {
await page.waitForSelector('#textL', { state: 'visible', timeout: 10000 });
await page.fill('#textL', textL);
} catch (err) {
console.error('Elemen #textL gagal diisi:', err);
}
try {
await page.waitForSelector('#textR', { state: 'visible', timeout: 10000 });
await page.fill('#textR', textR);
} catch (err) {
console.error('Elemen #textR gagal diisi:', err);
}
await page.waitForTimeout(2000);
const imageBuffer = await page.$eval('#canvas', (canvas) => {
return canvas.toDataURL('image/png').split(',')[1];
});
const buffer = Buffer.from(imageBuffer, 'base64');
await browser.close();
return buffer;
}
app.get('/balogo/v3', async (req, res) => {
try {
const { textL = "蔚蓝", textR = "档案" } = req.query;
const imageBuffer = await baLogov3(textL, textR);
res.setHeader('Content-Type', 'image/png');
res.send(imageBuffer);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Error generating logo" });
}
});
async function baLogov4(textL = "蔚蓝", textR = "档案") {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
});
const page = await context.newPage();
await page.goto('https://ba.api.hli.icu/');
try {
await page.waitForSelector('#canvas', { timeout: 30000 });
} catch (err) {
console.error('Canvas tidak ditemukan:', err);
}
try {
await page.waitForSelector('#textL', { state: 'visible', timeout: 10000 });
await page.fill('#textL', textL);
} catch (err) {
console.error('Elemen #textL gagal diisi:', err);
}
try {
await page.waitForSelector('#textR', { state: 'visible', timeout: 10000 });
await page.fill('#textR', textR);
} catch (err) {
console.error('Elemen #textR gagal diisi:', err);
}
await page.waitForTimeout(500);
const imageBuffer = await page.$eval('#canvas', (canvas) => {
return canvas.toDataURL('image/png').split(',')[1];
});
const buffer = Buffer.from(imageBuffer, 'base64');
await browser.close();
return buffer;
}
app.get('/balogo/v4', async (req, res) => {
try {
const { textL = "蔚蓝", textR = "档案" } = req.query;
const imageBuffer = await baLogov4(textL, textR);
res.setHeader('Content-Type', 'image/png');
res.send(imageBuffer);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Error generating logo" });
}
});
app.get('/rayso', async (req, res) => {
const { code, title = 'app.js', theme = 'supabase', language = '', darkMode = 'true', background = 'false' } = req.query;
if (!code)
return res.status(400).json({ error: 'Parameter "code" (Base64 encoded) diperlukan' });
try {
const encodedCode = code.toString('base64');
const url = `https://www.ray.so/#code=${encodedCode}&title=${title}&theme=${theme}&language=${language}&background=${background}&darkMode=${darkMode}`;
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
});
const page = await context.newPage();
await page.goto(url);
await page.waitForSelector('.Frame_frame__rcr69');
const elementHandle = await page.$('.Frame_frame__rcr69');
const screenshotBuffer = await elementHandle.screenshot({ fullPage: true });
await browser.close();
res.setHeader('Content-Type', 'image/png');
return res.status(200).end(screenshotBuffer);
} catch (error) {
return res.status(500).json({ error: 'Gagal mengambil screenshot', details: error.message });
}
});
app.get('/carbon', async (req, res) => {
const { code, theme } = req.query;
if (!code) return res.status(400).json({ error: 'Parameter "code" diperlukan.' });
if (!theme) return res.status(400).json({ error: 'Parameter "theme" diperlukan.' });
try {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
acceptDownloads: true
});
const page = await context.newPage();
await page.goto('https://carbon.now.sh/');
await page.click('input[aria-labelledby="theme-dropdown"]');
await page.keyboard.type(theme);
await page.keyboard.press('Enter');
await page.click('pre.CodeMirror-line span[role="presentation"]');
await page.keyboard.press('Control+A');
await page.keyboard.press('Backspace');
await page.keyboard.type(code);
await page.waitForSelector('button[data-cy="quick-export-button"]');
const [download] = await Promise.all([
page.waitForEvent('download'),
page.click('button[data-cy="quick-export-button"]')
]);
const downloadPath = await download.path();
res.setHeader('Content-Type', 'application/octet-stream');
return res.status(200).sendFile(downloadPath);
} catch (error) {
return res.status(500).json({ error: 'Gagal memproses permintaan.', details: error.message });
} finally {
await browser.close();
}
});
app.get('/recoded', async (req, res) => {
const { code, colors, font, lang, bg } = req.query;
if (!code) return res.status(400).json({ error: 'Parameter "code" diperlukan.' });
if (!colors) return res.status(400).json({ error: 'Parameter "colors" diperlukan.' });
if (!font) return res.status(400).json({ error: 'Parameter "font" diperlukan.' });
if (!lang) return res.status(400).json({ error: 'Parameter "lang" diperlukan.' });
if (!bg) return res.status(400).json({ error: 'Parameter "bg" diperlukan.' });
try {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
acceptDownloads: true,
});
const page = await context.newPage();
await page.goto('https://recoded.netlify.app/');
await page.fill('textarea.npm__react-simple-code-editor__textarea', code);
await page.click('div.input-box[style*="120px"]:has-text("VS Code Dark")');
await page.keyboard.type(colors);
await page.keyboard.press('Enter');
await page.click('div[data-testid="font-select"]');
await page.keyboard.type(font);
await page.keyboard.press('Enter');
await page.click('div[data-testid="language-select"]');
await page.keyboard.type(lang);
await page.keyboard.press('Enter');
await page.click('div[data-testid="background-color-select"]');
await page.keyboard.type(bg);
await page.keyboard.press('Enter');
const [download] = await Promise.all([
page.waitForEvent('download'),
page.click('button.button.export')
]);
const downloadPath = await download.path();
res.setHeader('Content-Type', 'image/png');
return res.status(200).send(downloadPath);
} catch (error) {
return res.status(500).json({ error: 'Gagal memproses permintaan.', details: error.message });
} finally {
await browser.close();
}
});
app.get('/chalkist', async (req, res) => {
const { code, title } = req.query;
if (!code) return res.status(400).json({ error: 'Parameter "code" diperlukan.' });
if (!title) return res.status(400).json({ error: 'Parameter "title" diperlukan.' });
let browser;
try {
browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
});
const page = await context.newPage();
await page.goto('https://chalk.ist/');
// Isi kolom judul
const titleSelector = 'div[data-placeholder="Untitled..."]';
await page.focus(titleSelector);
await page.keyboard.type(title);
// Isi kolom kode
const codeSelector = 'textarea.editor.font-config';
await page.fill(codeSelector, code);
// Tunggu elemen muncul untuk screenshot
const screenshotSelector = 'div[data-editor-frame]';
await page.waitForSelector(screenshotSelector);
// Ambil screenshot elemen
const element = await page.$(screenshotSelector);
const screenshotBuffer = await element.screenshot();
res.setHeader('Content-Type', 'image/png');
res.status(200).send(screenshotBuffer);
} catch (error) {
console.error('Error:', error);
res.status(500).json({ error: 'Gagal memproses permintaan.', details: error.message });
} finally {
if (browser) await browser.close();
}
});
app.get('/brat/v2', async (req, res) => {
const { text } = req.query;
if (!text) return res.status(400).json({ error: 'Parameter "text" diperlukan.' });
try {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
acceptDownloads: true,
});
const page = await context.newPage();
await page.goto('https://brat-generator.net/');
await page.fill('input[class="w-full p-3 text-base border border-gray-200 rounded-lg mb-5 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-colors"]', text);
try {
await page.waitForSelector('button[class="px-5 py-3 text-sm font-medium rounded-lg flex items-center justify-between flex-1 transition-all bg-white border-2 border-blue-500 text-blue-600"]', { visible: true });
await page.click('button[class="px-5 py-3 text-sm font-medium rounded-lg flex items-center justify-between flex-1 transition-all bg-white border-2 border-blue-500 text-blue-600"]');
} catch (error) {
console.log("Tombol 'White Background' tidak ditemukan atau tidak terlihat, melewati langkah ini.");
}
try {
await page.waitForSelector('button[class="w-full mt-5 px-5 py-3 text-sm font-medium rounded-lg transition-all bg-blue-500 text-white hover:bg-blue-600"]', { visible: true });
await page.click('button[class="w-full mt-5 px-5 py-3 text-sm font-medium rounded-lg transition-all bg-blue-500 text-white hover:bg-blue-600"]');
} catch (error) {
console.log("Tombol 'Download Image' tidak ditemukan atau tidak terlihat, melewati langkah ini.");
}
await page.waitForSelector('canvas[class="absolute top-0 left-0 w-full h-full bg-white shadow-inner"]', { visible: true });
await page.waitForTimeout(800);
const canvas = await page.$('canvas[class="absolute top-0 left-0 w-full h-full bg-white shadow-inner"]');
const screenshot = await canvas.screenshot();
res.setHeader('Content-Type', 'image/png');
res.status(200).send(screenshot);
} catch (error) {
return res.status(500).json({ error: 'Gagal memproses permintaan.', details: error.message });
} finally {
await browser.close();
}
});
const getRandomName = () => {
const names = ['wudy', 'andi', 'budi', 'citra', 'dina'];
return names[Math.floor(Math.random() * names.length)];
};
const getRandomClass = () => {
const classes = ['A', 'B', 'C', 'D'];
return classes[Math.floor(Math.random() * classes.length)];
};
const getRandomText = () => {
const texts = ['halo', 'selamat pagi', 'apa kabar?', 'siang', 'malam'];
return texts[Math.floor(Math.random() * texts.length)];
};
const getRandomType = () => {
return Math.floor(Math.random() * 14) + 1; // generates a random number between 1 and 20
};
const getRandomDay = () => {
const days = ['senin', 'selasa', 'rabu', 'kamis', 'jumat', 'sabtu', 'minggu'];
return days[Math.floor(Math.random() * days.length)];
};
const getRandomYear = () => {
const currentYear = new Date().getFullYear();
return Math.floor(Math.random() * (currentYear - 2000 + 1)) + 2000; // generates a random year between 2000 and current year
};
app.get('/nulis', async (req, res) => {
try {
const {
waktu = (getRandomYear()).toString(),
hari = (getRandomDay()).toString(),
nama = (getRandomName()).toString(),
kelas = (getRandomClass()).toString(),
text = (getRandomText()).toString(),
type = (getRandomType()).toString()
} = req.query;
const diNama3 = nama;
const diKelas3 = kelas;
const diTulis9 = text;
const panjangKalimat9 = diTulis9.replace(/(\S+\s*){1,10}/g, '$&\n');
const panjangNama3 = diNama3.replace(/(\S+\s*){1,10}/g, '$&\n');
const panjangKelas3 = diKelas3.replace(/(\S+\s*){1,10}/g, '$&\n');
const panjangBaris9 = panjangKalimat9.split('\n').slice(0, 30).join('\n');
const panjangBarisNama3 = panjangNama3.split('\n').slice(0, 30).join('\n');
const panjangBarisKelas3 = panjangKelas3.split('\n').slice(0, 30).join('\n');
const months = ['- 1 -', '- 2 -', '- 3 -', '- 4 -', '- 5 -', '- 6 -', '- 7 -', '- 8 -', '- 9 -', '- 10 -', '- 11 -', '- 12 -'];
const myDays = ['Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu'];
const date = new Date();
const day = date.getDate();
const month = date.getMonth();
const thisDay = myDays[date.getDay()];
const year = date.getFullYear();
const waktu6 = `${day} ${months[month]} ${year}`;
const hari6 = thisDay;
const inputImagePath = path.join(process.cwd(), 'magernulis1.jpg');
const fontPath = path.join(process.cwd(), 'Zahraaa.ttf');
let theme = null;
if (type === '1') {
theme = [
inputImagePath,
'-font', fontPath,
'-fill', '#8c1a00',
'-size', '1024x784',
'-pointsize', '20',
'-interline-spacing', '1',
'-annotate', '+806+78', hari6,
'-annotate', '+806+102', waktu6,
'-annotate', '+360+100', panjangBarisNama3,
'-annotate', '+360+120', panjangBarisKelas3,
'-annotate', '+344+142', panjangBaris9,
'png:-'
];
}
if (type === '2') {
theme = [
inputImagePath,
'-font', fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'-7.5',
'-annotate',
'+344+142',
panjangBaris9,
'png:-'
]
}
if (type === '3') {
theme = [
inputImagePath,
'-fill',
'#001675',
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'-7.5',
'-annotate',
'+344+142',
panjangKalimat9,
'png:-'
]
}
if (type === '4') {
theme = [
inputImagePath,
'-fill',
'#8c1a00',
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'-7.5',
'-annotate',
'+344+142',
panjangKalimat9,
'png:-'
]
}
if (type === '5') {
theme = [
inputImagePath,
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'1',
'-annotate',
'+806+78',
hari,
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+806+102',
waktu,
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'-7.5',
'-annotate',
'+344+142',
panjangKalimat9,
'png:-'
]
}
if (type === '6') {
theme = [
inputImagePath,
'-fill',
'#001675',
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'1',
'-annotate',
'+806+78',
hari,
'-fill',
'#001675',
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+806+102',
waktu,
'-fill',
'#001675',
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'-7.5',
'-annotate',
'+344+142',
panjangKalimat9,
'png:-'
]
}
if (type === '7') {
theme = [
inputImagePath,
'-fill',
'#8c1a00',
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'1',
'-annotate',
'+806+78',
hari,
'-fill',
'#8c1a00',
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+806+102',
waktu,
'-fill',
'#8c1a00',
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'-7.5',
'-annotate',
'+344+142',
panjangKalimat9,
'png:-'
]
}
if (type === '8') {
theme = [
inputImagePath,
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'1',
'-annotate',
'+806+78',
hari,
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+806+102',
waktu,
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+360+100',
nama,
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+360+120',
kelas,
'-font',
fontPath,
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'-7.5',
'-annotate',
'+344+142',
panjangKalimat9,
'png:-'
]
}
if (type === '9') {
theme = [
inputImagePath,
'-font',
fontPath,
'-fill',
'#001675',
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'1',
'-annotate',
'+806+78',
hari,
'-font',
fontPath,
'-fill',
'#001675',
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+806+102',
waktu,
'-font',
fontPath,
'-fill',
'#001675',
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+360+100',
nama,
'-font',
fontPath,
'-fill',
'#001675',
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+360+120',
kelas,
'-font',
fontPath,
'-fill',
'#001675',
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'-7.5',
'-annotate',
'+344+142',
panjangKalimat9,
'png:-'
];
}
if (type === '10') {
theme = [
inputImagePath,
'-font',
fontPath,
'-fill',
'#8c1a00',
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'1',
'-annotate',
'+806+78',
hari,
'-font',
fontPath,
'-fill',
'#8c1a00',
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+806+102',
waktu,
'-font',
fontPath,
'-fill',
'#8c1a00',
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+360+100',
nama,
'-font',
fontPath,
'-fill',
'#8c1a00',
'-size',
'1024x784',
'-pointsize',
'18',
'-interline-spacing',
'1',
'-annotate',
'+360+120',
kelas,
'-font',
fontPath,
'-fill',
'#8c1a00',
'-size',
'1024x784',
'-pointsize',
'20',
'-interline-spacing',
'-7.5',
'-annotate',
'+344+142',
panjangKalimat9,
'png:-'
]
}
const splitText = text.replace(/(\S+\s*){1,9}/g, '$&\n')
const fixHeight = splitText.split('\n').slice(0, 31).join('\n')
const sebelumkiri = path.join(process.cwd(), 'sebelumkiri.jpg');
const sebelumkanan = path.join(process.cwd(), 'sebelumkanan.jpg');
const foliokanan = path.join(process.cwd(), 'foliokanan.jpg');
const foliokiri = path.join(process.cwd(), 'foliokiri.jpg');
const fontPathB = path.join(process.cwd(), 'Indie-Flower.ttf');
if (type === '11') {
theme = [
sebelumkiri,
'-font',
fontPathB,
'-size',
'960x1280',
'-pointsize',
'22',
'-interline-spacing',
'2',
'-annotate',
'+140+153',
fixHeight,
'png:-'
];
}
if (type === '12') {
theme = [
sebelumkanan,
'-font',
fontPathB,
'-size',
'960x1280',
'-pointsize',
'23',
'-interline-spacing',
'2',
'-annotate',
'+128+129',
fixHeight,
'png:-'
];
}
if (type === '13') {
theme = [
foliokanan,
'-font',
fontPathB,
'-size',
'960x1280',
'-pointsize',
'23',
'-interline-spacing',
'3',
'-annotate',
'+89+190',
fixHeight,
'png:-'
];
}
if (type === '14') {
theme = [
foliokiri,
'-font',
fontPathB,
'-size',
'1720x1280',
'-pointsize',
'23',
'-interline-spacing',
'4',
'-annotate',
'+48+185',
fixHeight,
'png:-'
];
}
const convert = spawn('convert', theme);
const collectImageData = () => {
return new Promise((resolve, reject) => {
let imageData = Buffer.alloc(0);
convert.stdout.on('data', (data) => {
imageData = Buffer.concat([imageData, data]);
});
convert.on('close', (code) => {
if (code !== 0) {
return reject(new Error(`ImageMagick exited with code ${code}`));
}
resolve(imageData);
});
convert.on('error', (err) => {
reject(err);
});
});
};
const imageData = await collectImageData();
res.set('Content-Type', 'image/png');
res.send(imageData);
convert.kill('SIGTERM');
} catch (err) {
console.error(err);
res.status(500).json({ error: 'Terjadi kesalahan server.' });
}
});
Readable.fromEventEmitter = function (emitter, events) {
const readable = new Readable({
read() {}
});
const onData = (data) => {
readable.push(data);
};
const onEnd = () => {
readable.push(null);
};
const onError = (err) => {
readable.emit('error', err);
};
emitter.on(events[0], onData);
emitter.on(events[1], onEnd);
emitter.on(events[2], onError);
return readable;
};
const iask = {
turndownService: new TurndownService(),
request(query, mode, options) {
if (typeof query === 'object') {
return query;
}
return { q: query, mode, ...options };
},
eventx(query) {
const pipe = new EventEmitter();
const getQueryString = () => {
const params = new URLSearchParams(query);
return params.toString();
};
return { query, pipe, getQueryString };
},
parseChunk(message) {
try {
const data = JSON.parse(message);
const diff = data.pop();
let content = '';
let stop = false;
if (diff?.e?.[0]?.[1]?.data) {
content = diff.e[0][1].data.replace(/
/g, '\n');
console.log(content);
}
if (diff?.response?.rendered?.[2]?.[1]?.[4]?.[4]) {
content = this.turndownService.turndown(diff.response.rendered[2][1][4][4]);
stop = true;
console.log(content);
}
return { content, stop };
} catch (error) {
console.error(error);
return { content: '', stop: true };
}
},
inspect(response) {
const $ = cheerio.load(response.data);
const phxElement = $('[id^="phx-"]').first();
const joinMessage = JSON.stringify([
null,
null,
`lv:${phxElement.attr('id')}`,
'phx_join',
{
url: response.request.res.responseUrl,
session: phxElement.attr('data-phx-session'),
},
]);
const csrfToken = $('meta[name="csrf-token"]').attr('content');
return { joinMessage, csrfToken };
},
async cws(queryString, jar) {
const client = wrapper(axios.create({ jar }));
try {
const response = await client.get(`https://iask.ai?${queryString}`);
const { joinMessage, csrfToken } = this.inspect(response);
const cookies = await jar.getCookieString('https://iask.ai');
console.log(cookies);
const ws = new WebSocket(`wss://iask.ai/live/websocket?_csrf_token=${csrfToken}&vsn=2.0.0`, {
headers: {
'Cookie': cookies
}
});
await new Promise((resolve, reject) => {
ws.on('open', () => {
console.log('Websocket berhasil terhubung...');
ws.send(joinMessage);
resolve();
});
ws.on('error', (err) => {
console.error('Tidak dapat terhubung ke WebSocket:', err);
reject(err);
});
});
return ws;
} catch (error) {
console.error(error);
throw error;
}
},
async handleJoin(event) {
try {
const jar = new CookieJar();
const ws = await this.cws(event.getQueryString(), jar);
const pipe = event.pipe;
ws.on('message', (message) => {
console.log(message.toString());
const { content, stop } = this.parseChunk(message.toString());
if (content !== '') {
pipe.emit('data', content);
}
if (stop) {
pipe.emit('end');
ws.close();
}
});
ws.on('close', () => {
console.log('Websocket terputus...');
pipe.emit('end');
});
ws.on('error', (err) => {
console.error(err);
pipe.emit('error', err);
});
} catch (error) {
console.error(error);
event.pipe.emit('error', error);
}
},
dispatcher: new EventEmitter(),
setupDispatcher() {
this.dispatcher.on('JoinEvent', (event) => this.handleJoin(event));
},
ask: async (query, mode = 'question', options = {}) => {
const summon = iask.request(query, mode, options);
const event = iask.eventx(summon);
iask.dispatcher.emit('JoinEvent', event);
return Readable.fromEventEmitter(event.pipe, ['data', 'end', 'error']);
},
init() {
this.setupDispatcher();
}
};
async function Ask(query, mode = 'question', options = { detail_level: 'detailed' }) {
try {
iask.init();
const stream = await iask.ask(query, mode, options);
// Return a Promise to properly handle stream events
return new Promise((resolve, reject) => {
let result = '';
stream.on('data', (chunk) => {
result += chunk;
});
stream.on('end', () => {
console.log('Permintaan ke Websocket iASK berhasil..');
console.log('Result:', result);
resolve({ result }); // Resolve with the accumulated result
});
stream.on('error', (err) => {
console.error(err);
reject({ err }); // Reject on error
});
});
} catch (error) {
console.error(error);
throw error; // Re-throw error to ensure it's caught in the calling context
}
}
app.post('/ask', async (req, res) => {
const { query, mode = 'question', ...options } = req.body;
if (!query) {
return res.status(400).json({ error: 'Query parameter is required' });
}
try {
const result = await Ask(query, mode, options);
// Send response as JSON
return res.status(200).json(result);
} catch (error) {
console.error(error);
return res.status(500).json({ error: 'Failed to handle the query' });
}
});
app.get('/ask', async (req, res) => {
const { query, mode = 'question', ...options } = req.query;
if (!query) {
return res.status(400).json({ error: 'Query parameter is required' });
}
try {
const result = await Ask(query, mode, options);
// Send response as JSON
return res.status(200).json(result);
} catch (error) {
console.error(error);
return res.status(500).json({ error: 'Failed to handle the query' });
}
});
app.post("/playwright", async (req, res) => {
const { code, timeout = 300000 } = req.body;
if (!code) return res.status(400).json({ error: "Kode tidak boleh kosong" });
let output = [];
const originalLog = console.log;
console.log = (...args) => {
const message = args.map(arg => (typeof arg === "object" ? JSON.stringify(arg) : arg)).join(" ");
output.push(message);
originalLog.apply(console, args);
};
const vm = new NodeVM({
console: "inherit",
sandbox: {},
require: {
external: true,
builtin: ["fs", "path"],
root: "./",
mock: {
playwright: { chromium },
},
},
});
const script = `
module.exports = async () => {
${code}
};
`;
let runCode;
try {
runCode = vm.run(script, "sandbox.js");
} catch (error) {
console.log = originalLog;
return res.status(500).json({ error: "Gagal menjalankan kode", details: error.message });
}
try {
await runCode();
const startTime = Date.now();
while (output.length === 0 && Date.now() - startTime < timeout) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
const result = output.length > 0 ? output.pop() : "Tidak ada hasil yang ditemukan.";
console.log = originalLog;
res.json({ output: result });
} catch (err) {
console.log = originalLog;
res.status(500).json({ error: "Kesalahan saat menjalankan kode", details: err.message });
}
});
app.post("/playwright/v2", async (req, res) => {
const { code, timeout = 300000 } = req.body;
if (!code) return res.status(400).json({ error: "Kode tidak boleh kosong" });
let output = [];
const originalLog = console.log;
console.log = (...args) => {
const message = args.map(arg => (typeof arg === "object" ? JSON.stringify(arg) : arg)).join(" ");
output.push(message);
originalLog.apply(console, args);
};
let runCode;
try {
// Menggunakan eval untuk mengeksekusi kode
runCode = eval(`
(async () => {
${code}
})();
`);
} catch (error) {
console.log = originalLog;
return res.status(500).json({ error: "Gagal menjalankan kode", details: error.message });
}
try {
await runCode;
const startTime = Date.now();
while (output.length === 0 && Date.now() - startTime < timeout) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
const result = output.length > 0 ? output.pop() : "Tidak ada hasil yang ditemukan.";
console.log = originalLog;
res.json({ output: result });
} catch (err) {
console.log = originalLog;
res.status(500).json({ error: "Kesalahan saat menjalankan kode", details: err.message });
}
});
app.post('/compile', async (req, res) => {
const { code, language } = req.body;
try {
const output = await CompileFile(language, code);
// Extract stdout from the output object
const stdout = output.stdout || '';
res.json({ output: stdout });
} catch (error) {
res.status(500).json({ error: error.toString() });
}
});
class ColorifyAI {
constructor() {
this.ws = null;
this.sessionHash = this.generateHash();
}
generateHash() {
return crypto.randomBytes(8).toString('hex');
}
async imageToBase64(imageUrl = "https://i.pinimg.com/236x/21/81/c4/2181c4e2d51db79bb2ac000dcac2df90.jpg") {
try {
const res = await axios.get(imageUrl, { responseType: 'arraybuffer' });
return `data:image/webp;base64,${Buffer.from(res.data).toString('base64')}`;
} catch (error) {
console.error('Error converting image to base64:', error);
throw error;
}
}
async start(options) {
return new Promise((resolve, reject) => {
let wsUrl = "";
if (options.type === "img2color") {
wsUrl = "wss://colorifyai.art/demo-auto-coloring/queue/join";
} else if (options.type === "txt2img") {
wsUrl = "wss://colorifyai.art/demo-colorify-text2img/queue/join";
} else if (options.type === "img2img") {
wsUrl = "wss://colorifyai.art/demo-colorify-img2img/queue/join";
} else {
return reject(new Error("Invalid type. Use 'img2color', 'txt2img', or 'img2img'."));
}
this.ws = new WebSocket(wsUrl, {
headers: {
"Upgrade": "websocket",
"Origin": "https://colorifyai.art",
"Cache-Control": "no-cache",
"Accept-Language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7",
"Pragma": "no-cache",
"Connection": "Upgrade",
"Sec-WebSocket-Key": crypto.randomBytes(16).toString("base64"),
"User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36",
"Sec-WebSocket-Version": "13",
"Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits",
"Accept": "application/json, text/plain, */*",
"Referer": "https://colorifyai.art",
}
});
this.ws.on("open", () => {
console.log("Connected to WebSocket, waiting for send_hash...");
});
this.ws.on("message", async (data) => {
const response = JSON.parse(data.toString());
if (response.msg === "send_hash") {
console.log("Sending session_hash...");
this.ws.send(JSON.stringify({ session_hash: this.sessionHash }));
}
if (response.msg === "send_data") {
console.log("Sending data...");
try {
let requestData = {};
if (options.type === "img2color" || options.type === "img2img") {
const base64Image = await this.imageToBase64(options.imageUrl);
requestData = {
data: {
source_image: base64Image,
prompt: options.prompt || "(masterpiece), best quality",
request_from: 10
}
};
} else {
requestData = {
data: {
prompt: options.prompt,
style: options.style || "default",
aspect_ratio: options.aspectRatio || "9:16",
request_from: 10
}
};
}
this.ws.send(JSON.stringify(requestData));
} catch (err) {
reject(err);
}
}
if (response.msg === "process_completed") {
console.log("Process completed:", response);
resolve({
baseUrl: 'https://temp.colorifyai.art',
...(typeof response.output === 'object' && response.output !== null ? response.output : {})
});
this.ws.close();
}
});
this.ws.on("error", (error) => {
console.error("WebSocket Error:", error);
reject(error);
});
this.ws.on("close", () => {
console.log("WebSocket closed");
});
});
}
}
// Handle POST request to /colorify
app.post('/colorifyai', async (req, res) => {
const params = req.body;
const validTypes = ["img2color", "txt2img", "img2img"];
if (!params.type || !validTypes.includes(params.type.toLowerCase())) {
return res.status(400).json({ error: "Invalid type. Allowed types: img2color, txt2img, img2img" });
}
const ai = new ColorifyAI();
try {
const data = await ai.start(params);
return res.status(200).json(data);
} catch (error) {
return res.status(500).json({ error: "Error during WebSocket request", details: error.message });
}
});
// Handle GET request to /colorify
app.get('/colorifyai', async (req, res) => {
const params = req.query;
const validTypes = ["img2color", "txt2img", "img2img"];
if (!params.type || !validTypes.includes(params.type.toLowerCase())) {
return res.status(400).json({ error: "Invalid type. Allowed types: img2color, txt2img, img2img" });
}
const ai = new ColorifyAI();
try {
const data = await ai.start(params);
return res.status(200).json(data);
} catch (error) {
return res.status(500).json({ error: "Error during WebSocket request", details: error.message });
}
});
const PORT = process.env.PORT || 7860;
app.listen(PORT, async () => {
console.log(`Server running on port ${PORT}`);
await utils.initialize();
});
process.on('SIGINT', async () => {
await utils.close();
process.exit(0);
});