सभी लेख
ईमेल डिलीवरी, बाउंस और शिकायत के इवेंट लिफ़ाफ़े हस्ताक्षरित टनल से होकर localhost पर Next.js रूट में जाते हुए।
ResendNext.jsemail webhookslocalhost

Next.js में Resend वेबहुक को लोकल रूप से टेस्ट करें

Resend वेबहुक को Next.js में स्थानीय रूप से परीक्षण करने के लिए, एक App Router POST रूट बनाएं जो रॉ बॉडी को पढ़ता है, अपने Resend साइनिंग सीक्रेट के साथ इसके Svix हेडर को सत्यापित करें, और Resend डैशबोर्ड में एक HTTPS टनल URL पंजीकृत करें। Resend के माध्यम से एक ईमेल भेजें, फिर वास्तविक को संभालें email.sent, email.delivered, email.bounced, या email.complained लोकलहोस्ट पर घटनाएँ।

Resend वेबहुक आपके एप्लिकेशन को क्या बताता है

एक एपीआई प्रतिक्रिया यह कहती है कि एक ईमेल स्वीकार कर लिया गया है, यह इस बात का प्रमाण नहीं है कि यह प्राप्तकर्ता तक पहुंच गया है। वितरण अतुल्यकालिक रूप से होता है. Resend वेबहुक आपके एप्लिकेशन को संदेश की स्थिति अपडेट करने, खराब पते को दबाने, बाउंस की रिपोर्ट करने और मूल भेजने का अनुरोध समाप्त होने के बाद शिकायतों पर प्रतिक्रिया करने देता है। द आधिकारिक Resend वेबहुक दस्तावेज़ीकरण ईवेंट प्रकार और डैशबोर्ड सेटअप सूचीबद्ध करता है।

एक स्थानीय वेबहुक परीक्षण में संपूर्ण राज्य मशीन को कवर किया जाना चाहिए, न कि केवल यह कि कोई POST आपके मार्ग तक पहुंचता है या नहीं। प्रत्येक ईवेंट की ईमेल आईडी को भेजते समय बनाए गए रिकॉर्ड के साथ सहसंबंधित करें। राज्यों को संक्रमण के रूप में मानें: स्वीकार किया गया, भेजा गया, वितरित किया गया, विलंबित किया गया, बाउंस किया गया, शिकायत की गई, खोला गया, या जहां लागू हो वहां क्लिक किया गया। बाद के डुप्लिकेट को अधिक उपयोगी स्थिति को अधिलेखित नहीं करना चाहिए या एक ही अलर्ट को दो बार ट्रिगर नहीं करना चाहिए।

Next.js App Router रूट बनाएं

हस्ताक्षर प्रारूप के लिए बनाए गए सत्यापनकर्ता को स्थापित करें:

npm install svix

फिर एक नोड-रनटाइम रूट बनाएं। Resend मूल निकाय पर हस्ताक्षर करता है, इसलिए उपयोग करें request.text() पार्सिंग से ठीक पहले एक बार।

// app/api/webhooks/resend/route.ts
import { Webhook } from 'svix';

export const runtime = 'nodejs';

export async function POST(request: Request) {
  const payload = await request.text();
  const headers = {
    'svix-id': request.headers.get('svix-id') ?? '',
    'svix-timestamp': request.headers.get('svix-timestamp') ?? '',
    'svix-signature': request.headers.get('svix-signature') ?? '',
  };

  let event: ResendEvent;
  try {
    const webhook = new Webhook(process.env.RESEND_WEBHOOK_SECRET!);
    event = webhook.verify(payload, headers) as ResendEvent;
  } catch {
    return Response.json({ error: 'Invalid webhook signature' }, { status: 400 });
  }

  await enqueueResendEvent({
    deliveryId: headers['svix-id'],
    event,
  });
  return Response.json({ received: true });
}

हस्ताक्षर करने का रहस्य इस वेबहुक एंडपॉइंट से संबंधित है और आम तौर पर प्रदाता-विशिष्ट उपसर्ग से शुरू होता है। इसे Resend वेबहुक सेटिंग्स से किसी उपेक्षित स्थानीय परिवेश फ़ाइल में कॉपी करें .env.local. यह ईमेल भेजने के लिए उपयोग की जाने वाली Resend API कुंजी नहीं है।

