cloudbrowser / src /server.mjs
Vo Hoang Minh
up
bbbc331
import { Hono } from "hono";
import puppeteer from "puppeteer-core";
import { default as GoLogin } from "gologin";
import { serve } from "@hono/node-server";
const app = new Hono();
const PORT = process.env.PORT || 3000;
// Tạo một instance GoLogin để quản lý profile
const GL = new GoLogin({
token:
process.env.GOLOGIN_TOKEN ||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2N2VlYWJmOGJkODY2YjdjM2Y2NmIzZjEiLCJ0eXBlIjoiZGV2Iiwiand0aWQiOiI2N2VlYWMyNjcwZTM0MDBhNWY2YjdkZmUifQ.tUvpgtJL0swAUinAx1XIeWt4OQMjBqszIciDPKoE9Nk", // Token từ GoLogin để xác thực
tmpdir: "/tmp", // Thư mục lưu trữ tạm thời
profile_id: "67eeaf4dc3162f03167f4570",
remote_debugging_port: 3500,
executablePath: "/usr/bin/orbita-browser/chrome",
extra_params: [
"--start-maximized",
"--disable-dev-shm-usage",
"--no-sandbox",
"--no-zygote",
"--window-position=0,0",
],
remote: false,
});
app.get("/api/ping", (c) => {
return c.json({
message: "Hello",
});
});
// API endpoint để khởi tạo trình duyệt
app.get("/api/start", async (c) => {
try {
// Tạo profile mới
// Khởi động trình duyệt với profile đã tạo
const wsUrl = await GL.createStartupAndSpawnBrowser();
return c.json({
success: true,
profileId,
wsUrl,
});
} catch (error) {
console.error("Error starting browser:", error);
return c.json(
{
success: false,
error: error.message,
},
500
);
}
});
// API endpoint để điều hướng trình duyệt
app.post("/api/navigate", async (c) => {
try {
const { profileId, url } = await c.req.json();
if (!profileId || !url) {
return c.json(
{
success: false,
error: "Profile ID and URL are required",
},
400
);
}
const wsUrl = await GL.getProfileStartupInfo(profileId);
// Kết nối đến trình duyệt đang chạy
const browser = await puppeteer.connect({
browserWSEndpoint: wsUrl.wsUrl,
ignoreHTTPSErrors: true,
});
// Mở tab mới
const page = await browser.newPage();
// Điều hướng đến URL
await page.goto(url, { waitUntil: "networkidle2" });
// Chụp ảnh màn hình
const screenshot = await page.screenshot({ encoding: "base64" });
return c.json({
success: true,
screenshot,
});
} catch (error) {
console.error("Error navigating browser:", error);
return c.json(
{
success: false,
error: error.message,
},
500
);
}
});
// API endpoint để đóng trình duyệt
app.post("/api/stop", async (c) => {
try {
const { profileId } = await c.req.json();
if (!profileId) {
return c.json(
{
success: false,
error: "Profile ID is required",
},
400
);
}
// Dừng trình duyệt từ xa
await GL.stopRemote(profileId);
return c.json({
success: true,
message: "Browser stopped successfully",
});
} catch (error) {
console.error("Error stopping browser:", error);
return c.json(
{
success: false,
error: error.message,
},
500
);
}
});
// Trang chủ
app.get("/api", (c) => {
return c.html(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cloud Browser API</title>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
h1 { color: #333; }
.endpoint { background: #f5f5f5; padding: 15px; margin: 20px 0; border-radius: 5px; }
code { background: #e0e0e0; padding: 2px 5px; border-radius: 3px; }
</style>
</head>
<body>
<h1>Cloud Browser API</h1>
<p>Sử dụng API này để khởi tạo và điều khiển trình duyệt từ xa.</p>
<div class="endpoint">
<h2>POST /browser/start</h2>
<p>Khởi động một trình duyệt mới và trả về profile ID và WebSocket URL.</p>
</div>
<div class="endpoint">
<h2>POST /browser/navigate</h2>
<p>Điều hướng trình duyệt đến URL xác định và trả về ảnh chụp màn hình.</p>
<p>Body: <code>{ "profileId": "...", "url": "https://example.com" }</code></p>
</div>
<div class="endpoint">
<h2>POST /browser/stop</h2>
<p>Đóng trình duyệt.</p>
<p>Body: <code>{ "profileId": "..." }</code></p>
</div>
</body>
</html>
`);
});
// Khởi động server
console.log(`Server is starting on port ${PORT}...`);
// Bắt đầu lắng nghe kết nối
serve({
fetch: app.fetch,
port: 3000,
});