Webhooks નો પરિચય

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. આ દસ્તાવેજોમાંના સુંદર રીતે ફોર્મેટ કરેલા ઉદાહરણો ફક્ત વાંચનીયતા માટે છે.

ઇવેન્ટ પ્રકારો અને પેલોડ ફીલ્ડ્સની સંપૂર્ણ સૂચિ માટે ઇવેન્ટ્સ કૅટલૉગ જુઓ.

સહીની ચકાસણી

દરેક વિનંતીમાં X-ThunderPhone-Signature હેડરમાં કાચા વિનંતી બોડી પર HMAC-SHA256 સહી હોય છે. સહી કી એ એન્ડપોઇન્ટનું secret છે (અથવા લેગસી ડિલિવરી માટે તમારું org-સ્તરનું webhook secret).

પગલાં

  1. કોઈપણ પાર્સિંગ પહેલાં કાચા વિનંતી બોડી વાંચો.
  2. hmac_sha256(secret, body).hexdigest() ની ગણતરી કરો.
  3. X-ThunderPhone-Signature હેડર સાથે સ્થિર સમયમાં સરખામણી કરો.

અમે ટ્રાન્સમિટ કરીએ છીએ તે જ બાઇટ્સ પર સહી કરીએ છીએ, અને તે બાઇટ્સ કેનોનિકલ JSON સિરિયલાઇઝેશન છે (ક્રમબદ્ધ કીઓ, કોમ્પેક્ટ વિભાજકો). તેથી કાચા બોડી સામે ચકાસણી હંમેશાં કાર્ય કરે છે — અને જો તમારું ફ્રેમવર્ક તમને માત્ર પાર્સ કરેલું JSON આપે, તો તેને ક્રમબદ્ધ કીઓ અને કોમ્પેક્ટ વિભાજકો સાથે ફરીથી સિરિયલાઇઝ કરવાથી એકસરખા બાઇટ્સ મળે છે. બંને રીતો ચકાસણી માર્ગદર્શિકામાં આવરી લેવામાં આવી છે.

import hmac
import hashlib

def verify_signature(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode("utf-8"),
        body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, signature or "")

# Example Flask handler
from flask import Flask, request, abort
app = Flask(__name__)

@app.post("/thunderphone-webhook")
def handle():
    body = request.get_data()
    sig = request.headers.get("X-ThunderPhone-Signature", "")
    if not verify_signature(body, sig, WEBHOOK_SECRET):
        abort(401)
    event = request.get_json()
    # dispatch on event["type"] …
    return "", 204
import crypto from "node:crypto";
import express from "express";

function verifySignature(body, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(body)
    .digest("hex");
  if (!signature || expected.length !== signature.length) return false;
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature),
  );
}

const app = express();
app.post(
  "/thunderphone-webhook",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const sig = req.header("X-ThunderPhone-Signature") || "";
    if (!verifySignature(req.body, sig, process.env.WEBHOOK_SECRET)) {
      return res.sendStatus(401);
    }
    const event = JSON.parse(req.body.toString("utf8"));
    // dispatch on event.type …
    res.sendStatus(204);
  },
);

વિતરણનું વર્તન

આ સિમેન્ટિક્સ એન્ડપૉઇન્ટ વિતરણો પર લાગુ પડે છે. લેગસી સિંગલ-URL વેબહૂક કોઈ રિટ્રાય વિના એક જ સિંક્રોનસ પ્રયાસ કરે છે.

રિટ્રાય

દરેક ઇવેન્ટનો તરત એક વખત પ્રયાસ થાય છે. કોઈપણ 2xx પ્રતિસાદ વિતરણને સ્વીકારે છે. અન્ય કોઈપણ પરિણામ પર (non-2xx, કનેક્શન ભૂલ, સમયસમાપ્તિ) અમે પ્રથમ પ્રયાસ પછી 1 મિનિટ, 5 મિનિટ, 30 મિનિટ, 2 કલાક, 6 કલાક, 12 કલાક અને 24 કલાકે રિટ્રાય કરીએ છીએ — 24 કલાકમાં કુલ 8 પ્રયાસો. દરેક પ્રયાસ નિષ્ફળ જાય તો વિતરણ અટકી જાય છે અને એન્ડપૉઇન્ટને વેબહૂક એન્ડપૉઇન્ટ્સમાં status="failing" તરીકે ચિહ્નિત કરવામાં આવે છે. પેલોડ સ્થાયી રીતે સ્વીકારવામાં આવે તેટલી વહેલી તકે 2xx પરત કરો; અસિંક્રોનસ રીતે પ્રોસેસ કરો.

ક્રમ