तीन Svix हेडर क्यों मायने रखते हैं

  • svix-id विशिष्ट रूप से एक डिलीवरी की पहचान करता है और सबसे अच्छी निष्क्रियता कुंजी है।
  • svix-timestamp हस्ताक्षर को एक समय से बांधता है, जिससे सत्यापनकर्ता को उसकी सहनशीलता के बाहर पुराने अनुरोधों को अस्वीकार करने की अनुमति मिलती है।
  • svix-signature इसमें मुख्य भाग को प्रमाणित करने के लिए उपयोग किए जाने वाले एक या अधिक संस्करण वाले हस्ताक्षर शामिल हो सकते हैं।

जब तक आपके पास कोई ठोस कारण न हो, हेडर स्ट्रिंग्स को विभाजित करके इस प्रोटोकॉल को लागू न करें। एसडीके एन्कोडिंग, एकाधिक हस्ताक्षर और टाइमस्टैम्प जांच को संभालता है। Resend स्पष्ट रूप से सत्यापन के लिए हस्ताक्षर रहस्य और इन हेडर का उपयोग करने की अनुशंसा करता है। उतना ही गहरा हस्ताक्षर सत्यापन मार्गदर्शिका बताता है कि कच्चे बाइट्स और समय-सुरक्षित चेक क्यों मायने रखते हैं।

Next.js को उजागर करें और समापन बिंदु को पंजीकृत करें

  1. भागो npm run dev और पुष्टि करें कि एप्लिकेशन पोर्ट 3000 पर सुनता है।
  2. प्रारंभ करें npx portpreview 3000 दूसरे टर्मिनल में.
  3. Resend में, एक वेबहुक बनाएं जिसका समापन बिंदु है https://YOUR-TUNNEL.portpreview.dev/api/webhooks/resend.
  4. केवल उन्हीं ईमेल ईवेंट का चयन करें जिन्हें आपका एप्लिकेशन प्रोसेस करता है।
  5. समापन बिंदु के हस्ताक्षर रहस्य को कॉपी करें RESEND_WEBHOOK_SECRET और Next.js को पुनरारंभ करें ताकि यह वेरिएबल लोड कर सके।
  6. सत्यापित डोमेन का उपयोग करके एक संदेश भेजें और स्थानीय मार्ग तक पहुंचने वाली घटनाओं का निरीक्षण करें।

सत्र के लिए सार्वजनिक URL को स्थिर रखें. यदि सुरंग का उद्गम बदलता है, तो दोबारा परीक्षण करने से पहले Resend समापन बिंदु को संपादित करें। पुराने URL से कॉन्फ़िगर किया गया समापन बिंदु आपकी नई प्रक्रिया तक नहीं पहुंच सकता, भले ही लोकलहोस्ट स्वयं स्वस्थ हो।

टाइप किए गए ईवेंट डिस्पैचर का उपयोग करें

वेबहुक पेलोड को एक संकीर्ण डिस्पैचर में प्रवेश करना चाहिए। आवश्यक फ़ील्ड को मान्य करें और अज्ञात ईवेंट प्रकारों को सर्वर विफलताओं के रूप में माने बिना अवलोकन योग्य बनाएं।

async function processEvent(event: ResendEvent) {
  switch (event.type) {
    case 'email.delivered':
      await markDelivered(event.data.email_id, event.created_at);
      break;
    case 'email.bounced':
      await markBounced(event.data.email_id, event.data.bounce?.message);
      await suppressIfPermanent(event.data);
      break;
    case 'email.complained':
      await suppressRecipients(event.data.to);
      await alertCompliance(event.data.email_id);
      break;
    default:
      await recordUnhandledEvent(event);
  }
}

यह मानने के बजाय कि प्रत्येक ईवेंट में समान डेटा है, पेलोड प्रकारों को वर्तमान Resend स्कीमा के साथ संरेखित रखें। उदाहरण के लिए, बाउंस विवरण और प्राप्तकर्ता सूचियाँ केवल कुछ घटनाओं पर ही प्रासंगिक हो सकती हैं। समर्थन जांच के लिए ईवेंट प्रकार, प्रदाता ईमेल आईडी, ईवेंट टाइमस्टैम्प और न्यूनतम संशोधित पेलोड सहेजें।

परीक्षण के पुनः प्रयास से पहले हैंडलिंग को निष्क्रिय बनाएं

वेबहुक सिस्टम व्यवहार में कम से कम एक बार डिलीवरी व्यवहार प्रदान करता है। आपके डेटाबेस के प्रतिबद्ध होने के बाद लेकिन प्रदाता को आपकी 200 प्रतिक्रिया प्राप्त होने से पहले एक टाइमआउट हो सकता है। इसके बाद प्रदाता आपके द्वारा पहले से लागू किए गए अनुरोध का पुनः प्रयास करता है। उपयोग करें svix-id एक अद्वितीय डिलीवरी कुंजी के रूप में और राज्य परिवर्तन के रूप में इसे उसी लेनदेन में डालें।

