File size: 4,796 Bytes
2661273
 
 
f002fc5
2661273
 
 
 
 
 
 
 
 
f67ba22
2f9e1df
f67ba22
f002fc5
 
 
 
 
 
 
 
ce8f202
2661273
 
379141e
8f02d62
 
 
 
 
2661273
3387658
2661273
 
 
 
bbbc331
2661273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3387658
2661273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3387658
2661273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379141e
2661273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb5d0b2
379141e
 
 
f002fc5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
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,
});