𝗛𝗮𝗻𝗱𝗹𝗲 𝗡𝘆𝗹𝗮𝘀 𝗪𝗲𝗯𝗵𝗼𝗼𝗸𝘀 𝗶𝗻 𝗡𝗲𝘅𝘁.𝗷𝘀
An email hits your AI agent. You have 10 seconds to respond.
If you use Nylas Agent Accounts, a message.created webhook hits your server immediately. In Next.js, you handle this with one route file.
Here is how to build it correctly.
𝗧𝗵𝗲 𝗖𝗵𝗮𝗹𝗹𝗲𝗻𝗴𝗲 𝗛𝗮𝗻𝗱𝘀𝗵𝗮𝗸𝗲
When you create a webhook, Nylas sends a GET request with a challenge parameter. You must return the exact value in the response body.
Do not use JSON. Do not add quotes. Use a bare response. If you fail this, the webhook fails.
Example GET handler:
export async function GET(req: NextRequest) { const challenge = req.nextUrl.searchParams.get("challenge"); return new Response(challenge ?? "", { status: 200 }); }
𝗧𝗵𝗲 𝗣𝗢𝗦𝗧 𝗡𝗼𝘁𝗶𝗳𝗶𝗰𝗮𝘁𝗶𝗼𝗻
When a message arrives, Nylas sends a POST request. Follow these three rules to avoid errors:
- Acknowledge immediately. Return a 200 status before you run your heavy logic. If your LLM takes too long, the webhook will time out.
- Verify signatures. Use the X-Nylas-Signature header and your webhook secret. This prevents unauthorized users from triggering your agent.
- Use the raw body. To verify the HMAC signature, you need the raw text. Read the text first, verify it, then parse the JSON.
Example POST handler:
export async function POST(req: NextRequest) { const raw = await req.text(); const signature = req.headers.get("x-nylas-signature") ?? "";
const expected = crypto .createHmac("sha256", process.env.NYLAS_WEBHOOK_SECRET!) .update(raw, "utf8") .digest("hex");
const valid = signature.length === expected.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
if (!valid) { return new Response("invalid signature", { status: 401 }); }
const payload = JSON.parse(raw); const { object } = payload.data;
processMessage(object.grant_id, object.id).catch(console.error);
return NextResponse.json({ ok: true }, { status: 200 }); }
𝗣𝗿𝗼𝗱𝘂𝗰𝘁𝗶𝗼𝗻 𝗧𝗶𝗽𝘀
• 消息去重。Webhook 采用“至少一次”的交付机制。使用数据库约束或 Redis 来确保不会重复处理同一条消息。
• 处理截断的负载。如果消息超过 1 MB,正文会被截断。务必通过 API 重新获取消息以获取完整内容。
• 使用清洗后的内容。使用 message.created.cleaned 来获取 Markdown,而不是杂乱的 HTML。这对你的 LLM 效果更好。
你在 Webhook 处理程序中是如何处理去重的?你是使用 Redis 还是数据库约束?
来源:https://dev.to/qasim157/handle-messagecreated-webhooks-in-nextjs-4e80