Skip to Content

Webhooks (प्राप्त करना)

जब आपके SupDesk प्रोजेक्ट में घटनाएँ होती हैं, तो आउटबाउंड webhooks आपके कॉन्फ़िगर किए गए एंडपॉइंट पर HTTP POST अनुरोध पहुँचाते हैं। यह पृष्ठ पेलोड प्रारूप, हस्ताक्षर तंत्र और पुनः प्रयास व्यवहार का दस्तावेज़ीकरण करता है ताकि आप विश्वसनीय webhook रिसीवर बना सकें।

पेलोड प्रारूप

हर webhook डिलीवरी एक मानक आवरण का उपयोग करती है:

{ "event": "post.created", "timestamp": "2026-07-15T12:00:00.000Z", "project_id": "550e8400-e29b-41d4-a716-446655440000", "data": { ... } }
फ़ील्डप्रकारविवरण
eventstringवह घटना जिसने डिलीवरी ट्रिगर की
timestampstringघटना कब हुई इसका ISO 8601 टाइमस्टैम्प
project_idstringउस प्रोजेक्ट का UUID जहाँ घटना हुई
dataobjectघटना-विशिष्ट पेलोड (नीचे देखें)

घटनाएँ

post.created

एक नई फ़ीडबैक पोस्ट सबमिट की गई।

{ "event": "post.created", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "title": "Add dark mode", "type": "feature", "status": "open", "author_type": "end_user", "body": "It would be great to have a dark mode option.", "created_at": "2026-07-15T12:00:00Z" } }

post.updated

एक फ़ीडबैक पोस्ट संपादित की गई।

{ "event": "post.updated", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "title": "Add dark mode (updated)", "type": "feature", "status": "open", "author_type": "end_user", "body": "Updated description.", "created_at": "2026-07-15T12:00:00Z" } }

post.deleted

एक फ़ीडबैक पोस्ट हटाई गई।

{ "event": "post.deleted", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "title": "Add dark mode", "type": "feature", "status": "open", "author_type": "end_user", "body": "It would be great to have a dark mode option.", "created_at": "2026-07-15T12:00:00Z" } }

post.status_changed

किसी पोस्ट की स्थिति बदली गई।

{ "event": "post.status_changed", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "title": "Add dark mode", "type": "feature", "old_status": "open", "new_status": "planned", "author_type": "member", "body": "We're planning this for Q3.", "created_at": "2026-07-15T12:00:00Z" } }

comment.created

किसी पोस्ट में नई टिप्पणी जोड़ी गई।

{ "event": "comment.created", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "post_id": "550e8400-e29b-41d4-a716-446655440001", "post_title": "Add dark mode", "author_type": "end_user", "body": "Any update on this?", "created_at": "2026-07-15T12:00:00Z" } }

comment.updated

एक टिप्पणी संपादित की गई।

{ "event": "comment.updated", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "post_id": "550e8400-e29b-41d4-a716-446655440001", "post_title": "Add dark mode", "author_type": "end_user", "body": "Updated comment.", "created_at": "2026-07-15T12:00:00Z" } }

comment.deleted

एक टिप्पणी हटाई गई।

{ "event": "comment.deleted", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "post_id": "550e8400-e29b-41d4-a716-446655440001", "post_title": "Add dark mode", "author_type": "end_user", "body": "Any update on this?", "created_at": "2026-07-15T12:00:00Z" } }

message.created

एक नया निजी संदेश भेजा गया।

{ "event": "message.created", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "thread_id": "550e8400-e29b-41d4-a716-446655440001", "thread_subject": "Help needed", "sender": "end_user", "body": "I can't find the settings page.", "via": "web", "created_at": "2026-07-15T12:00:00Z" } }

message.updated

एक निजी संदेश संपादित किया गया।

{ "event": "message.updated", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "thread_id": "550e8400-e29b-41d4-a716-446655440001", "thread_subject": "Help needed", "sender": "end_user", "body": "Updated message.", "via": "web", "created_at": "2026-07-15T12:00:00Z" } }

message.deleted

एक निजी संदेश हटाया गया।

{ "event": "message.deleted", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "thread_id": "550e8400-e29b-41d4-a716-446655440001", "thread_subject": "Help needed", "sender": "end_user", "body": "I can't find the settings page.", "via": "web", "created_at": "2026-07-15T12:00:00Z" } }

beta_feedback.created

एक बीटा परीक्षक ने बीटा प्रोग्राम पर फ़ीडबैक भेजा।

{ "event": "beta_feedback.created", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "program": "Acme 2.0 Beta", "category": "bug", "severity": "high", "title": "Crash on export", "body": "The app closes when I export a large file.", "created_at": "2026-07-15T12:00:00Z" } }

severity null हो सकता है।

beta_feedback.deleted

एक बीटा फ़ीडबैक आइटम हटाया गया।

{ "event": "beta_feedback.deleted", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "program": "Acme 2.0 Beta", "category": "bug", "severity": "high", "title": "Crash on export", "body": "The app closes when I export a large file.", "created_at": "2026-07-15T12:00:00Z" } }

waitlist_signup.created

एक आगंतुक वेटलिस्ट में शामिल हुआ।

{ "event": "waitlist_signup.created", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "email": "jamie@example.com", "status": "waiting", "position": 42, "referral_count": 0, "referral_code": "a1b2c3", "source": "portal", "created_at": "2026-07-15T12:00:00Z", "invited_at": null, "joined_at": null } }