await db.transaction(async (tx) => {
  const inserted = await tx.webhookDelivery.insertOnce({
    provider: 'resend',
    deliveryId,
  });
  if (!inserted) return;
  await applyEmailEvent(tx, event);
});

केवल ईमेल आईडी द्वारा डुप्लिकेट न काटें क्योंकि एक ईमेल वैध रूप से कई ईवेंट प्रकार प्राप्त करता है। अपने डेटा मॉडल के आधार पर, डिलीवरी-स्तर की अद्वितीय कुंजी और राज्य-संक्रमण नियम दोनों रखें। पढ़ें वेबहुक पुनः प्रयास और निष्क्रियता पैटर्न इवेंट को बिलिंग, दमन, या ग्राहक सूचनाओं से जोड़ने से पहले।

इवेंट गँवाए बिना शीघ्रता से लौटें

अनुरोध पथ में हस्ताक्षर सत्यापन उपयुक्त है; व्यवसायिक कार्य धीमा नहीं है. सत्यापित ईवेंट को जारी रखें या सूचीबद्ध करें, फिर 2xx वापस लौटें। यदि आप किसी टिकाऊ लेखन से पहले लौटते हैं, तो एक प्रक्रिया क्रैश होने से ईवेंट खो सकता है। यदि आप कई दूरस्थ एपीआई की प्रतीक्षा करते हैं, तो आपका समापन बिंदु समय समाप्त हो सकता है और पुनः प्रयास को आमंत्रित कर सकता है। डेटाबेस इनबॉक्स तालिका अक्सर सबसे सरल स्थानीय और उत्पादन डिज़ाइन होती है।

उपयोगी परीक्षण ईवेंट उत्पन्न करें

भेजा और वितरित किया गया

उस पते पर भेजें जिसे आप सत्यापित डोमेन से नियंत्रित करते हैं। सेंड एपीआई द्वारा लौटाई गई ईमेल आईडी को रिकॉर्ड करें और पुष्टि करें कि आने वाली घटनाएं उसी पंक्ति को अपडेट करती हैं। डिलीवरी का समय प्राप्तकर्ता सर्वर के अनुसार अलग-अलग होता है, इसलिए यह न मानें कि ईवेंट तुरंत या सरल अनुक्रम में आते हैं।

उछलता है

असंबंधित डोमेन पर ट्रैफ़िक का आविष्कार करने के बजाय Resend के दस्तावेज़ित परीक्षण पते या परीक्षण सुविधाओं का उपयोग करें। सत्यापित करें कि स्थायी विफलताएँ भविष्य के मेल को दबा देती हैं जबकि अस्थायी स्थितियाँ आपकी पुनः प्रयास नीति का पालन करती हैं। प्रत्येक विलंबित घटना को स्वत: दबाएँ नहीं।

शिकायतें

शिकायत प्रबंधन वितरण योग्यता और अनुपालन तर्क दोनों है। सुनिश्चित करें कि बार-बार वेबहुक बार-बार अलर्ट नहीं बनाता है, और सुनिश्चित करें कि प्रभावित प्राप्तकर्ता को आपकी नीति के अनुसार बाद के अभियानों से बाहर रखा गया है।

Resend वेबहुक विफलताओं का समस्या निवारण करें

हस्ताक्षर सत्यापन हमेशा विफल रहता है

पुष्टि करें कि एंडपॉइंट का हस्ताक्षर रहस्य—एपीआई कुंजी नहीं—लोड किया गया है। उपयोग करें await request.text(), JSON को पार्स और पुनः स्ट्रिंग न करें, और सभी तीन Svix हेडर को उनके सटीक मानों के साथ पास करें। बदलने के बाद डेवलपमेंट सर्वर को पुनरारंभ करें .env.local.

मार्ग 404 या 405 लौटाता है

App Router रूट फ़ाइलों का नाम होना चाहिए route.ts इच्छित URL खंडों और निर्यात के नीचे POST. जांचें कि क्या मिडलवेयर किसी लोकेल या लॉगिन पेज पर टनल अनुरोध को फिर से लिखता है। कर्ल के साथ सार्वजनिक यूआरएल का परीक्षण करें और वास्तविक प्रतिक्रिया का निरीक्षण करें।

Resend सफल प्रसंस्करण के बावजूद पुनः प्रयास दिखाता है

जांचें कि प्रत्येक सफल शाखा तुरंत 2xx लौटाती है। डेटाबेस अद्यतन के बाद होने वाली त्रुटियाँ 500 और डुप्लिकेट पुनः प्रयास उत्पन्न कर सकती हैं। प्रसंस्करण को लेन-देनात्मक और निष्क्रिय बनाएं, फिर प्रतिक्रिया विलंबता का निरीक्षण करें।

