Spaces:
Paused
Paused
| import express from 'express'; | |
| import { chromium } from 'playwright-core'; | |
| import cors from 'cors'; | |
| import { solve } from './solver.js'; | |
| const app = express(); | |
| const PORT = process.env.PORT || 7860; | |
| app.use(cors()); | |
| app.use(express.json()); | |
| app.get('/', (req, res) => { | |
| res.json({ | |
| status: 'ok', | |
| message: 'reCAPTCHA Solver API is running', | |
| endpoints: { | |
| solve: '/api/solve?url=YOUR_URL', | |
| health: '/health' | |
| } | |
| }); | |
| }); | |
| app.get('/health', (req, res) => { | |
| res.json({ status: 'healthy' }); | |
| }); | |
| app.get('/api/solve', async (req, res) => { | |
| const { url } = req.query; | |
| if (!url) { | |
| return res.status(400).json({ | |
| error: 'Missing required parameter', | |
| message: 'Please provide a URL parameter' | |
| }); | |
| } | |
| let browser; | |
| const startTime = Date.now(); | |
| try { | |
| console.log(`[API] Starting to solve reCAPTCHA for: ${url}`); | |
| browser = await chromium.launch({ | |
| headless: true, | |
| args: [ | |
| '--no-sandbox', | |
| '--disable-setuid-sandbox', | |
| '--disable-dev-shm-usage', | |
| '--disable-gpu', | |
| '--disable-software-rasterizer', | |
| '--disable-extensions', | |
| '--disable-blink-features=AutomationControlled' | |
| ], | |
| executablePath: process.env.PLAYWRIGHT_BROWSERS_PATH || '/usr/bin/chromium' | |
| }); | |
| const context = await browser.newContext({ | |
| userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', | |
| viewport: { width: 1280, height: 720 } | |
| }); | |
| const page = await context.newPage(); | |
| await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 }); | |
| console.log('[API] Attempting to solve reCAPTCHA...'); | |
| await solve(page); | |
| const solveTime = ((Date.now() - startTime) / 1000).toFixed(2); | |
| console.log(`[API] reCAPTCHA solved in ${solveTime}s`); | |
| const pageUrl = page.url(); | |
| const pageTitle = await page.title(); | |
| const token = await page.evaluate(() => { | |
| const textarea = document.querySelector('[name="g-recaptcha-response"]'); | |
| return textarea ? textarea.value : null; | |
| }); | |
| await browser.close(); | |
| res.json({ | |
| success: true, | |
| message: 'reCAPTCHA solved successfully', | |
| solveTime: `${solveTime}s`, | |
| url: pageUrl, | |
| title: pageTitle, | |
| hasToken: !!token, | |
| tokenLength: token ? token.length : 0, | |
| timestamp: new Date().toISOString() | |
| }); | |
| } catch (error) { | |
| console.error('[API] Error solving reCAPTCHA:', error); | |
| if (browser) { | |
| await browser.close().catch(err => console.error('Error closing browser:', err)); | |
| } | |
| res.status(500).json({ | |
| success: false, | |
| error: 'Failed to solve reCAPTCHA', | |
| message: error.message, | |
| timestamp: new Date().toISOString() | |
| }); | |
| } | |
| }); | |
| app.post('/api/solve', async (req, res) => { | |
| const { url, submitSelector } = req.body; | |
| if (!url) { | |
| return res.status(400).json({ | |
| error: 'Missing required field', | |
| message: 'Please provide a URL in the request body' | |
| }); | |
| } | |
| let browser; | |
| const startTime = Date.now(); | |
| try { | |
| console.log(`[API] Starting to solve reCAPTCHA for: ${url}`); | |
| browser = await chromium.launch({ | |
| headless: true, | |
| args: [ | |
| '--no-sandbox', | |
| '--disable-setuid-sandbox', | |
| '--disable-dev-shm-usage', | |
| '--disable-gpu', | |
| '--disable-blink-features=AutomationControlled' | |
| ], | |
| executablePath: process.env.PLAYWRIGHT_BROWSERS_PATH || '/usr/bin/chromium' | |
| }); | |
| const context = await browser.newContext({ | |
| userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', | |
| viewport: { width: 1280, height: 720 } | |
| }); | |
| const page = await context.newPage(); | |
| await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 }); | |
| console.log('[API] Attempting to solve reCAPTCHA...'); | |
| await solve(page); | |
| await page.waitForTimeout(2000); | |
| if (submitSelector) { | |
| await page.click(submitSelector); | |
| await page.waitForTimeout(3000); | |
| } | |
| const solveTime = ((Date.now() - startTime) / 1000).toFixed(2); | |
| console.log(`[API] reCAPTCHA solved in ${solveTime}s`); | |
| const pageUrl = page.url(); | |
| await browser.close(); | |
| res.json({ | |
| success: true, | |
| message: 'reCAPTCHA solved successfully', | |
| solveTime: `${solveTime}s`, | |
| url: pageUrl, | |
| timestamp: new Date().toISOString() | |
| }); | |
| } catch (error) { | |
| console.error('[API] Error solving reCAPTCHA:', error); | |
| if (browser) { | |
| await browser.close().catch(err => console.error('Error closing browser:', err)); | |
| } | |
| res.status(500).json({ | |
| success: false, | |
| error: 'Failed to solve reCAPTCHA', | |
| message: error.message, | |
| timestamp: new Date().toISOString() | |
| }); | |
| } | |
| }); | |
| app.listen(PORT, '0.0.0.0', () => { | |
| console.log(`π reCAPTCHA Solver API running on port ${PORT}`); | |
| console.log(`π Health check: http://localhost:${PORT}/health`); | |
| console.log(`π§ Solve endpoint: http://localhost:${PORT}/api/solve?url=YOUR_URL`); | |
| }); | |
| process.on('SIGTERM', () => { | |
| console.log('SIGTERM received, shutting down gracefully...'); | |
| process.exit(0); | |
| }); | |
| process.on('SIGINT', () => { | |
| console.log('SIGINT received, shutting down gracefully...'); | |
| process.exit(0); | |
| }); |