Bỏ qua, tới nội dung chính

Hướng dẫn

App giữ trình duyệt

Gắn tài khoản trong app của bạn với hồ sơ, giữ trình duyệt của hồ sơ trong lúc code làm việc, gia hạn, nhả mà không đóng trình duyệt và theo dõi sự kiện phiên.

Xem dạng Markdown

Một app làm việc với nhiều tài khoản — đăng bài, kiểm tra hộp thư, thu thập dữ liệu — cần ba điều từ Browlix: hồ sơ nào thuộc tài khoản nào, một trình duyệt dùng được mà không ai giành mất giữa chừng, và cách nhả ra mà không bỏ phí trình duyệt đang mở cho việc kế tiếp. Liên kết (binding) và lượt giữ (hold) làm đúng việc đó, qua cùng API, công cụ MCP, SDK và quyền như mọi thứ khác.

Một chương trình hoàn chỉnh làm tất cả việc này — và phục hồi sau mất kết nối, khởi động lại — là app mẫu.

Gắn tài khoản với hồ sơ

Một liên kết nói rằng "tài khoản acc-42 của app fb-poster dùng hồ sơ này". Liên kết không bao giờ chứa mật khẩu, cookie hay token — trạng thái đăng nhập đã nằm trong hồ sơ.

const b = await bx.call("bindings.create", {
  body: { app_id: "fb-poster", external_account_id: "acc-42", profile_id: profileId, label: "Shop page" },
});
  • Mỗi cặp (app_id, external_account_id) chỉ có một liên kết. Tạo lần hai trả CONFLICT kèm binding_id đang có; muốn đổi hồ sơ thì dùng bindings.update.
  • bindings.update và bindings.delete cần revision bạn đọc gần nhất, để hai công cụ không ghi đè nhau.
  • metadata tối đa 4 KiB dữ liệu của riêng bạn. Khoá trông giống thông tin đăng nhập (password, token, cookie, secret, otp, auth, api_key) bị từ chối.
  • bindings.list trả từng liên kết kèm phiên đang chạy của hồ sơ và ai đang giữ.

Tạo, sửa, xoá liên kết cần quyền profile.edit; đọc cần profile.read. Phạm vi nhóm vẫn áp dụng: khoá của thành viên chỉ thấy vài nhóm thì chỉ thấy liên kết của các nhóm đó.

Giữ trình duyệt

sessions.acquire mở hồ sơ trên một máy phù hợp — hoặc dùng lại trình duyệt nếu nó còn mở và rảnh — rồi trao cho app của bạn một lượt giữ.

const hold = await bx.acquireSession({
  appId: "fb-poster",
  externalAccountId: "acc-42",
  holderRef: "poster-worker-3",   // tên cố định của worker này
  ttlSeconds: 120,                // phải gia hạn trong khoảng này
  keepWarmSeconds: 300,           // giữ mở chừng này sau khi nhả
  wait: true,                     // trả về khi trình duyệt sẵn sàng
  onLost: () => abortCurrentJob(), // đã có lượt giữ mới hơn, hoặc phiên đã kết thúc
});
const a = await bx.attach(hold.sessionId);
// … điều khiển trang bằng Playwright (xem Gắn Playwright)
await hold.detach();

Gửi profile_id thay cho app_id + external_account_id nếu bạn không dùng liên kết. Thêm device_id để chọn máy; nếu không, Browlix chọn máy online ít việc nhất có cùng hệ điều hành với hồ sơ.

Kết quả là phiên kèm lease (generation, holder_ref, expires_at, …) và acquired:

acquiredHTTPÝ nghĩa
opened201Đã mở trình duyệt mới cho bạn
reused200Trình duyệt còn mở từ lượt giữ trước; bạn nhận nó với số thế hệ mới
renewed200Bạn đang giữ rồi (cùng khoá và holder_ref); lượt giữ được gia hạn

Khi người khác đang giữ

Mỗi hồ sơ có một trình duyệt và một người giữ tại một thời điểm. Nếu đang bận, acquire trả BUSY kèm details.holder_kind:

holder_kindAiretryable
personNgười đang dùng trên web (xem từ xa có quyền điều khiển) hoặc phiên mở không qua lượt giữkhông — hỏi họ
automationMột luồng tự động hoá đang chạycó, khi lượt chạy xong
appLượt giữ hiện tại của app kháccó, khi họ nhả hoặc hết hạn
stoppingTrình duyệt đang đóngcó, chờ chút
other_machineĐang mở trên máy khác với device_id bạn yêu cầukhông