ईवेंट आते हैं लेकिन उन्हें ईमेल से लिंक नहीं किया जा सकता

मूल Resend से प्रदाता ईमेल आईडी जारी रखें और प्रतिक्रिया भेजें। पहचानकर्ता के रूप में विषय पंक्ति या प्राप्तकर्ता पते पर भरोसा न करें। वे क्षेत्र सहसंबंध के लिए न तो अद्वितीय हैं और न ही पर्याप्त रूप से स्थिर हैं।

दोबारा चलाए गए कैप्चर टाइमस्टैम्प सत्यापन में विफल हो गए

सामान्य सत्यापनकर्ता के माध्यम से पुराने हस्ताक्षरित अनुरोध को दोबारा चलाने पर यह अपेक्षित है: इसका टाइमस्टैम्प अनुमत सहनशीलता से बाहर हो सकता है। जहां उपलब्ध हो वहां प्रदाता पुनर्वितरण को प्राथमिकता दें। पृथक व्यवसाय-तर्क परीक्षणों के लिए, एक बार सत्यापित करें, एक स्वच्छ ईवेंट फ़िक्स्चर सहेजें, और डिस्पैचर का अलग से परीक्षण करें। द रीप्ले गाइड इस सीमा की व्याख्या करता है.

ईमेल ईवेंट परीक्षण के लिए सुरक्षा और गोपनीयता

  • कभी उजागर न करें RESEND_API_KEY या स्रोत, ब्राउज़र बंडल, स्क्रीनशॉट, या अनुरोध लॉग में गुप्त हस्ताक्षर करने वाला एंडपॉइंट।
  • ईवेंट को पार्स करने या जारी रखने से पहले सत्यापित करें।
  • साझा टनल कैप्चर से प्राप्तकर्ताओं, विषयों, हेडर और संदेश मेटाडेटा को संशोधित करें।
  • कच्चे वेबहुक पेलोड पर प्रतिधारण सीमाएँ लागू करें; केवल वही संग्रहित करें जिसके लिए समर्थन और अनुपालन की आवश्यकता हो।
  • उत्पादन से एक अलग स्थानीय समापन बिंदु रहस्य का उपयोग करें और परीक्षण समापन बिंदु हटा दिए जाने पर इसे घुमाएं।

अंतिम डिज़ाइन को तैनाती के बाद समान रूप से काम करना चाहिए: सार्वजनिक HTTPS एंडपॉइंट, रॉ-बॉडी सत्यापन, टिकाऊ निष्क्रियता, तेज़ पावती, और अतुल्यकालिक राज्य हैंडलिंग। App Router-विशिष्ट रॉ-बॉडी विवरण के लिए, देखें Next.js वेबहुक लोकलहोस्ट गाइड.

अक्सर पूछे जाने वाले प्रश्न

मैं Next.js में स्थानीय स्तर पर Resend वेबहुक का परीक्षण कैसे करूँ?
एक App Router POST रूट बनाएं, Svix हेडर और एंडपॉइंट साइनिंग सीक्रेट के साथ रॉ बॉडी को सत्यापित करें, HTTPS के माध्यम से पोर्ट 3000 को उजागर करें, और उस सार्वजनिक URL को Resend में पंजीकृत करें।
क्या Resend वेबहुक को Next.js में request.json() का उपयोग करना चाहिए?
सत्यापन से पहले नहीं. wait request.text() पढ़ें ताकि हस्ताक्षरित बाइट्स अपरिवर्तित रहें, Svix के साथ सत्यापित करें, और SDK द्वारा लौटाए गए सत्यापित ईवेंट का उपयोग करें।
क्या Resend वेबहुक साइनिंग सीक्रेट एपीआई कुंजी के समान है?
नहीं, एपीआई कुंजी अनुरोध भेजने को अधिकृत करती है। प्रत्येक वेबहुक एंडपॉइंट में एक हस्ताक्षर रहस्य होता है जिसका उपयोग आने वाली घटनाओं को सत्यापित करने के लिए किया जाता है; दोनों को अलग-अलग स्टोर करें.
मैं डुप्लिकेट Resend वेबहुक प्रोसेसिंग को कैसे रोकूँ?
एक अद्वितीय बाधा के तहत Svix-id को स्टोर करें और उसी लेनदेन में ईवेंट लागू करें। केवल ईमेल आईडी द्वारा डुप्लिकेट न काटें क्योंकि एक ईमेल में कई मान्य ईवेंट होते हैं।