Skip to main content
Mọi yêu cầu chúng tôi gửi đến máy chủ của bạn — lượt gửi webhook và lệnh gọi tool endpoint — đều có chữ ký HMAC-SHA256 trong header X-ThunderPhone-Signature. Xác thực đúng một lần rồi dùng cùng helper cho mọi handler.

Thuật toán

  1. Đọc phần thân yêu cầu thô — chính xác các byte chúng tôi POST đến bạn.
  2. Tính hmac_sha256(secret, body).hexdigest().
  3. So sánh theo thời gian hằng số với X-ThunderPhone-Signature. (So sánh chuỗi thông thường làm lộ thông tin thời gian.)
Chúng tôi ký chính xác các byte được truyền đi, vì vậy việc xác thực phần thân thô luôn hoạt động. Các byte đó cũng là chuỗi tuần tự hóa JSON chuẩn của payload — khóa được sắp xếp theo thứ tự chữ cái, dấu phân cách gọn (,: không có khoảng trắng), UTF-8. Điều này cung cấp cho bạn một cách thứ hai hoàn toàn tương đương khi framework của bạn chỉ cung cấp JSON đã phân tích: tuần tự hóa lại theo chuẩn rồi tính HMAC cho dữ liệu đó.
Ưu tiên phần thân thô — ít hơn một bước và tránh được các vấn đề khi chuyển đổi qua lại số JSON trong một số ngôn ngữ.

Dùng secret nào?

Lưu secret trong trình quản lý secret hoặc biến môi trường — không bao giờ commit secret đó.

Các cách triển khai tham khảo

Cả bốn cách đều xác thực phần thân yêu cầu thô:

Kết nối theo framework cụ thể

Xác minh lệnh gọi công cụ

Khi tác nhân AI gọi trực tiếp một trong các công cụ hàm của bạn (công cụ có endpoint), yêu cầu sẽ mang hai header ThunderPhone bên cạnh endpoint.headers bạn đã cấu hình:
  • X-ThunderPhone-Call-ID — id dạng số của cuộc gọi đang diễn ra.
  • X-ThunderPhone-Signature — HMAC-SHA256, sử dụng secret webhook cấp tổ chức của bạn làm khóa, trên chính xác các byte của phần thân yêu cầu.
Cùng helper verify() hoạt động không thay đổi, với hai điểm cần lưu ý:
  1. Công cụ GET / DELETE không có phần thân. Đối số được truyền dưới dạng tham số truy vấn và chữ ký được tính trên chuỗi byte rỗng — do đó dùng verify(b"", sig, secret) (Python) hoặc verify(Buffer.alloc(0), sig, secret) (Node). Không hash chuỗi truy vấn.
  2. Tổ chức không cấu hình webhook cũ sẽ không có secret cấp tổ chức. Trong trường hợp đó, lệnh gọi công cụ chỉ mang X-ThunderPhone-Call-ID và không có header chữ ký. Cấu hình webhook cũ (PUT /v1/webhook) để có secret ký, hoặc xác thực lệnh gọi công cụ bằng header riêng của bạn qua endpoint.headers.
Điều phối công cụ ở chế độ webhook-mode (công cụ không có endpoint, được gửi đến webhook tổ chức của bạn dưới dạng telephony.tool / web.tool) là một webhook được ký thông thường — áp dụng quy trình chuẩn ở trên. Xem Công cụ hàm để biết cả hai dạng yêu cầu.

Các lỗi thường gặp

Phân tích body rồi xuất lại bằng các thiết lập mặc định của thư viện JSON (dấu cách sau , / :, khóa theo thứ tự chèn) sẽ tạo ra byte khác và làm HMAC không hợp lệ. Xác minh body thô — hoặc nếu bắt buộc phải tuần tự hóa lại, hãy khớp chính xác định dạng chuẩn của chúng tôi: khóa được sắp xếp, dấu phân cách gọn, UTF-8.
Middleware express.json() của Express tiêu thụ luồng body khiến bạn mất các byte thô. Dùng express.raw() riêng cho route webhook, hoặc đệm body thô trong một middleware tiền xử lý. NestJS / Koa cũng tương tự — hãy xem tài liệu về “raw body” của chúng.
expected === signature trong JS hoặc expected == signature trong Python là các phép so sánh có thời gian thay đổi. Hãy dùng crypto.timingSafeEqual hoặc hmac.compare_digest tương ứng. Chênh lệch hiệu năng là không đáng kể.
Các lệnh gọi trực tiếp đến endpoint công cụ được ký bằng webhook secret cấp tổ chức (GET /v1/webhook) — không phải bằng bất kỳ secret riêng theo endpoint nào từ /v1/developer/webhook-endpoints. Dùng lại cùng hàm verify() nhưng hãy đảm bảo truyền secret của tổ chức vào hàm đó trên các route công cụ.
Với các phương thức công cụ không có body, chữ ký bao phủ chuỗi byte rỗng, giúp duy trì một công thức chung: HMAC body yêu cầu thô, bất kể đó là gì. Băm URL hoặc chuỗi truy vấn sẽ không bao giờ khớp.
Trả về 200 khi xác minh thất bại khiến handler trở thành mục tiêu phát lại. Luôn phản hồi mã không thuộc nhóm 2xx nếu xác minh thất bại.

Bước tiếp theo

Tổng quan về webhook

Ngữ nghĩa phân phối, thử lại, IP nguồn.

Endpoint webhook

Quản lý nhiều URL, xoay vòng secret.

Công cụ hàm

Hai luồng gọi công cụ và cấu trúc yêu cầu của chúng.

Tích hợp công cụ

Xây dựng một tích hợp hoàn chỉnh sử dụng công cụ từ đầu đến cuối.