વિતરણનો ક્રમ શ્રેષ્ઠ-પ્રયાસ આધારિત છે. વ્યવહારમાં અમે ઇવેન્ટ્સ ઉત્પન્ન થાય તે ક્રમમાં વિતરિત કરીએ છીએ, પરંતુ નિષ્ફળતા પર રિટ્રાય ક્રમ બદલી શકે છે. હંમેશા call_id / ઑબ્જેક્ટ ID દ્વારા ડિડુપ્લિકેટ કરો અને સમાધાન કરો.

ડુપ્લિકેટ્સ

વિતરણ ઓછામાં ઓછું એક વખત થાય છે: જે પ્રતિસાદ અમને મળ્યો જ નથી તેના પછીનો રિટ્રાય ઇવેન્ટની ડુપ્લિકેટ નકલ બનાવી શકે છે. દરેક રિટ્રાયમાં સમાન event_id હોય છે, તેથી પ્રોસેસ કરેલા ID સંગ્રહો અને પુનરાવર્તનો છોડો. event_id એન્ડપૉઇન્ટ્સ વચ્ચે પણ શેર થાય છે — સમાન ઇવેન્ટને સબ્સ્ક્રાઇબ કરેલા બે એન્ડપૉઇન્ટ્સને સમાન event_id મળે છે.

સમયસમાપ્તિ

એન્ડપૉઇન્ટ વિતરણોમાં દરેક પ્રયાસ માટે 30 સેકન્ડની સમયસમાપ્તિ હોય છે. લેગસી પાથ પર, લાઇવ કૉલનું વર્તન નિયંત્રિત કરતી બ્લોકિંગ રિક્વેસ્ટ્સ — telephony.incoming / web.incoming કન્ફિગરેશન એક્સચેન્જ — 10 સેકન્ડ પછી સમયસમાપ્ત થાય છે, પરંતુ ધીમો પ્રતિસાદ કૉલ પિકઅપમાં વિલંબ કરે છે, તેથી લગભગ બે સેકન્ડમાં જવાબ આપવાનો પ્રયાસ કરો. વેબહૂક-મોડ ટૂલ ડિસ્પેચ 20 સેકન્ડની મંજૂરી આપે છે.

સ્રોત IP

આઉટબાઉન્ડ વેબહૂક્સ ThunderPhoneની ક્લાઉડ IP રેન્જમાંથી આવે છે. જો તમારા ફાયરવૉલને અલાઉલિસ્ટની જરૂર હોય, તો સપોર્ટનો સંપર્ક કરો અને અમે વર્તમાન રેન્જ શેર કરીશું.

લેગસી અને એન્ડપૉઇન્ટ-આધારિત વેબહૂક્સ વચ્ચે પસંદગી

સુવિધાલેગસી (/v1/webhook)એન્ડપૉઇન્ટ્સ (/v1/developer/webhook-endpoints)
URLની સંખ્યાપ્રતિ સંસ્થા 1પ્રતિ સંસ્થા અનેક
ઇવેન્ટ કવરેજમાત્ર telephony.* / web.*તમામ 10 ઇવેન્ટ પ્રકારો
ઇવેન્ટ ફિલ્ટરદરેક એન્ડપૉઇન્ટ માટે
રિટ્રાયકોઈ નહીં24 કલાકમાં 8 પ્રયાસો
એન્વલપtype + datatype + data + event_id
સિક્રેટ રોટેશનએકલ સિક્રેટને બદલે છેદરેક એન્ડપૉઇન્ટ માટે સિક્રેટ
કાઢી નાખ્યા વિના અક્ષમ કરોstatus=disabled
સ્ટેટસ દૃશ્યતાactive / disabled / failing
બ્લોકિંગ કન્ફિગરેશન એક્સચેન્જહા (telephony.incoming / web.incoming)ક્યારેય નહીં — માત્ર સૂચનાઓ
આ માટે શ્રેષ્ઠડાયનેમિક કૉલ કન્ફિગરેશનપ્રોડક્શનમાં ઇવેન્ટનો ઉપયોગ

નવી ઇન્ટિગ્રેશન્સે એન્ડપૉઇન્ટ-આધારિત વેબહૂક્સ દ્વારા ઇવેન્ટ્સનો ઉપયોગ કરવો જોઈએ. જો તમે કૉલ પિકઅપ સમયે ડાયનેમિક રીતે કૉલ કન્ફિગર કરો છો અથવા વેબહૂક-મોડ ટૂલ ડિસ્પેચનો ઉપયોગ કરો છો, તો જ લેગસી URL રાખો (અથવા ઉમેરો) — આ રિક્વેસ્ટ/રિસ્પોન્સ એક્સચેન્જ માત્ર લેગસી પાથ પર ચાલે છે.


સંબંધિત