บทความทั้งหมด
วิธีทดสอบ SendGrid Event Webhook บน localhost
SendGridemail webhookssignature verificationlocalhost

วิธีทดสอบ SendGrid Event Webhook บน localhost

เพื่อทดสอบก SendGrid Event Webhook บน localhost เรียกใช้ตัวจัดการของคุณภายในเครื่อง เปิดเผยพอร์ตด้วย npx portpreview PORTให้ป้อนผลลัพธ์ HTTPS จุดสิ้นสุดเป็น SendGridURL โพสต์ของ และตรวจสอบทุกคำขอด้วย Signed Event Webhook พับลิกคีย์ก่อนประมวลผลกิจกรรม

อะไร. SendGrid Event Webhook ส่ง

ที่ Event Webhook รายงานสิ่งที่เกิดขึ้นหลังจากนั้น SendGrid ยอมรับข้อความ กิจกรรมการส่งมอบรวมถึง processed, delivered, deferred, bounce, และ dropped. กิจกรรมการมีส่วนร่วมได้แก่ open, clickรายงานสแปม และการเปลี่ยนแปลงการสมัครรับข้อมูล ช่องข้อมูลที่แน่นอนจะแตกต่างกันไปตามประเภทของกิจกรรม ดังนั้นให้เปิดเส้นทางเป็นหลัก event และถือว่าฟิลด์ตัวเลือกเป็นทางเลือก

เนื้อหาคำขอคือก JSON อาร์เรย์ไม่จำเป็นต้องมีเพียงวัตถุเดียว SendGrid อาจจัดหลายเหตุการณ์ไว้ในที่เดียว POST. ตัวจัดการที่ถือว่า req.body.event จะพลาดชุดไปอย่างเงียบๆ อย่างเป็นทางการ Event Webhook อ้างอิง บันทึกชื่อเหตุการณ์และฟิลด์ต่างๆ รวมถึง sg_event_id และ sg_message_id.

ใช้เหตุการณ์เป็นข้อเท็จจริง ไม่ใช่คำสั่ง ตัวอย่างเช่น ก delivered เหตุการณ์สามารถอัพเดตสถานะข้อความได้ในขณะที่ click สามารถผนวกบันทึกการมีส่วนร่วมได้ หลีกเลี่ยงการทำ click ตัวจัดการจะเขียนทับสถานะการยกเลิกการสมัครในภายหลังเพียงเพราะคำขอไม่เป็นไปตามคำสั่ง

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 ที่เก็บโหนดมีการจับคู่ ลงนาม Event Webhook ตัวอย่าง.

2. ให้ SendGrid หนึ่ง HTTPS URL

ให้แอปพลิเคชันทำงานต่อไป open เทอร์มินัลที่สอง:

npx portpreview 3000

PortPreview พิมพ์สาธารณะ HTTPS ต้นทาง. ถ้าเป็นอย่างนั้น https://example.portpreview.devURL ของโพสต์ที่สมบูรณ์คือ:

https://example.portpreview.dev/webhooks/sendgrid

เส้นทางจะต้องตรงกับเส้นทางทุกประการ รักษากระบวนการทันเนลให้คงอยู่ขณะทดสอบ อุโมงค์ส่งต่อการจราจร ไม่ได้มาแทนที่เซิร์ฟเวอร์ภายในเครื่องของคุณ ดังนั้นการเชื่อมต่อที่ล้มเหลวมักจะหมายความว่าแอปหยุดทำงาน กำลังฟังบนพอร์ตอื่น หรือถูกผูกไว้ในลักษณะที่อุโมงค์ไม่สามารถเข้าถึงได้

3. กำหนดค่า Event Webhook ใน SendGrid

  1. ใน SendGrid UI, open การตั้งค่า > การตั้งค่าเมล.
  2. ภายใต้การตั้งค่า Webhook open Event Webhookส และเลือก สร้างเว็บฮุคใหม่.
  3. เปิดใช้งานเพิ่ม PortPreview URL เป็น URL ของโพสต์ และเลือกเฉพาะการดำเนินการที่แอปพลิเคชันของคุณต้องการ
  4. ภายใต้คุณลักษณะความปลอดภัย ให้เปิดใช้งาน Signed Event Webhook.
  5. บันทึก webhook อีกครั้งopen การตั้งค่า คัดลอกคีย์การยืนยันสาธารณะที่สร้างขึ้น และจัดเก็บเป็น SENDGRID_WEBHOOK_PUBLIC_KEY.
  6. ใช้ Test Your Integrationจากนั้นส่งข้อความจริงเพื่อออกกำลังกายประเภทเหตุการณ์ที่สำคัญ

