ThunderPhone 2.0 अब लाइव है।सेल्फ़-सर्व, 2¢/मिनट से।घोषणा पढ़ें

Webhooks

वेबहुक्स अवलोकन

ThunderPhone रीयल-टाइम इवेंट्स कैसे डिलीवर करता है, सिग्नेचर कैसे सत्यापित करें, और लेगेसी तथा एंडपॉइंट-आधारित डिलीवरी मॉडल की तुलना कैसे करें।

ThunderPhone आपके सर्वर को HTTP POST रिक्वेस्ट भेजता है जब कॉल के दौरान कुछ होता है — इनबाउंड कॉल शुरू होती है, कॉल समाप्त होती है, ग्रेडिंग रन पूरा होता है, अलर्ट ट्रिगर होता है, और इसी तरह। दो डिलीवरी मॉडल हैं:

इवेंट्स कैटलॉग में सूचीबद्ध सभी इवेंट टाइप्स वेबहुक एंडपॉइंट्स के माध्यम से डिलीवर किए जाते हैं। छह कॉल-लाइफसाइकल इवेंट्स (telephony.incoming, telephony.complete, telephony.tool, web.incoming, web.complete, web.tool) भी लेगेसी सिंगल-URL वेबहुक को भेजे जाते हैं — यदि आपके पास लेगेसी URL और मैचिंग एंडपॉइंट दोनों हैं, तो आपको इवेंट दोनों पाथ्स पर मिलता है। ब्लॉकिंग व्यवहार (telephony.incoming / web.incoming कॉन्फ़िगरेशन एक्सचेंज और वेबहुक-मोड टूल डिस्पैच) केवल लेगेसी पाथ पर होता है; प्रत्येक एंडपॉइंट डिलीवरी फायर-एंड-फॉरगेट नोटिफिकेशन होती है।

पेलोड फ़ॉर्मेट

एंडपॉइंट डिलीवरी data, event_id, और type के साथ एक JSON ऑब्जेक्ट होती है:

{
  "data": {
    "call_id": 987654321,
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  },
  "event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
  "type": "telephony.incoming"
}

event_id प्रत्येक उत्सर्जित इवेंट के लिए यूनिक होता है। यह रिट्राइज़ और इवेंट प्राप्त करने वाले प्रत्येक एंडपॉइंट पर समान होता है — इसके आधार पर डीडुप्लिकेट करें।

लेगेसी सिंगल-URL वेबहुक समान type और data भेजता है, लेकिन event_id के बिना:

