Обработка вебхуков Nylas в Next.js
На ваш ИИ-агент приходит письмо. У вас есть 10 секунд на ответ.
Если вы используете Nylas Agent Accounts, вебхук message.created немедленно поступает на ваш сервер. В Next.js это обрабатывается с помощью одного файла маршрута.
Вот как это сделать правильно.
Проверка рукопожатия (Challenge Handshake)
При создании вебхука Nylas отправляет GET-запрос с параметром challenge. Вы должны вернуть именно это значение в теле ответа.
Не используйте JSON. Не добавляйте кавычки. Используйте простой текстовый ответ (bare response). Если вы не выполните это условие, вебхук не будет работать.
Пример обработчика GET:
export async function GET(req: NextRequest) {
const challenge = req.nextUrl.searchParams.get("challenge");
return new Response(challenge ?? "", { status: 200 });
}
POST-уведомление
Когда приходит сообщение, Nylas отправляет POST-запрос. Следуйте этим трем правилам, чтобы избежать ошибок:
- Подтверждайте получение немедленно. Возвращайте статус 200 до запуска тяжелой логики. Если ваш LLM будет работать слишком долго, произойдет тайм-аут вебхука.
- Проверяйте подписи. Используйте заголовок
X-Nylas-Signatureи ваш секрет вебхука. Это предотвратит попытки неавторизованных пользователей запустить вашего агента. - Используйте «сырое» тело (raw body). Для проверки HMAC-подписи вам нужен исходный текст. Сначала прочитайте текст, проверьте его, а затем парсите JSON.
Пример обработчика POST:
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 });
}
Советы для продакшена
• Обеспечьте дедупликацию сообщений. Вебхуки доставляются по принципу «at-least-once» (минимум один раз). Используйте ограничение базы данных или Redis, чтобы не обрабатывать одно и то же сообщение дважды.
• Обрабатывайте усеченные полезные нагрузки. Если сообщение превышает 1 МБ, его тело обрезается. Всегда повторно запрашивайте сообщение через API, чтобы получить полный контент.
• Используйте очищенный контент. Используйте message.created.cleaned, чтобы получить Markdown вместо запутанного HTML. Это лучше подходит для вашей LLM.
Как вы обрабатываете дедупликацию в своих обработчиках вебхуков? Используете ли вы Redis или ограничение базы данных?
Источник: https://dev.to/qasim157/handle-messagecreated-webhooks-in-nextjs-4e80