Webhook OpenAI chịu được handler chạy 45 giây.
Handler (đoạn code xử lý webhook trên server của bạn) đang làm việc thật: RAG, thêm một lệnh gọi mô hình, một transaction DB. OpenAI cho nó vài giây. AnyHook trả về 200 sau khoảng 1 giây và cho handler của bạn tối đa bằng timeout của gói để chạy xong, trong hạn mức compute (tài nguyên tính toán đi kèm gói).
Bài toán thời gian
Background response, batch job và fine-tuning job của OpenAI đều báo kết quả qua HTTP và chờ 2xx trong vài giây, rồi thử lại (retry) trong tối đa 72 giờ. Ngay khi handler của bạn làm gì đó đáng kể, như gọi thêm một mô hình, tìm kiếm vector hay gọi Stripe, bạn sẽ vượt quá thời hạn đó.
Khi bạn vượt quá, OpenAI thử lại. Handler của bạn chạy lại. Giờ bạn trả tiền token hai lần và hệ thống downstream thấy dữ liệu trùng lặp. Cách sửa không phải là timeout dài hơn, mà là tách riêng hai bước xác nhận (ack) và xử lý.
Thay thế trực tiếp: đổi URL webhook
Handler hiện tại của bạn không cần sửa gì. AnyHook xác nhận với OpenAI sau khoảng 1 giây tại edge (lớp máy chủ biên của Cloudflare), rồi chuyển tiếp payload đã xác minh tới endpoint của bạn, kèm đầy đủ thử lại, phát lại (replay) và nhật ký sự kiện.
// 1. Point OpenAI's webhook URL at your AnyHook inbound:
// https://in.anyhook.net/{user-slug}/{app-slug}
//
// 2. Keep your existing handler, it now has all the time it needs.
// AnyHook re-signs every delivery with AnyHook-Signature.
import OpenAI from "openai";
import { verifyWebhook } from "anyhook-verify";
const openai = new OpenAI();
export async function POST(req: Request) {
const ok = await verifyWebhook(req, process.env.ANYHOOK_SIGNING_SECRET!);
if (!ok) return new Response("invalid signature", { status: 401 });
// OpenAI's own event, byte for byte: { type: "response.completed", data: { id }, ... }
const event = await req.json();
if (event.type !== "response.completed") return new Response("ok");
const response = await openai.responses.retrieve(event.data.id);
// Run anything here. AnyHook already returned 200 to OpenAI.
// If you fail, AnyHook retries with backoff (up to 10 attempts on Scale).
await ragPipeline(response); // 25s
await secondModelCall(response); // 18s
await persistResult(response); // 2s
return new Response("ok", { status: 200 });
}Câu hỏi các team thường đặt ra
- Tôi có mất bước xác minh chữ ký của OpenAI không?
- Không. OpenAI ký theo cơ chế Standard Webhooks (webhook-id, webhook-timestamp, webhook-signature). Đặt nguồn của App (một URL nhận cho một nguồn webhook, ví dụ “Stripe production”) là Standard Webhooks và dán signing secret (khóa bí mật dùng để ký, dạng whsec_...) của webhook: AnyHook kiểm tra chữ ký tại edge và từ chối request giả mạo, rồi ký lại mọi lượt gửi tới endpoint của bạn bằng AnyHook-Signature.
- Chuyện gì xảy ra nếu handler của tôi ngừng hoạt động một giờ?
- AnyHook đưa sự kiện vào hàng đợi và thử lại theo exponential backoff (khoảng chờ tăng theo cấp số nhân): tối đa 3 lần trên gói Free, 5 lần trên gói Pro, 10 lần trên gói Scale. Mọi lần gửi đều được ghi lại và phát lại được từ dashboard. OpenAI chỉ thấy một mã 200 và đi tiếp.
- Cách này áp dụng cho những sự kiện OpenAI nào?
- Mọi thứ OpenAI gửi qua webhook: background response (response.completed cùng các sự kiện anh em failed, cancelled và incomplete), batch job, fine-tuning job và eval run. Streaming không phải webhook: đó là luồng dữ liệu mà code của bạn đọc trực tiếp, nên nó không bao giờ đi qua AnyHook.
Đổi một URL. Giữ nguyên handler OpenAI của bạn.
Gói Free gồm 10.000 sự kiện / tháng. Không cần SDK: trỏ OpenAI về URL nhận webhook của bạn trên AnyHook.