SendGridเป็นปัจจุบัน คู่มือการตั้งค่า ตั้งข้อสังเกตว่าการทดสอบจะส่งเหตุการณ์ตัวอย่างมากกว่าข้อมูลจากการส่งเมลจริง บันทึกก่อนการทดสอบ signature การตรวจสอบ: คู่คีย์จะถูกสร้างขึ้นเมื่อ Signed Event Webhook บันทึกการกำหนดค่าแล้ว

ยังไง SendGridการตรวจสอบ webhook ที่ลงนามแล้วใช้งานได้

Signed Event Webhook การใช้งาน ECDSA. SendGrid เก็บรหัสส่วนตัวและแสดงรหัสยืนยันสาธารณะที่เกี่ยวข้องให้กับคุณ การจัดส่งแต่ละครั้งประกอบด้วย X-Twilio-Email-Event-Webhook-Signature และ X-Twilio-Email-Event-Webhook-Timestamp. การตรวจสอบครอบคลุมถึง timestamp เชื่อมต่อกับไบต์ข้อมูลดิบและ a SHA-256 กัญชา; ที่ signature เป็น Base64-เข้ารหัส ผู้ช่วยอย่างเป็นทางการจัดการการแปลงคีย์สาธารณะ signature การถอดรหัส การแฮช และ ECDSA การตรวจสอบ

นี่คือการตรวจสอบแบบไม่สมมาตร: ค่าที่แสดงเป็นคีย์สาธารณะ ไม่ใช่ข้อมูลลับ HMAC อย่ารันเพย์โหลดผ่าน JSON.stringify()ตัดช่องว่าง เพิ่มบรรทัดใหม่ หรือตรวจสอบองค์ประกอบอาร์เรย์ทีละรายการ ตรวจสอบไบต์คำขอที่สมบูรณ์ก่อน จากนั้นจึงแยกวิเคราะห์อาร์เรย์ ดู SendGridของ เอกสารประกอบคุณลักษณะด้านความปลอดภัย สำหรับอัลกอริทึมและส่วนหัว

ถูกต้อง signature กำหนดว่าไบต์ที่ลงนามมาจากเจ้าของ SendGridรหัสส่วนตัวของและไม่ได้มีการเปลี่ยนแปลง มันไม่ได้ทำให้การประมวลผลเหตุการณ์เป็น idempotent อนุญาตการดำเนินการตามอำเภอใจ หรือพิสูจน์ว่าเหตุการณ์นั้นเป็นเหตุการณ์ใหม่ สิ่งเหล่านี้เป็นการควบคุมที่แยกจากกัน

ทำให้การประมวลผลเป็นชุด idempotent

SendGrid การลองใหม่ล้มเหลว POSTและเครือข่ายอาจสูญเสียการตอบสนองที่ประสบความสำเร็จ ดังนั้นการส่งซ้ำจึงเป็นเรื่องปกติ ใช้แต่ละเหตุการณ์ 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 ในการผลิตเนื่องจากการรีสตาร์ทจะลบมันและหลายอินสแตนซ์ไม่แชร์มัน ยิ่งกว้าง. คู่มือการลองซ้ำของ webhook และ idempotency ครอบคลุมลวดลายคงทน

ทำความเข้าใจการลองใหม่ก่อนที่จะเลือกรหัสสถานะ

ตาม SendGridของ Event Webhook เอกสารประกอบ การตอบสนอง 2xx ทำเครื่องหมาย POST ประสบความสำเร็จ. การตอบสนองที่ไม่ใช่ 2xx ทำให้เกิดการลองใหม่ในช่วงเวลาที่เพิ่มขึ้นสูงสุด 24 ชั่วโมงหลังเหตุการณ์ นี่คือหน้าต่างแบบเลื่อนสำหรับเหตุการณ์ที่ล้มเหลวใหม่แต่ละรายการ พฤติกรรมนั้นหมายถึงความถาวร signature ความล้มเหลวยังสามารถสร้างความพยายามซ้ำแล้วซ้ำอีก ในขณะที่ส่งคืน 2xx สำหรับเหตุการณ์ที่คุณไม่เคยเก็บไว้ก็จะสูญเสียไป

  • 2xx: ชุดทั้งหมดได้รับการรับรองความถูกต้องและคงทน acceptedหรือทุกเหตุการณ์รู้อยู่แล้ว
  • 4xx: อินพุตที่มีรูปแบบไม่ถูกต้องหรือไม่ได้รับการรับรองความถูกต้อง บันทึกการวินิจฉัยที่ปลอดภัยเท่านั้น คาดหวัง SendGridพฤติกรรมการลองซ้ำทั่วไปที่ไม่ใช่ 2xx ของ
  • 5xx: ฐานข้อมูลชั่วคราว คิว หรือแอปพลิเคชันล้มเหลวที่ควรลองใหม่