{
  "type": "telephony.incoming",
  "data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}

वायर पर, प्रत्येक बॉडी कैनॉनिकली सीरियलाइज़ होती है — कीज़ वर्णानुक्रम में सॉर्टेड, कोई व्हाइटस्पेस नहीं, UTF-8। इन डॉक्स में प्रिटी-प्रिंटेड उदाहरण केवल पठनीयता के लिए हैं।

इवेंट टाइप्स और पेलोड फ़ील्ड्स की पूरी सूची के लिए इवेंट्स कैटलॉग देखें।

सिग्नेचर वेरिफिकेशन

हर अनुरोध में दो हस्ताक्षर होते हैं, दोनों एंडपॉइंट के secret (या लेगेसी डिलीवरी के लिए आपके संगठन-स्तरीय वेबहुक secret) के साथ HMAC-SHA256 द्वारा की किए जाते हैं:

  • X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<hex> टाइमस्टैम्प, मेथड, पाथ और क्वेरी, तथा रॉ बॉडी पर हस्ताक्षर करता है। इसे सत्यापित करें, और उन अनुरोधों को अस्वीकार करें जिनका t आपकी घड़ी से 5 मिनट से अधिक अलग हो, ताकि कैप्चर किए गए अनुरोध को बाद में दोबारा चलाया न जा सके। भेजे जाने पर रिट्राई पर फिर से हस्ताक्षर किए जाते हैं।
  • X-ThunderPhone-Signature केवल रॉ बॉडी पर हस्ताक्षर करता है। मौजूदा वेरिफ़ायर काम करते रहें, इसलिए इसे बिना बदलाव के अभी भी भेजा जाता है।

चरण

  1. किसी भी पार्सिंग से पहले हेडर, मेथड, रॉ पाथ और क्वेरी, और रॉ बॉडी पढ़ें।
  2. अपने सीक्रेट के साथ <t>\n<METHOD>\n<path and query>\n<body> का हेक्स HMAC-SHA256 कंप्यूट करें।
  3. अगर t 300 सेकंड से अधिक अलग है, या कॉन्स्टेंट-टाइम तुलना में परिणाम v1 से मेल नहीं खाता है, तो रिक्वेस्ट अस्वीकार करें।

बॉडी कैनॉनिकल JSON सीरियलाइज़ेशन हैं (सॉर्ट की गई कीज़, कॉम्पैक्ट सेपरेटर), और हम ठीक उन्हीं बाइट्स पर साइन करते हैं जो हम ट्रांसमिट करते हैं। वेरिफिकेशन गाइड में सटीक साइन्ड स्ट्रिंग, एक वर्क्ड उदाहरण, SDK के बिना कोड, और लेगेसी हेडर है।

Python (Flask)
from flask import Flask, abort, request
from thunderphone import verify_signature
 
app = Flask(__name__)
 
@app.post("/thunderphone-webhook")
def handle():
    query = request.query_string.decode()
    if not verify_signature(
        request.headers.get("X-ThunderPhone-Signature-V2"),
        secret=WEBHOOK_SECRET,
        method=request.method,
        path=request.path + (f"?{query}" if query else ""),
        body=request.get_data(),  # raw bytes
    ):
        abort(401)
    event = request.get_json()
    # dispatch on event["type"] …
    return "", 204
Node.js (Express)
import express from "express";
import { verifySignature } from "@thunderphone/sdk";
 
const app = express();
app.post(
  "/thunderphone-webhook",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const ok = verifySignature({
      header: req.header("X-ThunderPhone-Signature-V2"),
      secret: process.env.WEBHOOK_SECRET,
      method: req.method,
      path: req.originalUrl,
      body: req.body,
    });
    if (!ok) return res.sendStatus(401);
    const event = JSON.parse(req.body.toString("utf8"));
    // dispatch on event.type …
    res.sendStatus(204);
  },
);

डिलीवरी सेमांटिक्स

ये सेमांटिक्स एंडपॉइंट डिलीवरी पर लागू होते हैं। लेगसी सिंगल-URL webhook एक सिंगल सिंक्रोनस प्रयास है, जिसमें कोई रीट्राई नहीं होता, सिवाय फोन-कॉल telephony.incoming कॉन्फ़िगरेशन एक्सचेंज के, जिसे एक बार रीट्राई किया जाता है।

रीट्राई

हर इवेंट का तुरंत एक बार प्रयास किया जाता है। कोई भी 2xx रिस्पॉन्स डिलीवरी को स्वीकार करता है। किसी भी अन्य परिणाम पर (non-2xx, कनेक्शन एरर, टाइमआउट), हम पहले प्रयास के बाद 1 मिनट, 5 मिनट, 30 मिनट, 2 घंटे, 6 घंटे, 12 घंटे और 24 घंटे पर रीट्राई करते हैं — 24 घंटों में 8 प्रयास। अगर हर प्रयास विफल हो जाता है, तो डिलीवरी रुक जाती है और एंडपॉइंट को webhook endpoints में status="failing" के रूप में मार्क किया जाता है; हम आपके संगठन के ओनर्स और एडमिन्स को ईमेल करते हैं और इसे डैशबोर्ड में दिखाते हैं। पेलोड के स्थायी रूप से स्वीकार होते ही 2xx लौटाएँ; असिंक्रोनस रूप से प्रोसेस करें। एंडपॉइंट टेस्ट API से किए गए टेस्ट सेंड्स को पहले प्रयास के लगभग एक मिनट बाद एक रीट्राई मिलता है और वे कभी भी एंडपॉइंट का स्टेटस नहीं बदलते।

क्रम

