Щоб перевірити SendGrid Event Webhook на локальній зупинці, запустіть свій обробник локально, виведіть свій порт з npx portpreview PORT, введіть отриману URL-адресу HTTPS як URL-адресу SendGrid, і перевірте кожен запит з Signed Event Webhook публічним ключем перед обробкою його подій.
Що SendGrid Event Webhook надсилає
Event Webhook повідомляє, що відбувається після SendGrid приймає повідомлення. Проведення заходів з експлуатації processedй deliveredй deferredй bounceй dropped. Залучення заходів включають openй clickСМС-репортажі та зміни підписки. Точні поля залежать від типу події, тому маршрут в першу чергу на event і обробляти додаткові поля як додаткові.
Орган запиту - JSON Головна, не обов'язково один предмет.Відправитиможе розмістити кілька подій в одному POST. Рушник, що припускає req.body.event безшумно пропустіть партію. Офіційна інформація Event Webhook посилання документи імен та полів заходу, в тому числі sg_event_id і sg_message_idй
Використовуйте події як факти, не команди. Наприклад, подія delivered може оновити статус повідомлень, в той час як клацання можна застосувати запис взаємодії. Уникайте створення натискного обробника перезаписати пізніше відписаного стану, тому що запити прибули з замовлення.
1. Створення локальної кінцевої точки
Цей Express приклад навмисно застосовується лише до маршруту SendGrid. Верифікації сигналів залежить від точних байтів SendGrid; парсування та ресеріалізація JSON може змінити ці байти.
import express from 'express';
import { EventWebhook, EventWebhookHeader } from '@sendgrid/eventwebhook';
const app = express();
const verifier = new EventWebhook();
const publicKey = verifier.convertPublicKeyToECDSA(
process.env.SENDGRID_WEBHOOK_PUBLIC_KEY,
);
app.post(
'/webhooks/sendgrid',
express.raw({ type: 'application/json' }),
async (req, res) => {
const signature = req.get(EventWebhookHeader.SIGNATURE());
const timestamp = req.get(EventWebhookHeader.TIMESTAMP());
if (!signature || !timestamp || !verifier.verifySignature(
publicKey,
req.body,
signature,
timestamp,
)) {
return res.status(403).send('invalid signature');
}
let events;
try {
events = JSON.parse(req.body.toString('utf8'));
} catch {
return res.status(400).send('invalid JSON');
}
if (!Array.isArray(events)) {
return res.status(400).send('expected an event array');
}
await enqueueNewEvents(events);
return res.sendStatus(204);
},
);
app.use(express.json());
app.listen(3000);
Встановити офіційний помічник npm install @sendgrid/eventwebhookГора глобальна express.json() після цього маршруту або явно виключити цей шлях. Те ж саме правило діє в Next.js, Fastify, NestJS, безсерверних функцій, а також API шлюзів: зберігайте оригінальне тіло як рядок або байтовий буфер до завершення перевірки. Офіційна SendGrid Node repository має відповідність Event Webhook прикладй
2. Дати SendGrid URL HTTPS
Зберігати програму, потім відкрити другий термінал:
npx portpreview 3000
PortPreview друкує громадське походження HTTPS. Якщо це https://example.portpreview.devURL:
https://example.portpreview.dev/webhooks/sendgrid
Шлях повинен відповідати маршруту точно. Тримайте процес тунелю живим під час тестування. Не замінює локальний сервер, тому збій з'єднання зазвичай означає, що додаток припиняється, слухаючи на іншому порту, або зв'язується таким чином, тунель не може досягати.
3. Налаштування Event Webhook в SendGrid
- У SendGrid УІ, відкрита Налаштування > Налаштування поштий
- Під Налаштування Webhook, відкрити Event Webhooks і вибрати Створення нового вебхукай
- Увімкніть його, додайте URL-адресу PortPreview, як URL-адреса повідомлення, і виберіть лише дії, необхідні для вашої програми.
- Під функціями безпеки, ввімкнути Signed Event Webhookй
- Заощаджуйте вебхоок, відкрийте його налаштування, скопіюйте сформований ключ публічної перевірки та зберігайте його як
SENDGRID_WEBHOOK_PUBLIC_KEYй - Зареєструватися Тестувати свою інтеграцію, потім надсилайте реальне повідомлення для здійснення типів подій, які мають значення.
SendGrid струм Керівництво налаштування примітки, що тестові надсилання на прикладі подій, а не дані з реального відправлення пошти. Заощаджуйте перед перевіркою підпису: за збереження конфігурації Signed Event Webhook.
Як SendGrid підписані роботи по влаштуванню вебгока
Signed Event Webhook використовує ECDSA. SendGrid зберігає приватний ключ і відображає відповідний ключ публічної перевірки. Кожна доставка X-Twilio-Email-Event-Webhook-Signature і X-Twilio-Email-Event-Webhook-Timestamp. Перевірка охоплює часову заглушку, яка зашифрована сирими байтами навантаження та байтами SHA-256; підпис Base64-encoded. Офіційна довідник ручить перетворенню ключа, декодування підпису, заслухання та перевірку ECDSA.
Це симетрична перевірка: відображення значення є публічним ключем, не секрет HMAC. Не запустіть перевантаження через JSON.stringify(), обробка білого простору, додавання нової лінії або перевірки одного елемента масиву одночасно. Перевірити повний запит байт спочатку, потім записати масив. Див SendGrid Документи для алгоритму та заголовків.
Важкий підпис встановлює, що підписані байти вийшли з власника SendGrid приватного ключа і не були змінені. Це не робить обробки подій idempotent, авторизувати довільні дії, або довести, що подія є новим. Ті окремі елементи керування.
Зробіть пакетну обробку idempotent
SendGrid ретріс не вдалося POSTs, а мережі можуть втратити успішну відповідь. Тому дублікати доставки є нормальним. Використовуйте кожен захід sg_event_id як основний ключ дедуплікації, з унікальним обмеженням бази даних. Якщо ваш продукт поєднує в собі кілька облікових записів SendGrid або оточення, простір імен, ключ від провайдера та облікового запису або навколишнього середовища.
async function enqueueNewEvents(events) {
for (const event of events) {
await db.transaction(async (tx) => {
const inserted = await tx.webhookReceipts.insertIfAbsent({
provider: 'sendgrid',
eventId: event.sg_event_id,
receivedAt: new Date(),
});
if (!inserted) return;
await tx.jobs.enqueue({
type: 'process-sendgrid-event',
payload: event,
});
});
}
}
Вставляння квитанції і міцний аккаунт повинен здійснюватися разом. Тільки повертаємо 2xx після того, як пакет відрізняється великою accepted. Якщо один захід не вдається після того, як інші комісії, відповідь не-2xx може викликати весь запит, щоб повернутися; дедуплікація дає можливість отримати наступну спробу пропустити події вже accepted і продовжувати безпечно. Не використовуйте в пам'яті Set у виробництві, тому що перезавантажити його і кілька екземплярів не діляться. Широкий Повідомляємо про те, що веб-довідник по переробці та зберіганню охоплює міцні візерунки.
Витримувати речення перед вибором кодів стану
За данимиВідправитиРВебокдокументація, відповідь 2xxx відзначає POST успішним. Відповідність не-2xxx викликає речення при збільшенні інтервалів до 24 годин після події; це вікно для прокатки для кожного нового події з недійсним. Таким чином, поведінка є постійною відмовою підпису, також може генерувати повторні спроби, при поверненні 2xx для події, які ніколи не зберігають його.
- 2кскс: Повна партія була автентифікована і довговічнаУвійтиабо кожен захід вже відомий.
- 4кскс: неправильний або неаутентичний вхід. Ввійти тільки безпечну діагностику; expect SendGrid загальна не-2xxx.
- 5кскс: перехідна база даних, черга або відмова додатків, яка повинна бути перерозподілена.
Зберігайте шлях запиту коротким: перевірте, встановіть зовнішній вигляд, атомічно від'єднайте і робіть, потім відповідайте. Виконайте оновлення аналітики електронної пошти, синхронізацію CRM та сповіщення працівників.
Виправлення неполадок локальних SendGrid webhooks
Підпис завжди недійсний
Найпоширеніша причина JSON середнього програмного забезпечення, що споживає тіло до перевірки. Підтвердіть, що вивержувач отримує оригінальний Buffer, включаючи будь-який провідний або причіпний білий простір. Потім перевірте, що публічний ключ належить до цієї точної конфігурації Event Webhook і що обидва Twilio заголовки досягають програми незмінними. Перезавантажити локальний процес після зміни навколишнього середовища.
Тестова інтеграція досягається, але реальні події не з'являються
Перевірити, що ввімкнено вебок і які потрібні дії. Відкрийте відправлення, і натисніть кнопку слідкувати. Також пам'ятайте, що тестовий запит містить приклади; використовувати фактичне відправлення для перевірки виробничих полів та відведення.
Кінцева точка повертається 404 або 502
Для 404, порівняти настрочений шлях з /webhooks/sendgrid. Для помилок шлюзу переконайтеся, що локальний додаток працює на одному порту, переданому PortPreview. Якщо запити прибувають, але повертають 500, перевіряють локальні колоди і тимчасово знижують обробник для перевірки плюс міцний захоплення.
Події дублюються або з замовлення
Це реальність системи доставки, не свідчить про те, що тунель дублюється трафік. Дублікат sg_event_id, вносити переходи в монотонію, де можливо, і зберігати час заходів окремо від отримання часу. Використання локальний webhook debugging workflow для ізоляції транспорту, автентифікації та бізнес-логічних збоїв.
Контроль безпеки для місцевого та виробничого використання
- Використовуйте HTTPS і перевірте кожного підпису перед оформленням або оформленням повідомлень.
- Зберігайте ключ публічної перевірки в конфігурації, щоб він був оновлений чисто при зміні ключа Webhook.
- Прийміть POST тільки, обмежте розмір запиту, перевірте, що номінальна вартість є масивом, і дозволити тільки імена подій, які ви керуєте.
- Не розміщуйте PII в SendGrid категорії або унікальні аргументи; SendGrid посилання явно попереджає, що ці поля зберігаються і не розглядаються як PII.
- Не піддавати адміністративній сесії, дебюгувати консолі, або не пов'язані локальні маршрути за тим самим тимчасовим походженням.
- Не записувати адреси одержувача, перевантаження, підписи, або значення навколишнього середовища, якщо це необхідно і відповідно відредаговано.
- Замініть URL-адресу тимчасового тунелю з стабільною виробничою точкою HTTPS після тестування та вимкнення конфігурацій вебок.
SendGrid також може використовуватися OAuth 2.0 для Event Webhook безпеки, або окремо або поряд з підписами. Якщо Ваше розгортання потребує контроль життєвого циклу ведмедя, слідуйте за офіційним посібником безпеки, а не запроваджуючи обмін токени. Перевірка підписів залишається цінним, оскільки він зв’язує точний час і перезавантаження байтів.
Тест на прийняття продукції
- Надішліть заявку на реєстрацію та підтверджуємо відповідь 2xxx.
- Змінення одного завантаження та підтвердження 403 без написання бази даних.
- Відтворити ідентичний дійсний запит і підтвердити відсутність дублікатів або дії бізнесу.
- Надіслати об'єкт JSON замість масиву і підтвердити керований 400.
- Припиніть базу коротко, підтвердіть 5xxx, відновіть його, і перевірте, що птиця accepted раз.
- Надішліть реальну електронну пошту і підтвердіть вибрані події доставки та залучення до неї.
Після того, як ці перевірки проходять, перемістіть кінцеву точку до виробництва, не змінивши логіку перевірки та повідомлення. Для більш глибоких режимів криптографічної недостатності читайте Керівництво по перевірці підписів Webhookй