ทำให้เส้นทางคำขอสั้น: ตรวจสอบ ตรวจสอบรูปร่างภายนอก ขจัดข้อมูลซ้ำซ้อนแบบอะตอมมิก และจัดคิว จากนั้นตอบสนอง ดำเนินการอัปเดตการวิเคราะห์อีเมล CRM การซิงโครไนซ์และการแจ้งเตือนในผู้ปฏิบัติงาน

การแก้ไขปัญหาในท้องถิ่น SendGrid เว็บฮุค

ที่ signature ไม่ถูกต้องเสมอไป

สาเหตุที่พบบ่อยที่สุดคือ JSON มิดเดิลแวร์ที่ใช้เนื้อความก่อนการตรวจสอบ ยืนยันว่าผู้ตรวจสอบได้รับต้นฉบับ Bufferรวมถึงช่องว่างนำหน้าหรือต่อท้าย จากนั้นตรวจสอบว่ากุญแจสาธารณะเป็นของสิ่งนี้ Event Webhook การกำหนดค่าและทั้งสองอย่าง Twilio ส่วนหัวเข้าถึงแอปไม่เปลี่ยนแปลง รีสตาร์ทกระบวนการในเครื่องหลังจากเปลี่ยนสภาพแวดล้อม

การทดสอบการรวมสำเร็จ แต่เหตุการณ์จริงไม่ปรากฏขึ้น

ตรวจสอบว่าเปิดใช้งานเว็บฮุคแล้ว และเลือกการดำเนินการที่ต้องการแล้ว เปิดต้องการ open ติดตามและ clickต้องการ click ติดตาม โปรดจำไว้ว่าคำขอทดสอบมีตัวอย่าง ใช้การส่งจริงเพื่อตรวจสอบความถูกต้องของฟิลด์และการจัดลำดับที่เหมือนจริง

จุดสิ้นสุดส่งคืน 404 หรือ 502

สำหรับ 404 ให้เปรียบเทียบเส้นทางที่กำหนดค่าด้วย /webhooks/sendgrid. สำหรับข้อผิดพลาดของเกตเวย์ ตรวจสอบให้แน่ใจว่าแอปในเครื่องทำงานบนพอร์ตเดียวกันที่ส่งผ่านไป PortPreview. หากคำขอมาถึงแต่ส่งคืน 500 ให้ตรวจสอบบันทึกในเครื่องและลดตัวจัดการชั่วคราวเป็นการยืนยันพร้อมการบันทึกที่คงทน

กิจกรรมซ้ำซ้อนหรือไม่เป็นระเบียบ

นั่นคือความเป็นจริงของระบบจัดส่ง ไม่ใช่หลักฐานว่าอุโมงค์ซ้ำซ้อนการรับส่งข้อมูล ทำซ้ำโดย sg_event_idทำให้การเปลี่ยนสถานะเป็นแบบโมโนโทนิกหากเป็นไปได้ และจัดเก็บเวลากิจกรรมแยกจากเวลารับ ใช้ เวิร์กโฟลว์การดีบัก webhook ในเครื่อง เพื่อแยกความล้มเหลวในการขนส่ง การรับรองความถูกต้อง และตรรกะทางธุรกิจ

รายการตรวจสอบความปลอดภัยสำหรับการใช้งานในท้องถิ่นและการผลิต

  • ใช้ HTTPS และตรวจสอบทุก signature ก่อนที่จะแยกวิเคราะห์หรือบันทึกรายละเอียดเหตุการณ์
  • เก็บคีย์การยืนยันสาธารณะไว้ในการกำหนดค่าเพื่อให้สามารถอัปเดตได้อย่างสมบูรณ์เมื่อคีย์เว็บฮุคมีการเปลี่ยนแปลง
  • ยอมรับ POST เท่านั้น จำกัดขนาดคำขอ ตรวจสอบว่าค่าที่แยกวิเคราะห์เป็นอาร์เรย์ และอนุญาตเฉพาะชื่อเหตุการณ์ที่คุณจัดการเท่านั้น
  • อย่าใส่ PII เข้าไป SendGrid หมวดหมู่หรือข้อโต้แย้งที่ไม่ซ้ำใคร SendGridการอ้างอิงของเตือนอย่างชัดเจนว่าช่องเหล่านั้นถูกจัดเก็บและไม่ถือเป็น PII
  • อย่าเปิดเผยเซสชันของผู้ดูแลระบบ คอนโซลดีบัก หรือเส้นทางท้องถิ่นที่ไม่เกี่ยวข้องผ่านทางต้นทางชั่วคราวเดียวกัน
  • อย่าบันทึกที่อยู่ของผู้รับ เพย์โหลด signatureหรือค่าสภาพแวดล้อม เว้นแต่จะมีการแก้ไขที่จำเป็นและเหมาะสม
  • แทนที่ URL ช่องสัญญาณชั่วคราวด้วยการผลิตที่เสถียร HTTPS ตำแหน่งข้อมูลหลังการทดสอบ และปิดใช้การกำหนดค่า Webhook เก่า

