Lập trình viên & AI agent
Webhook và sự kiện
Luồng sự kiện X-Buddy, gửi webhook và thử lại, xác minh chữ ký, quy tắc URL và gửi thử đến endpoint.
X-Buddy ghi lại những gì diễn ra trong workspace dưới dạng sự kiện. Bạn có thể đọc bằng cách thăm dò, hoặc nhận dưới dạng webhook tại endpoint HTTPS của mình.
Thăm dò
GET /events (events_list) trả về các sự kiện theo thứ tự. Truyền cursor của sự kiện cuối cùng bạn đã xử lý vào after để chỉ lấy các sự kiện mới hơn. Con trỏ sự kiện là các số tăng dần (ở dạng chuỗi). Sự kiện được lưu trong 30 ngày. Thăm dò là cách đáng tin cậy; webhook là cách nhận nhanh.
Các loại sự kiện
| Nhóm | Loại |
|---|---|
| Việc | job.succeeded, job.failed, job.unknown, job.held, job.cancelled, batch.completed |
| Hộp thư và tương tác | dm.received, dm.request_received, reply.received, mention.received, follower.gained, follower.lost |
| Bài đăng | post.published, post.failed, post.partial |
| Chiến dịch | campaign.person_entered, campaign.person_replied, campaign.person_completed, campaign.paused_auto |
| Nick | account.session_lost, account.session_restored, account.safety_changed, account.x_rate_limited, account.chat_locked |
| Hạ tầng và các loại khác | vps.offline, vps.online, proxy.failed, alert.opened, integration.paused, scan.completed, limit.reached |
Cấu trúc bao ngoài
Sự kiện tuân theo CloudEvents 1.0:
{
"specversion": "1.0",
"id": "<event id>",
"type": "job.succeeded",
"source": "x-buddy:workspace:<workspace_id>",
"subject": "<what the event is about>",
"time": "2026-11-01T09:00:00Z",
"observed_at": "2026-11-01T09:00:01Z",
"cursor": "1042",
"workspace_id": "<workspace_id>",
"account_id": "<account_id>",
"job_id": "<job_id>",
"integration_id": null,
"data": {}
}
Khi kết nối không có quyền đọc văn bản tin nhắn, các sự kiện có nội dung sẽ chứa "text_withheld": true thay cho văn bản.
Xác minh chữ ký
Các lần gửi tuân theo Standard Webhooks và chứa ba header: webhook-id, webhook-timestamp và webhook-signature (v1,<base64>).
- Tạo chuỗi
<webhook-id>.<webhook-timestamp>.<raw body>. - Tính HMAC-SHA256 bằng khoá bí mật ký của bạn (giải mã base64 sau khi bỏ tiền tố
whsec_). - So sánh với từng chữ ký
v1trong header (có thể có hai chữ ký trong thời gian luân chuyển khoá bí mật, với khoảng chồng lấp 24 giờ). - Từ chối dấu thời gian lệch quá 5 phút so với đồng hồ của bạn.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verify(secret: string, id: string, ts: string, body: string, header: string): boolean {
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
const expected = createHmac("sha256", key).update(`${id}.${ts}.${body}`).digest();
return header.split(" ").some((part) => {
const [v, sig] = part.split(",");
if (v !== "v1" || !sig) return false;
const got = Buffer.from(sig, "base64");
return got.length === expected.length && timingSafeEqual(got, expected);
});
}
Gửi và thử lại
- Gửi bằng
POSTvới thời gian chờ tối đa 10 giây. Chỉ phản hồi2xxmới được tính là gửi thành công; không đi theo chuyển hướng. - Thử lại sau 30 giây, 2 phút, 10 phút, 1 giờ, 6 giờ, 12 giờ, 24 giờ và 24 giờ (dao động ngẫu nhiên ±20%), trong tối đa 72 giờ.
- Sau 20 lần thất bại liên tiếp trong 24 giờ, endpoint bị tạm dừng và một cảnh báo được mở.
Dùng id của sự kiện để bỏ qua các bản trùng lặp: lần gửi thử lại có cùng id.
Quy tắc URL
Endpoint phải dùng https://, trên cổng mặc định, 443 hoặc 8443. Địa chỉ chứa thông tin xác thực và các địa chỉ nội bộ, loopback, link-local, riêng tư hoặc cloud-metadata đều bị từ chối — kể cả tên miền phân giải về các địa chỉ đó. X-Buddy kiểm tra lại ngay trước khi gửi.
Kiểm tra endpoint
POST /webhooks/{endpoint_id}/test (webhook_test) gửi ngay một sự kiện webhook.test có chữ ký và trả về trạng thái HTTP, thời gian thực hiện cùng phần đầu phản hồi của bạn. Thao tác này không làm gì trên X.