index.ts
Copiar
Perguntar à IA
import { define, z } from "@jelou/functions";
export default define({
name: "webhook-receiver",
description: "Receives and processes webhooks from external services",
input: z.object({
event: z.string(),
data: z.object({
id: z.string(),
status: z.string(),
metadata: z.record(z.unknown()).optional(),
}),
}),
config: {
path: "/webhooks/events",
methods: ["POST"],
mcp: false,
},
handler: async (input, ctx) => {
ctx.log("Webhook received", {
event: input.event,
id: input.data.id,
requestId: ctx.requestId,
});
const secret = ctx.env.get("WEBHOOK_SECRET");
switch (input.event) {
case "payment.completed": {
ctx.log("Payment completed", { id: input.data.id });
return { acknowledged: true, action: "payment_processed" };
}
case "user.created": {
ctx.log("User created", { id: input.data.id });
return { acknowledged: true, action: "user_synced" };
}
default: {
ctx.log("Unhandled event", { event: input.event });
return { acknowledged: true, action: "ignored" };
}
}
},
});
Testes locais
Copiar
Perguntar à IA
curl -X POST http://localhost:3000/webhooks/events \
-H "Content-Type: application/json" \
-d '{"event": "payment.completed", "data": {"id": "pay_123", "status": "success"}}'
Por que funciona dessa forma
config.methods: ["POST"]— rejeita GET, PUT, etc. Webhooks são sempre POST.config.mcp: false— não faz sentido expor um webhook como ferramenta de IA.config.path— rota fixa que você configura no serviço externo.- O schema
inputvalida a estrutura do payload antes de chegar ao handler.
Este exemplo omite a verificação de assinatura do webhook por brevidade. Em produção, valide a assinatura (por exemplo, HMAC-SHA256 com o header
x-webhook-signature) antes de processar o evento.