invited और joined प्रविष्टियों के लिए position null होता है।

waitlist_signup.invited

एक वेटलिस्ट प्रविष्टि को सूची से आमंत्रित किया गया।

{ "event": "waitlist_signup.invited", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "email": "jamie@example.com", "status": "invited", "position": null, "referral_count": 0, "referral_code": "a1b2c3", "source": "portal", "created_at": "2026-07-15T12:00:00Z", "invited_at": "2026-07-15T12:00:00Z", "joined_at": null } }

waitlist_signup.joined

एक आमंत्रित प्रविष्टि ने स्वीकार किया और शामिल हुई।

{ "event": "waitlist_signup.joined", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "email": "jamie@example.com", "status": "joined", "position": null, "referral_count": 0, "referral_code": "a1b2c3", "source": "portal", "created_at": "2026-07-15T12:00:00Z", "invited_at": "2026-07-15T12:00:00Z", "joined_at": "2026-07-15T12:05:00Z" } }

csat_survey.completed

एक CSAT संतुष्टि सर्वेक्षण रेटिंग के साथ पूरा हुआ।

{ "event": "csat_survey.completed", "data": { "thread_id": "550e8400-e29b-41d4-a716-446655440000", "rating": 5, "comment": "Support was fast and friendly.", "created_at": "2026-07-15T12:00:00Z" } }

rating 1 और 5 के बीच का पूर्णांक है; comment null हो सकता है।

हस्ताक्षर सत्यापन

हर डिलीवरी में एक X-SupDesk-Signature हेडर होता है:

X-SupDesk-Signature: sha256=a1b2c3d4e5f6...

sha256= के बाद का मान कच्ची अनुरोध बॉडी का hex-एन्कोडेड HMAC-SHA256 है, जो आपके webhook के साइनिंग सीक्रेट से गणना किया जाता है।

सत्यापन चरण

  1. कच्ची अनुरोध बॉडी पढ़ें (पहले JSON पार्स न करें)
  2. HMAC-SHA256(signing_secret, raw_body) की गणना करें
  3. hex डाइजेस्ट की तुलना हस्ताक्षर हेडर के मान से करें
  4. टाइमिंग हमलों को रोकने के लिए स्थिर-समय तुलना का उपयोग करें

Node.js उदाहरण

import { createHmac, timingSafeEqual } from "crypto"; function verifySupDeskWebhook(secret, rawBody, signatureHeader) { const expected = createHmac("sha256", secret) .update(rawBody) .digest("hex"); const received = signatureHeader.replace("sha256=", ""); return timingSafeEqual(Buffer.from(expected), Buffer.from(received)); } // Express example app.post("/webhooks/supdesk", express.raw({ type: "application/json" }), (req, res) => { const sig = req.headers["x-supdesk-signature"]; if (!verifySupDeskWebhook(SECRET, req.body, sig)) { return res.status(401).json({ error: "Invalid signature" }); } const event = JSON.parse(req.body); // Process event... res.status(200).json({ ok: true }); });

Python उदाहरण

import hmac import hashlib from flask import Flask, request, jsonify app = Flask(__name__) WEBHOOK_SECRET = "your-signing-secret" def verify_signature(secret: str, body: bytes, header: str) -> bool: expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest() received = header.removeprefix("sha256=") return hmac.compare_digest(expected, received) @app.route("/webhooks/supdesk", methods=["POST"]) def handle_webhook(): sig = request.headers.get("X-SupDesk-Signature", "") if not verify_signature(WEBHOOK_SECRET, request.data, sig): return jsonify(error="Invalid signature"), 401 event = request.get_json() # Process event... return jsonify(ok=True), 200

Ruby उदाहरण

require "openssl" require "sinatra" require "json" WEBHOOK_SECRET = "your-signing-secret" def verify_signature(secret, body, header) expected = OpenSSL::HMAC.hexdigest("SHA256", secret, body) received = header.sub("sha256=", "") Rack::Utils.secure_compare(expected, received) end post "/webhooks/supdesk" do body = request.body.read sig = request.env["HTTP_X_SUPDESK_SIGNATURE"] || "" unless verify_signature(WEBHOOK_SECRET, body, sig) halt 401, { error: "Invalid signature" }.to_json end event = JSON.parse(body) # Process event... status 200 { ok: true }.to_json end

पुनः प्रयास

जब कोई webhook डिलीवरी विफल होती है, तो SupDesk एक्सपोनेंशियल बैकऑफ़ के साथ पुनः प्रयास करता है:

प्रयासविलंब
1तत्काल
21 सेकंड
32 सेकंड

जिन स्थितियों में पुनः प्रयास होता है: 5xx प्रतिक्रियाएँ, नेटवर्क त्रुटियाँ, टाइमआउट (10 सेकंड)।

पुनः प्रयास नहीं: 4xx प्रतिक्रियाएँ (क्लाइंट त्रुटियाँ कॉन्फ़िगरेशन समस्या दर्शाती हैं)।

webhooks का उत्तर देना

  • प्राप्ति स्वीकार करने के लिए 2xx स्थिति कोड लौटाएँ
  • टाइमआउट पुनः प्रयास से बचने के लिए 10 सेकंड के भीतर उत्तर दें
  • यदि आपके लॉजिक में अधिक समय लगे तो घटना को अतुल्यकालिक रूप से संसाधित करें
  • डुप्लिकेट डिलीवरी के लिए वही प्रतिक्रिया लौटाएँ (idempotency)
Last updated on