डिलीवरी क्रम best-effort है। व्यवहार में हम इवेंट के एमिट होने के क्रम में डिलीवर करते हैं, लेकिन विफलता होने पर रिट्राई क्रम बदल सकते हैं। हमेशा call_id / ऑब्जेक्ट आईडी के आधार पर डीडुप्लिकेट और रिकन्साइल करें।

डुप्लिकेट

डिलीवरी कम-से-कम-एक-बार होती है: ऐसे रिस्पॉन्स के बाद रिट्राई जिसे हमने नहीं देखा, किसी इवेंट को डुप्लिकेट कर सकता है। हर रिट्राई में वही event_id होता है, इसलिए प्रोसेस किए गए आईडी स्टोर करें और दोहराव छोड़ दें। event_id एंडपॉइंट्स के बीच भी साझा होता है — एक ही इवेंट को सब्सक्राइब करने वाले दो एंडपॉइंट्स को वही event_id मिलता है।

टाइमआउट

एंडपॉइंट डिलीवरी में प्रति प्रयास 30 सेकंड का टाइमआउट होता है। लेगसी पाथ पर, लाइव कॉल व्यवहार नियंत्रित करने वाले ब्लॉकिंग रिक्वेस्ट — telephony.incoming / web.incoming कॉन्फ़िगरेशन एक्सचेंज — फोन कॉल के पहले प्रयास के लिए 10 सेकंड तक और उसके एक रीट्राई सहित पूरे एक्सचेंज के लिए 13 सेकंड तक सीमित हैं, और विजेट सेशन के लिए 10 सेकंड तक। धीमा रिस्पॉन्स कॉल पिकअप में देरी करता है, इसलिए कुछ सेकंड के भीतर जवाब देने का लक्ष्य रखें। Webhook-मोड टूल डिस्पैच डिफ़ॉल्ट रूप से 20 सेकंड की अनुमति देता है, और टूल डिक्लेरेशन टॉप-लेवल timeout सेट कर सकते हैं।

सोर्स IP

आउटबाउंड webhooks ThunderPhone की क्लाउड IP रेंज से आते हैं। अगर आपके फ़ायरवॉल को allowlist की आवश्यकता है, तो सपोर्ट से संपर्क करें और हम मौजूदा रेंज साझा करेंगे।

लेगेसी और एंडपॉइंट-आधारित webhooks के बीच चयन

सुविधालेगेसी (/v1/webhook)एंडपॉइंट्स (/v1/developer/webhook-endpoints)
URL की संख्याप्रति संगठन 1प्रति संगठन कई
इवेंट कवरेजकेवल telephony.* / web.*सभी 10 इवेंट प्रकार
इवेंट फ़िल्टर—प्रति एंडपॉइंट
रिट्राइकोई नहीं, फ़ोन-कॉल कॉन्फ़िगरेशन एक्सचेंज के लिए एक को छोड़कर24 घं. में 8 प्रयास
एनवेलपtype + datatype + data + event_id
सीक्रेट रोटेशनएकल सीक्रेट को बदलता हैप्रति-एंडपॉइंट सीक्रेट
हटाए बिना अक्षम करेंPUT /v1/webhook के साथ {"url": ""}status=disabled
स्टेटस दृश्यता—active / disabled / failing
ब्लॉकिंग कॉन्फ़िग एक्सचेंजहाँ (telephony.incoming / web.incoming)कभी नहीं — केवल नोटिफिकेशन
इसके लिए सबसे उपयुक्तडायनामिक कॉल कॉन्फ़िगरेशनप्रोडक्शन में इवेंट कंजम्प्शन

नए इंटीग्रेशन को एंडपॉइंट-आधारित webhooks के माध्यम से इवेंट कंज्यूम करने चाहिए। लेगेसी URL केवल तभी रखें (या जोड़ें) जब आप पिकअप के समय कॉल को डायनामिक रूप से कॉन्फ़िगर करते हैं या webhook-मोड tool dispatch का उपयोग करते हैं — वे request/response एक्सचेंज केवल लेगेसी पथ पर चलते हैं।


संबंधित