SendGrid ยังสามารถใช้งานได้ OAuth 2.0 สำหรับ Event Webhook ความปลอดภัย ไม่ว่าจะคนเดียวหรือเคียงข้างกัน signatureส. หากการปรับใช้ของคุณต้องการผู้ถือ-token การควบคุมวงจรชีวิต ให้ปฏิบัติตามคำแนะนำด้านความปลอดภัยอย่างเป็นทางการ แทนที่จะคิดค้น token แลกเปลี่ยน. การตรวจสอบลายเซ็นยังคงมีคุณค่าเนื่องจากมีผลผูกพันกับทุกประการ timestamp และเพย์โหลดไบต์

การทดสอบการยอมรับพร้อมการผลิต

  1. ส่งคำขอทดสอบที่ลงนามแล้วและยืนยันการตอบกลับ 2xx
  2. เปลี่ยนหนึ่งเพย์โหลดไบต์และยืนยัน 403 โดยไม่มีการเขียนฐานข้อมูล
  3. เล่นซ้ำคำขอที่ถูกต้องและยืนยันว่าไม่มีงานหรือการดำเนินธุรกิจที่ซ้ำกัน
  4. ส่ง JSON วัตถุแทนอาร์เรย์และยืนยันการควบคุม 400
  5. หยุดฐานข้อมูลชั่วครู่ ยืนยัน 5xx คืนค่า และตรวจสอบว่ามีการลองอีกครั้ง accepted ครั้งหนึ่ง.
  6. ส่งอีเมลจริงและยืนยันการส่งมอบและเหตุการณ์การมีส่วนร่วมที่เลือกตามเส้นทางเดียวกัน

เมื่อการตรวจสอบเหล่านี้ผ่าน ให้ย้ายตำแหน่งข้อมูลไปยังการใช้งานจริงโดยไม่ต้องเปลี่ยนตรรกะการตรวจสอบและการระบุตำแหน่ง สำหรับโหมดความล้มเหลวในการเข้ารหัสเชิงลึก โปรดอ่าน เว็บฮุค signature คู่มือการตรวจสอบ.

คำถามที่พบบ่อย

สามารถ SendGrid ส่ง Event Webhookไปที่ localhost หรือไม่?
ไม่ใช่โดยตรง. รันตัวจัดการในเครื่อง เริ่มต้น `npx portpreview PORT`และกำหนดค่าสาธารณะที่สร้างขึ้น HTTPS URL บวกกับเส้นทาง webhook ของคุณเป็น SendGridURL ของโพสต์
ฉันจะตรวจสอบได้อย่างไร SendGrid ลงนาม Event Webhook?
อ่าน X-Twilio-Email-Event-Webhook-Signature และ X-Twilio-Email-Event-Webhook-Timestamp ส่วนหัว รักษาเนื้อหาคำขอดิบที่สมบูรณ์ และตรวจสอบด้วยรหัสสาธารณะโดยใช้ SendGridอย่างเป็นทางการ Event Webhook ผู้ช่วย
ทำไมไม่ SendGrid การยืนยัน webhook ล้มเหลวหลังจากนั้น JSON กำลังแยกวิเคราะห์?
ที่ ECDSA signature ครอบคลุม timestamp บวกกับไบต์ของเพย์โหลดดิบที่แน่นอน การแยกวิเคราะห์และซีเรียลไลซ์ใหม่ JSON สามารถเปลี่ยนช่องว่างหรือการจัดรูปแบบได้ ดังนั้นการตรวจสอบจะต้องเกิดขึ้นกับบัฟเฟอร์หรือสตริงดั้งเดิมก่อน JSON การแยกวิเคราะห์
ทำ SendGrid ลองอีกครั้งล้มเหลว Event Webhookส?
ใช่. SendGrid เอกสารที่เพิ่มช่วงเวลาการลองใหม่อีกครั้งสำหรับการตอบสนองที่ไม่ใช่ 2xx ได้นานถึง 24 ชั่วโมงหลังจากแต่ละเหตุการณ์ ส่งคืน 2xx หลังจากแบทช์ได้รับการตรวจสอบสิทธิ์และคงทนแล้วเท่านั้น acceptedและขจัดข้อมูลซ้ำซ้อนด้วย sg_event_id.