
CX
29/9/2026
Tóm tắt
blog.share_blog
@cogover/sdk: Inbound webhookTrang này thuộc API reference của @cogover/sdk.
Quản trị viên có thể tạo inbound access cho project để một hệ thống bên ngoài gọi route mà không cần phiên người dùng Cogover. Hệ thống bên ngoài nhận URL có dạng
https://{WORKSPACE_DOMAIN}/api/v1/ts-projects/{projectSlug}/hooks/{inboundId}/{route}
và xác thực mỗi lời gọi bằng inbound key hoặc chữ ký HMAC đã cấu hình cho inbound
access. Cogover kiểm tra key hoặc chữ ký, áp dụng rate limit và từ chối lời gọi
trước khi bất kỳ code nào của project chạy. Route handler thấy lời gọi như vậy với
request.path === "/hooks/{route}": đăng ký route webhook dưới /hooks/, và
inbound ID không nằm trong path.
import { createRouter } from "@cogover/sdk";
const router = createRouter();
router.post("/hooks/payments", async ({ request, invocation, crypto, jobs, response }) => {
if (invocation.identity !== "inbound") return response.empty({ status: 403 });
// Tuỳ chọn: kiểm tra chữ ký riêng của hệ thống bên ngoài trên raw body.
const expected = await crypto.hmacSha256({ secret: "payment_signing_secret" }, request.rawBody ?? "");
if (!crypto.timingSafeEqual(expected, request.headers["x-payment-signature"] ?? "")) {
return response.empty({ status: 401 });
}
const event = request.body as { id: string; orderId: string };
await jobs.enqueue("sync_payment", event, { idempotencyKey: `payment:${event.id}` });
return response.json({ received: true }, { status: 202 });
});
export default router.toHandler();invocation.identity là "inbound", invocation.user là null
và invocation.inbound chứa id, name và mode xác thực của inbound access.
data.object() thực hiện dưới danh tính system và chỉ hoạt động nếu identity
policy đã duyệt của project đặt allowInternalSystem: true; khi đó nó có cùng quyền
truy cập như trong job chạy theo lịch, không bị thu hẹp bởi các object được cấp cho
data.asSystem(). Nếu không, các lời gọi của nó ném PermissionDeniedError có
details.reason là "IDENTITY_NOT_GRANTED". data.asUser() và data.asSystem() chỉ
tuân theo quyền được cấp trong identity policy khi allowInternalSystem là true;
nếu không, chúng cũng bị từ chối như vậy, kể cả với object đã được cấp.
request.body; body dạng form, text hoặc dạng khác để request.body rỗng ({}).
request.rawBody luôn chứa body đúng như đã nhận, dưới dạng chuỗi UTF-8, và
request.contentType là Content-Type của request, nên handler có thể kiểm tra
chữ ký hoặc tự parse định dạng khác.
response hoạt động như
với mọi route. Giữ handler ngắn: xác nhận sự kiện rồi enqueue một job cho việc
thực sự, để hệ thống bên ngoài nhận trả lời nhanh và các lần retry không chồng
lên xử lý chậm.
idempotencyKey cho job được enqueue, hoặc làm key trong state.
Header Idempotency-Key hoạt động như với mọi route. Khi inbound access kiểm tra chữ
ký HMAC có timestamp, mỗi chữ ký chỉ được chấp nhận một lần, trước khi handler chạy:
lần retry lặp lại cùng chữ ký bị từ chối với HTTP 401, kể cả khi lần đầu thất bại, nên
bên gửi phải ký lại cho mỗi lần retry.

blog.blogs_related
Bắt đầu đổi mới phương thức vận hành và tự chủ hệ thống quản trị công việc của bạn
CÔNG TY CỔ PHẦN STRINGEE
Văn phòng