Обработка вебхуков 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-запрос. Следуйте этим трем правилам, чтобы избежать ошибок:

Пример обработчика 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