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ý.

72 giờ
Thời gian OpenAI tiếp tục thử lại một webhook bị lỡ
45–90 giây
Độ trễ thường gặp khi chạy agent trong handler
2×
Chi phí token khi lần thử lại chạy
~1 giây
Thời gian edge của AnyHook xác nhận: 1,1 giây sau một quãng yên ắng, ngắn hơn khi bận

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.