Browlix không bao giờ cho biết người giữ kia là ai. RECOVERY_REQUIRED nghĩa là phiên trước kết thúc không chắc chắn — phục hồi trước.

Chặn bản cũ

Mỗi lượt giữ có một generation (số thế hệ). Mỗi lần người giữ khác nhận trình duyệt, số này tăng lên, nên một worker bị treo, mất mạng hay chạy quá giờ không thể thao tác thay cho trình duyệt nữa:

  • sessions.renew và sessions.detach phải gửi đúng generation và holder_ref mà acquire trả về, bằng cùng khoá API.
  • Số thế hệ cũ, lượt giữ đã hết hạn, đã nhả hoặc phiên đã kết thúc đều trả FENCED kèm details.reason (superseded, expired, detached hoặc session_ended).
  • Khi nhận FENCED, ngừng đụng vào trình duyệt đó và acquire lại. Hàm acquireSession của SDK tự ngừng gia hạn và gọi onLost.

Gia hạn trước khi hết ttl_seconds (30–600, mặc định 120) — SDK gia hạn sau mỗi một phần ba khoảng đó. Lượt giữ không được gia hạn sẽ hết hạn: trình duyệt vẫn mở thêm keep_warm_seconds, sau đó tắt nếu không ai giữ lại.

Nhả mà không đóng

sessions.detach kết thúc lượt giữ nhưng không bao giờ tự tắt trình duyệt. Nó vẫn mở thêm keep_warm_seconds (0–1800, mặc định 120, hoặc giá trị gửi kèm detach) để việc kế tiếp của cùng tài khoản chạy ngay. Hết khoảng đó trình duyệt tắt — trừ khi trong lúc đó có người giành quyền điều khiển hoặc một lượt tự động hoá nhận nó; khi đó trình duyệt tiếp tục chạy cho họ. Muốn đóng ngay, gửi keep_warm_seconds: 0 hoặc gọi sessions.stop.

Browlix kiểm các lượt giữ hết hạn mỗi phút một lần, nên trình duyệt có thể mở quá thời gian giữ ấm tối đa khoảng một phút.

Theo dõi sự kiện phiên

Webhook có thể bị lỡ khi máy nhận của bạn tắt. sessions.events là nhật ký đứng sau chúng: mọi thay đổi trạng thái phiên và mọi lượt giữ được nhận, nhả, hết hạn hay kết thúc, theo thứ tự id.

ts
let after = loadCursor(); // id cuối cùng bạn đã xử lý, lần đầu là 0
const r = await bx.call("sessions.events", { query: { after, limit: 200 } });
for (const e of r.data as { id: number; kind: string; session_id: string }[]) {
  handle(e);           // id chỉ tăng; bỏ qua id đã gặp
  after = e.id;
}
saveCursor(after);
  • Sự kiện được giữ 7 ngày. gap: true nghĩa là các sự kiện sau con trỏ của bạn đã bị xoá — đồng bộ lại bằng sessions.list và bindings.list.
  • Lọc theo session_id hoặc profile_id. Đọc cần quyền session.read.

Mỗi máy hỗ trợ gì

devices.capabilities liệt kê việc mỗi máy làm được lúc này — gắn CDP (luôn trên cùng máy), chạy ẩn, đồng bộ hồ sơ, khoá lưu trữ, xem từ xa, tự động hoá, điều khiển đồng loạt, AI agent và API tương thích AdsPower — kèm phiên bản worker cần có, sức chứa và số trình duyệt đang chạy. Hãy đọc nó thay vì đoán từ số phiên bản.

Quyền

LệnhQuyền
bindings.listprofile.read
bindings.create, bindings.update, bindings.deleteprofile.edit
sessions.acquire, sessions.renew, sessions.detachsession.start
sessions.eventssession.read
devices.capabilitiesdevice.read

Mọi lệnh ghi đều có nhật ký và nhận command_id, nên gửi lại sau khi mất phản hồi sẽ nhận đúng kết quả lần đầu (lệnh và biên nhận). Qua MCP, các lệnh này là công cụ bindings_create, sessions_acquire, sessions_renew, sessions_detach, sessions_events, v.v.