Test / server.js
maylinejix's picture
Create server.js
e8abb59 verified
const express = require('express');
const puppeteer = require("puppeteer-extra");
const pluginStealth = require("puppeteer-extra-plugin-stealth");
const { hcaptcha, hcaptchaToken } = require("puppeteer-hcaptcha");
// Gunakan puppeteer stealth
puppeteer.use(pluginStealth());
const app = express();
app.use(express.json());
// Endpoint health check
app.get('/', (req, res) => {
res.json({
status: 'ok',
message: 'hCaptcha Solver API is running',
endpoints: {
'POST /solve': 'Solve hCaptcha with browser (Body: { url: string })',
'POST /solve-token': 'Get hCaptcha token only (Body: { url: string })',
'GET /solve-demo': 'Solve demo hCaptcha'
}
});
});
// Endpoint untuk solve hCaptcha dengan browser page
app.post('/solve', async (req, res) => {
const { url } = req.body;
if (!url) {
return res.status(400).json({
error: 'Missing required parameter: url'
});
}
let browser;
const startTime = Date.now();
try {
browser = await puppeteer.launch({
ignoreHTTPSErrors: true,
headless: true,
args: [
'--window-size=1920,1080',
'--disable-dev-shm-usage',
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-web-security',
'--disable-features=site-per-process',
'--disable-blink-features=AutomationControlled',
'--disable-gpu'
],
});
const [page] = await browser.pages();
await page.goto(url, {
waitUntil: 'networkidle2',
timeout: 60000
});
await page.setDefaultNavigationTimeout(0);
// Solve hCaptcha
await hcaptcha(page);
// Get token dari page
const token = await page.evaluate(() => {
const textarea = document.querySelector('[name="h-captcha-response"]');
return textarea ? textarea.value : null;
});
const endTime = Date.now();
const duration = ((endTime - startTime) / 1000).toFixed(2);
await browser.close();
res.json({
success: true,
token: token,
duration: `${duration} seconds`,
message: 'hCaptcha solved successfully'
});
} catch (error) {
if (browser) {
await browser.close();
}
console.error('Error solving captcha:', error);
const endTime = Date.now();
const duration = ((endTime - startTime) / 1000).toFixed(2);
res.status(500).json({
success: false,
error: error.message,
duration: `${duration} seconds`
});
}
});
// Endpoint untuk get token only (lebih cepat)
app.post('/solve-token', async (req, res) => {
const { url } = req.body;
if (!url) {
return res.status(400).json({
error: 'Missing required parameter: url'
});
}
const startTime = Date.now();
try {
// Metode ini lebih cepat karena langsung return token
const token = await hcaptchaToken(url);
const endTime = Date.now();
const duration = ((endTime - startTime) / 1000).toFixed(2);
res.json({
success: true,
token: token,
duration: `${duration} seconds`,
message: 'hCaptcha token retrieved successfully'
});
} catch (error) {
console.error('Error getting token:', error);
const endTime = Date.now();
const duration = ((endTime - startTime) / 1000).toFixed(2);
res.status(500).json({
success: false,
error: error.message,
duration: `${duration} seconds`
});
}
});
// Endpoint demo
app.get('/solve-demo', async (req, res) => {
const startTime = Date.now();
const demoUrl = "https://accounts.hcaptcha.com/demo?sitekey=4c672d35-0701-42b2-88c3-78380b0db560";
try {
const token = await hcaptchaToken(demoUrl);
const endTime = Date.now();
const duration = ((endTime - startTime) / 1000).toFixed(2);
res.json({
success: true,
token: token,
duration: `${duration} seconds`,
message: 'Demo hCaptcha solved successfully'
});
} catch (error) {
console.error('Error solving demo captcha:', error);
const endTime = Date.now();
const duration = ((endTime - startTime) / 1000).toFixed(2);
res.status(500).json({
success: false,
error: error.message,
duration: `${duration} seconds`
});
}
});
// Endpoint untuk solve dengan custom options
app.post('/solve-advanced', async (req, res) => {
const { url, waitForNavigation = false, timeout = 60000 } = req.body;
if (!url) {
return res.status(400).json({
error: 'Missing required parameter: url'
});
}
let browser;
const startTime = Date.now();
try {
browser = await puppeteer.launch({
ignoreHTTPSErrors: true,
headless: true,
args: [
'--window-size=1920,1080',
'--disable-dev-shm-usage',
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-web-security',
'--disable-features=site-per-process',
'--disable-blink-features=AutomationControlled'
],
});
const [page] = await browser.pages();
await page.goto(url, {
waitUntil: 'networkidle2',
timeout: timeout
});
await page.setDefaultNavigationTimeout(0);
// Solve hCaptcha
await hcaptcha(page);
// Tunggu jika diminta
if (waitForNavigation) {
await page.waitForTimeout(2000);
}
// Get token
const token = await page.evaluate(() => {
const textarea = document.querySelector('[name="h-captcha-response"]');
return textarea ? textarea.value : null;
});
const endTime = Date.now();
const duration = ((endTime - startTime) / 1000).toFixed(2);
await browser.close();
res.json({
success: true,
token: token,
duration: `${duration} seconds`,
message: 'hCaptcha solved successfully'
});
} catch (error) {
if (browser) {
await browser.close();
}
console.error('Error solving captcha:', error);
const endTime = Date.now();
const duration = ((endTime - startTime) / 1000).toFixed(2);
res.status(500).json({
success: false,
error: error.message,
duration: `${duration} seconds`
});
}
});
const PORT = process.env.PORT || 7860;
app.listen(PORT, '0.0.0.0', () => {
console.log(`🚀 Server running on port ${PORT}`);
console.log(`📡 API ready at http://0.0.0.0:${PORT}`);
});