अपने सॉफ़्टवेयर को WhatsApp से जोड़ना
API Management वह ज़रिया है जिससे कोई दूसरा सिस्टम — आपका बिलिंग सॉफ़्टवेयर, आपका ऑनलाइन स्टोर, आपका अपना बैकएंड — WizMessage के ज़रिये WhatsApp मैसेज भेजता है। यहाँ आप उसे एक API key जारी करते हैं, बताते हैं कि वह कौन-सा अप्रूव्ड WhatsApp टेम्पलेट भेज सकता है, और उसे एक वेबहुक से जोड़ देते हैं ताकि जवाब वापस आ सकें। यह गाइड पूरा रास्ता दिखाती है, और फिर उस REST API का ब्यौरा देती है जिसे आपके डेवलपर कॉल करेंगे।
डैशबोर्ड
आपकी API keys कहाँ रहती हैं
आपकी जारी की हुई हर key यहाँ API Keys के नीचे दिखती है। हर पंक्ति में key का स्टेटस, उसका पब्लिक प्रीफ़िक्स (key बनाने के बाद उसका बस यही हिस्सा दोबारा दिखाया जाता है), और आज उसने कितनी कॉल की हैं, यह दिखता है। "Manage" उस key को खोलता है; टॉगल उसे डिलीट किए बिना रोक देता है।


ऐसी key जो अभी पूरी नहीं हुई है
जिस key से कोई टेम्पलेट मैप नहीं है, उस पर "Needs setup" बैज लगा रहता है। वह ऑथेंटिकेट तो कर सकती है, लेकिन जब तक आप कोई टेम्पलेट मैप नहीं करते तब तक टेम्पलेट मैसेज नहीं भेज सकती — यानी अधूरा कॉन्फ़िगर किया गया इंटीग्रेशन बाद में भेजते समय फ़ेल होने के बजाय एक नज़र में ही दिख जाता है।

निर्देशित सेटअप
चरण 1 — आप क्या जोड़ रहे हैं?
"Connect your software" एक चार-चरणों वाला विज़ार्ड खोलता है। शुरुआत key को उस सिस्टम का नाम देकर करें जो उसे इस्तेमाल करेगा, और उससे मेल खाता प्रीसेट चुनें। प्रीसेट सिर्फ़ काम के फ़ील्ड नाम सुझाते हैं — बिलिंग प्रीसेट invoice_number, amount, due_date, customer_name सुझाता है — वे यह सीमित नहीं करते कि आप क्या मैप कर सकते हैं।


चरण 2 — मैसेज चुनें
अपने अप्रूव्ड WhatsApp टेम्पलेट में से एक चुनें। टेम्पलेट Meta पर रहते हैं, यहाँ नहीं — यह सूची आपके जुड़े हुए WhatsApp अकाउंट से लाइव लाई जाती है, और सिर्फ़ APPROVED टेम्पलेट ही भेजे जा सकते हैं। यह चरण वैकल्पिक है: अगर key सिर्फ़ सादा टेक्स्ट ही भेजेगी तो इसे छोड़ दें और टेम्पलेट बाद में मैप कर लें।

चरण 3 — जवाब कहाँ जाने चाहिए?
जब कोई आपके मैसेज का जवाब देता है, या कोई डिलीवरी रिपोर्ट वापस आती है, तो हम उसे आपके नियंत्रण वाले URL पर POST कर देते हैं। अगर आपका सिस्टम सिर्फ़ भेजता ही है तो इसे बंद रहने दें। आप इसे बाद में key के Webhooks टैब से जोड़ सकते हैं — यहाँ कुछ भी स्थायी नहीं है।

चरण 4 — लाइव करें
पिछले चरण पर Next दबाना ही असल में key बनाता है — यह स्क्रीन उसकी पुष्टि है। तीनों मान अभी कॉपी कर लें: API key, API secret और वेबहुक साइनिंग सीक्रेट ठीक एक ही बार दिखाए जाते हैं और बाद में इन्हें वापस नहीं पाया जा सकता। अगर सीक्रेट खो गया तो आपको उसे रोटेट करना पड़ेगा, यानी जो भी सिस्टम उसे इस्तेमाल कर रहा था उसे अपडेट करना होगा।

key को मैनेज करना
Overview
key खोलते ही आप Overview पर पहुँचते हैं: वह क्या कर सकती है, कितनी इस्तेमाल हो रही है, और किन एंडपॉइंट को कॉल कर सकती है। उपयोग की गिनती रिक्वेस्ट लॉग से पढ़ी जाती है, इसलिए वह असली ट्रैफ़िक दिखाती है।


ऐसी key जिसे अब भी सेट अप करना बाकी है
जिस key से कोई टेम्पलेट मैप नहीं है, वह इसके बजाय Setup टैब पर खुलती है — वही विज़ार्ड, इनलाइन। ध्यान दें कि टैब पिछले स्क्रीनशॉट से अलग हैं: जब तक किसी key के पास कम से कम एक टेम्पलेट न हो, Templates और Webhooks दिखाए ही नहीं जाते, क्योंकि उनके काम करने के लिए अभी कुछ है ही नहीं।


Templates
हर कार्ड एक ऐसा टेम्पलेट है जिसे यह key भेज सकती है। बॉडी टेक्स्ट वही मैसेज है जो Meta पर अप्रूव हुआ है, और उसके नीचे की चिप्स वे वेरिएबल नाम हैं जो आपका सिस्टम भरकर देगा। "Try it" एक टेस्ट भेजता है, "Get code" आठ भाषाओं में तैयार रिक्वेस्ट बना देता है।


वेरिएबल पढ़ना — यही एक चीज़ है जिस पर ठहरकर ध्यान देना चाहिए
payment_failed_alert कार्ड को देखिए। उसका मैसेज पहले {{1}}, फिर {{3}}, फिर {{2}} के क्रम में चलता है — टेक्स्ट में प्लेसहोल्डर संख्या-क्रम में नहीं हैं। नीचे दी गई चिप्स संख्या-क्रम में सूचीबद्ध हैं: customer_name {{1}} में भरता है, renewal_date {{2}} में, और plan_name {{3}} में। अपने मानों को हमेशा संख्या से मिलाइए, कभी उस क्रम से नहीं जिसमें प्लेसहोल्डर वाक्य में दिख जाते हैं। यह चूक सबसे ज़्यादा अनूदित टेम्पलेट में होती है, जहाँ शब्द-क्रम बदलने से प्लेसहोल्डर इधर-उधर खिसक जाते हैं।

हर टेम्पलेट पर मौजूद तीन बटन
"Try it" — बिना कोई कोड लिखे टेस्ट भेजें
पेपर-प्लेन बटन इस टेम्पलेट को हर वेरिएबल नाम के लिए एक-एक नमूना मान के साथ पहले से भरा हुआ खोलता है। आपके डेवलपर इसे छुएँ, उससे पहले मैपिंग सही है या नहीं यह जाँचने का यही सबसे तेज़ तरीका है। टॉगल पर ध्यान दें: "Simulate Only" डिफ़ॉल्ट है और कुछ भी बाहर नहीं जाता — सर्वर आपका पेलोड जस का तस लौटा देता है। इसे "Send Real Message" पर करते ही बॉक्स में लिखे नंबर पर असली WhatsApp मैसेज चला जाता है, और उसका शुल्क भी लगता है।


सिमुलेटेड सेंड आपको क्या लौटाता है
Simulate Only मोड में Send Request दबाने पर रिक्वेस्ट वैसी ही लौटती है जैसी प्लेटफ़ॉर्म को मिली थी, साथ में HTTP स्टेटस और राउंड-ट्रिप समय। इसे बनावट की जाँच मानिए, पूर्वाभ्यास नहीं: यह पुष्टि करता है कि आपका JSON पढ़ा गया और key स्वीकार हुई, लेकिन यह आपके वेरिएबल नामों को मैपिंग के विरुद्ध जाँचता नहीं है और Meta से कभी संपर्क नहीं करता। जो पेलोड सिमुलेशन में साफ़ निकलता है, वह असल भेजने पर फिर भी अस्वीकार हो सकता है। मैपिंग को असल में परखने के लिए Send Real Message चालू कीजिए और अपने ही फ़ोन पर भेजिए।

"Get code" — रिक्वेस्ट, आपके लिए लिखी हुई
एंगल-ब्रैकेट वाला बटन ठीक इसी टेम्पलेट के लिए आठ भाषाओं में चलने लायक रिक्वेस्ट बनाता है: cURL, JavaScript, Node.js, Python, PHP, Ruby, Go और C#. जो भी इंटीग्रेशन लिख रहा है, उसे यह सौंप दीजिए। वेरिएबल आपकी मैपिंग के नाम वाले {{placeholders}} के रूप में दिखते हैं, और क्रेडेंशियल YOUR_API_KEY / YOUR_API_SECRET के रूप में छोड़ दिए जाते हैं — यह डायलॉग आपकी असली key कभी नहीं छापता, इसलिए स्निपेट किसी टिकट में चिपकाना सुरक्षित है।

भाषा बदलना
ऊपर दी किसी भी भाषा पर क्लिक कीजिए और स्निपेट उसी के लिए दोबारा लिख दिया जाता है — वही कॉल, वही हेडर, उस भाषा का HTTP क्लाइंट। हर स्निपेट पहली बार क्लिक करने पर ही बनता है, इसलिए पहली बार बदलने पर थोड़ी देर का स्पिनर सामान्य है। Copy स्निपेट को जस का तस उठा लेता है: वह पूरा है, इम्पोर्ट समेत, और अगर इस key के लिए साइनेचर ज़रूरी हैं तो साइनिंग चरण भी उसमें पहले से मौजूद है।

"Edit" — बदलें कि आपका सिस्टम क्या भेजता है
पेंसिल मैपिंग को ही खोलती है। ऊपर दिया फ़ोन मॉक-अप असली मैसेज है जिसमें आपके मौजूदा नाम भर दिए गए हैं, इसलिए आप देख सकते हैं कि ग्राहक क्या पढ़ेगा। उसके नीचे, पहचाने गए हर वेरिएबल का नाम बदला जा सकता है, क्रम बदला जा सकता है, उसे अनिवार्य किया जा सकता है या कोई प्रकार दिया जा सकता है — तारीख़, मुद्रा राशि, इमेज। किसी वेरिएबल का नाम बदलने पर वह आपके API पेलोड में भी बदल जाता है, इसलिए जो सिस्टम अब भी पुराना नाम भेज रहा है वह फ़ेल होने लगेगा: दोनों को साथ-साथ बदलिए।

Test API — वही टूल, कोई भी एंडपॉइंट
टैब के ऊपर मौजूद "Test API" दरअसल टेम्पलेट की बंदिश के बिना "Try it" ही है: तीनों सेंड एंडपॉइंट में से कोई भी चुनिए, दूसरे ड्रॉपडाउन से टेम्पलेट बदलिए, और बॉडी को जैसे चाहें बदलिए। इसका इस्तेमाल कच्ची /messages/text या /messages/template कॉल जाँचने के लिए कीजिए, जिनका अपना कोई कार्ड नहीं है क्योंकि वे किसी मैपिंग से बँधी नहीं हैं। ध्यान दें कि इस टेम्पलेट के वेरिएबल अब भी body_1, body_2, body_3 कहलाते हैं — बिना मैपिंग वाला टेम्पलेट ऐसा ही दिखता है, और इसी को ठीक करने के लिए "Edit" है।

जवाब
Webhooks — जवाब वापस पाना
भेजना तो इंटीग्रेशन का आधा हिस्सा ही है। अपने HTTPS एंडपॉइंट पर एक वेबहुक लगाइए और WizMessage उस पर इनबाउंड मैसेज और डिलीवरी अपडेट POST करेगा। साइनिंग सीक्रेट जनरेट होते समय एक ही बार दिखाया जाता है; हर डिलीवरी पर उसे वेरिफ़ाई कीजिए ताकि आपको पक्का पता रहे कि कॉल वाकई हमारी ओर से आई है।

आपको कौन-से इवेंट मिलेंगे
चुनिए कि यह एंडपॉइंट कौन-से इवेंट प्राप्त करे। हर इवेंट अपने अलग POST के रूप में आता है।
| इवेंट | कब भेजा जाता है |
|---|---|
message.received | किसी ग्राहक ने आपको मैसेज भेजा। |
message.reaction | किसी ने इमोजी रिएक्शन जोड़ा या हटाया। दोनों दिशाओं में ट्रिगर होता है — देखें रिएक्शन। |
message.sent | कोई मैसेज बाहर गया — API से, वेब डैशबोर्ड से, या खुद बिज़नेस के फ़ोन पर टाइप किया हुआ। data.source बताता है कि कौन-सा। |
message.delivered | मैसेज पाने वाले के डिवाइस तक पहुँच गया। |
message.read | पाने वाले ने उसे खोल लिया। |
message.failed | भेजना या डिलीवरी विफल रही; कारण data.error में होता है। |
ध्यान दें:
message.receivedऔर इनबाउंडmessage.reactionतभी डिलीवर होते हैं जब खाते का चैटबॉट सिस्टम Webhook पर सेट हो। किसी और सेटिंग पर इनबाउंड मैसेज बॉट के पास चले जाते हैं और आपका एंडपॉइंट कभी कॉल नहीं होता — ऐसा होने पर Webhooks टैब आपको चेतावनी देता है। व्यवसाय खुद जो रिएक्शन भेजता है (direction: "outbound"), उन पर इस सेटिंग का कोई असर नहीं पड़ता।
ध्यान दें: व्यवसाय अपने फ़ोन से जो रिएक्शन भेजता था, वे पहले
message.sentके रूप में आते थे जिसकी बॉडी"[Unsupported message type]"होती थी। अब वेmessage.reactionके रूप मेंdirection: "outbound"के साथ आते हैं। अगर आप उन पर निर्भर थे तो नया इवेंट टिक कर लें।
डिलीवरी कम-से-कम-एक-बार (at-least-once) होती है। सिर्फ़ X-Webhook-Id हेडर के बजाय event और data.message_id दोनों के आधार पर डुप्लिकेट हटाइए, और जल्दी 2xx जवाब दीजिए।
REST API रेफ़रेंस
ऊपर की हर चीज़ key को कॉन्फ़िगर करती है। असल में आपके डेवलपर यही कॉल करते हैं। बेस URL https://wizmessage.com/api/v1/external है। हर एंडपॉइंट के लिए नीचे दिए ऑथ हेडर ज़रूरी हैं और वह key की रेट लिमिट के दायरे में आता है।
ऑथेंटिकेशन
हर रिक्वेस्ट के साथ अपनी API key भेजें। अगर key पर "Require signature" चालू है, तो आपको रिक्वेस्ट को साइन भी करना होगा — और जिस key पर यह चालू है, वह बिना साइन की गई किसी भी कॉल को सीधे अस्वीकार कर देगी।
| हेडर | मान |
|---|---|
X-API-Key | आपकी API key — पूरा pk_live_… मान, न कि सिर्फ़ वह प्रीफ़िक्स जो डैशबोर्ड में दिखता है। |
X-Timestamp | सेकंड में Unix टाइमस्टैम्प। सर्वर के समय से 5 मिनट से ज़्यादा अंतर होने पर अस्वीकार कर दिया जाता है। |
X-API-Signature | timestamp + "." + rawBody का HMAC-SHA256, SHA256(api_secret) को key बनाकर, लोअरकेस hex में। |
नोट: सिग्नेचर तभी लागू होते हैं जब key पर
require_signatureचालू हो। अगर नहीं है, तो मैसेज भेजने के लिए अकेली API key ही काफ़ी है — और ठीक इसीलिए key एक सीक्रेट है, कोई पहचानकर्ता नहीं। इसे पासवर्ड की तरह समझें: यह एक ही बार दिखाई जाती है, और जिसके पास भी यह होगी वह आपके ग्राहकों को मैसेज कर सकता है।
const crypto = require('node:crypto')
const body = JSON.stringify({ to: '+919876543210', message: 'Hello' })
const timestamp = Math.floor(Date.now() / 1000).toString()
const secretHash = crypto.createHash('sha256').update(API_SECRET).digest('hex')
const signature = crypto.createHmac('sha256', secretHash)
.update(timestamp + '.' + body)
.digest('hex')
await fetch('https://wizmessage.com/api/v1/external/messages/text', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY,
'X-Timestamp': timestamp,
'X-API-Signature': signature,
},
body,
})
एंडपॉइंट
| मेथड | पाथ | उद्देश्य |
|---|---|---|
POST | /messages/text | सादा टेक्स्ट मैसेज भेजें। यह सिर्फ़ खुली 24-घंटे की कन्वर्सेशन विंडो के भीतर ही काम करता है। |
POST | /messages/media | दस्तावेज़, इमेज, वीडियो या ऑडियो फ़ाइल भेजें। यह सिर्फ़ खुली 24-घंटे की कन्वर्सेशन विंडो के भीतर ही काम करता है। |
POST | /messages/reaction | किसी मैसेज पर इमोजी से रिएक्ट करें, या भेजा हुआ रिएक्शन हटाएँ। |
POST | /messages/template | टेम्पलेट भेजें, जिसमें Meta का रॉ components ऐरे आप खुद देते हैं। |
POST | /messages/template/send | डैशबोर्ड में आपके कॉन्फ़िगर किए मैपिंग का इस्तेमाल करके टेम्पलेट भेजें। आम तौर पर यही इस्तेमाल करना चाहिए। |
POST | /messages/interactive/list | इंटरैक्टिव लिस्ट मैसेज भेजें। |
POST | /messages/interactive/button | अधिकतम तीन रिप्लाई बटन भेजें। |
GET | /messages/:uuid | आपके भेजे हुए किसी मैसेज की डिलीवरी स्थिति देखें। |
POST | /media/upload | Meta पर PDF/इमेज/वीडियो अपलोड करें और टेम्पलेट हेडर में इस्तेमाल के लिए media_id पाएँ। |
GET | /templates | इस key के लिए उपलब्ध टेम्पलेट की सूची देखें। |
GET | /templates/:name | किसी एक टेम्पलेट का विवरण लाएँ। |
मैप किया गया टेम्पलेट भेजना
यह वह पेलोड है जो Templates टैब के साथ जोड़ी बनाता है। आप वेरिएबल नाम से भेजते हैं — वही नाम जो टेम्पलेट कार्ड पर चिप्स के रूप में दिखते हैं — और प्लेटफ़ॉर्म आपके लिए Meta के components तैयार कर देता है। टेम्पलेट मैप करने का पूरा मक़सद यही है: आपके बिलिंग सिस्टम को Meta के component फ़ॉर्मैट के बारे में कुछ भी जानने की ज़रूरत नहीं पड़ती।
POST /api/v1/external/messages/template/send
{
"to": "+919876543210",
"template_name": "payment_failed_alert",
"language": "en",
"variables": {
"customer_name": "Priya Sharma",
"renewal_date": "12 Aug 2026",
"plan_name": "Wiz Pro"
},
"reference": "invoice-2026-0817"
}
नोट: वेरिएबल नाम मैपिंग से बिल्कुल मेल खाने चाहिए — अनजाना नाम नज़रअंदाज़ कर दिया जाता है, और कोई ज़रूरी नाम छूट जाए तो रिक्वेस्ट
400के साथ अस्वीकार हो जाती है।referenceआपका अपना है: यह वेबहुक पर वापस लौटाया जाता है ताकि आप किसी डिलीवरी रिपोर्ट को अपने सिस्टम के किसी रिकॉर्ड से जोड़ सकें।
रेट लिमिट
हर key की अपनी लिमिट होती है, जो Overview टैब पर दिखती है — डिफ़ॉल्ट रूप से 60 रिक्वेस्ट/मिनट और 1,000 मैसेज/दिन। जवाबों में बची हुई सीमा शामिल रहती है, इसलिए सीमा खत्म होने पर दीवार से टकराते हुए दोबारा कोशिश करने के बजाय रुक जाइए।
API से फ़ाइलें भेजना
खुली 24-घंटे की विंडो के भीतर आपका सॉफ़्टवेयर सीधे फ़ाइल भेज सकता है — न टेम्पलेट, न मंज़ूरी। एक ही एंडपॉइंट दस्तावेज़, इमेज, वीडियो और ऑडियो सबको कवर करता है।
आप क्या भेज सकते हैं
रिक्वेस्ट में दिया गया type ही सीमाएँ तय करता है। इससे बड़ी या सूची से बाहर की फ़ॉर्मैट वाली फ़ाइल WhatsApp तक पहुँचने से पहले ही अस्वीकार हो जाती है।
| प्रकार | फ़ॉर्मैट | अधिकतम आकार | कैप्शन | फ़ाइल नाम |
|---|---|---|---|---|
document | pdf, doc, docx, xls, xlsx, ppt, pptx, txt | 100 MB | ✓ | ✓ |
image | jpg, jpeg, png, webp | 5 MB | ✓ | — |
video | mp4, 3gp | 16 MB | ✓ | — |
audio | aac, amr, mp3, ogg, m4a | 16 MB | — | — |
POST /api/v1/external/messages/media
{
"to": "+919876543210",
"type": "document",
"link": "https://example.com/invoice-2026-0817.pdf",
"filename": "Invoice 2026-0817.pdf",
"caption": "Your invoice for August",
"reference": "invoice-2026-0817"
}
एक बार अपलोड, बार-बार भेजें
अगर आप एक ही फ़ाइल बार-बार भेजते हैं — मूल्य सूची, कैटलॉग, शर्तों का PDF — तो उसे एक बार अपलोड करके id रख लें। यह 30 दिन मान्य रहती है और WhatsApp को हर संदेश पर आपका URL दोबारा लाने से बचाती है।
POST /api/v1/external/messages/media
{
"to": "+919876543210",
"type": "image",
"media_id": "1234567890",
"caption": "This month’s catalogue"
}
भेजना कब अस्वीकार होता है
- 24-घंटे की विंडो के बाहर। फ़्रीफ़ॉर्म मीडिया के लिए खुली बातचीत चाहिए। इसके बजाय मंज़ूर टेम्पलेट भेजें — देखें साझा इनबॉक्स गाइड।
- key के पास
send_mediaनहीं है। key के Overview टैब में अनुमतियाँ देखें। - ऑडियो पर कैप्शन। WhatsApp उसे दिखाता ही नहीं, इसलिए चुपचाप हटाने के बजाय अस्वीकार किया जाता है।
- दस्तावेज़ के अलावा किसी पर फ़ाइल नाम। नाम सिर्फ़ दस्तावेज़ ही दिखाते हैं।
media_idऔरlinkदोनों नहीं। ठीक एक ज़रूरी है।
ध्यान दें: यह सब बिना कोड लिखे आज़माया जा सकता है। key खोलें, Test API दबाएँ, और एंडपॉइंट सूची से
POST /messages/mediaचुनें — बॉडी पहले से भरी होती है, और "Get code" वही रिक्वेस्ट आठ भाषाओं में लिख देता है।
रिएक्शन
रिएक्शन वह इमोजी है जिसे कोई किसी एक मैसेज पर लगाता है — ऑर्डर कन्फ़र्मेशन पर 👍, किसी फ़ोटो पर ❤️। यह अपने आप में मैसेज नहीं है: यह किसी मैसेज की ओर इशारा करता है। आपका सॉफ़्टवेयर रिएक्शन को होते ही पढ़ सकता है, और खुद भी भेज सकता है।
एक इवेंट, तीन स्रोत
रिएक्शन आपके ग्राहक से आ सकता है, Business ऐप वाले फ़ोन पर मालिक के टैप करने से आ सकता है, या API कॉल करते आपके अपने सॉफ़्टवेयर से। तीनों एक ही message.reaction इवेंट पर आते हैं, इसलिए एक ही हैंडलर हर स्थिति संभाल लेता है — direction और source बताते हैं कि आपके सामने कौन-सा है।
रिएक्शन वेबहुक कैसा दिखता है
यहाँ एक ग्राहक आपके भेजे मैसेज पर 👍 जोड़ रहा है।
{
"version": 1,
"event": "message.reaction",
"timestamp": "2026-08-01T09:14:22.031Z",
"data": {
"message_id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQjkz…",
"direction": "inbound",
"from": "+919876543210",
"to": "+911122334455",
"reaction": {
"message_id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgUQ0Uz…",
"emoji": "👍",
"action": "added"
},
"contact": {
"name": "Priya Sharma",
"wa_id": "919876543210"
}
}
}
इस पेलोड में दो message_id हैं और दोनों का मतलब एक नहीं है। यही वह फ़ील्ड है जिसे दो बार पढ़ना सार्थक है।
| फ़ील्ड | यह क्या है |
|---|---|
data.message_id | रिएक्शन का अपना id — उस मैसेज का नहीं जिस पर रिएक्ट किया गया। |
data.reaction.message_id | उस मैसेज का wamid जिस पर रिएक्ट किया गया। अपने रिकॉर्ड से यही मिलाइए। |
data.reaction.emoji | इमोजी। रिएक्शन हटाए जाने पर खाली स्ट्रिंग। |
data.reaction.action | added या removed। इमोजी से ही निकाला जाता है, इसलिए सीधे इसी पर शाखा बना सकते हैं। |
data.direction | inbound — ग्राहक ने रिएक्ट किया। outbound — व्यवसाय ने। |
data.source | सिर्फ़ आउटबाउंड में: mobile (Business ऐप वाला फ़ोन) या api (आपका सॉफ़्टवेयर)। इनबाउंड में नहीं होता। |
data.from / data.to | दिशा के हिसाब से, message.sent की तरह: इनबाउंड यानी ग्राहक → व्यवसाय, आउटबाउंड यानी व्यवसाय → ग्राहक। |
data.reference | सिर्फ़ उन रिएक्शन पर जो आपके अपने सॉफ़्टवेयर ने भेजे, और तभी जब आपने दिया हो। |
data.contact, data.user_id, data.username | सिर्फ़ इनबाउंड — किसने रिएक्ट किया। हर आउटबाउंड रिएक्शन में अनुपस्थित। |
ध्यान दें:
data.fromसामान्यतः ग्राहक का फ़ोन नंबर होता है, लेकिन WhatsApp हमेशा नंबर नहीं भेजता। जब नहीं भेजता, तो आपको उनकी WhatsApp यूज़र id मिलती है — इसलिएfromको पहचान मानिए, ऐसा कुछ नहीं जिस पर आप हमेशा कॉल कर सकें।
रिएक्शन जोड़ना और हटाना
रिएक्शन हटाना अपने आप में एक अलग इवेंट है, खाली emoji और action: "removed" के साथ।
{
"event": "message.reaction",
"data": {
"message_id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSN0U3…",
"direction": "inbound",
"reaction": {
"message_id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgUQ0Uz…",
"emoji": "",
"action": "removed"
}
}
}
हर टैप अपने id वाला अलग WhatsApp मैसेज है। 👍 से रिएक्ट करना, फिर उसे ❤️ में बदलना, फिर पूरी तरह हटा देना — इससे तीन इवेंट बनते हैं, और आपके स्टोर में कोई भी दूसरे की जगह नहीं लेता। data.reaction.message_id को कुंजी बनाइए और सबसे नया रखिए — वही उस मैसेज का मौजूदा रिएक्शन है।
अपने सॉफ़्टवेयर से रिएक्शन भेजना
वही एंडपॉइंट जोड़ता भी है और हटाता भी। इनमें से क्या होगा, यह पूरी तरह इस पर निर्भर है कि आप इमोजी भेजते हैं या नहीं।
POST /api/v1/external/messages/reaction
{
"to": "+919876543210",
"message_id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgUQ0Uz…",
"emoji": "👍",
"reference": "invoice-2026-0817"
}
यहाँ message_id WhatsApp की id है — किसी send रिस्पॉन्स का whatsapp_message_id, या किसी वेबहुक का data.reaction.message_id। यह कभी हमारा uuid नहीं होता। रिएक्शन send_text अनुमति का उपयोग करते हैं, इसलिए जो भी key ग्राहक को मैसेज कर सकती है, वह रिएक्ट भी कर सकती है।
ध्यान दें: रिएक्शन कभी
message.deliveredयाmessage.readनहीं बनाता। WhatsApp रिएक्शन के लिए ये भेजता ही नहीं — आगे सिर्फ़message.failedमिल सकता है, जब रिएक्शन अस्वीकार हो जाए।GET /messages/:uuidसे देखना किसी भी अन्य भेजे गए मैसेज की तरह ही काम करता है।
रिएक्शन कब अस्वीकार होता है
कुछ अस्वीकृतियाँ यहीं हो जाती हैं, WhatsApp तक कुछ पहुँचने से पहले। ये आपके API कॉल को एरर लौटाती हैं और कोई वेबहुक नहीं बनातीं — बताने को कुछ है ही नहीं, क्योंकि कुछ भेजा ही नहीं गया।
- key के पास
send_textनहीं है।403। रिएक्शन उसी अनुमति का पुनः उपयोग करते हैं; अलग से देने को कुछ नहीं है। toE.164 में नहीं है।422। हर दूसरे एंडपॉइंट जैसा ही+…फ़ॉर्मैट।message_idगायब या खाली है।422। अधिकतम 255 अक्षर।emojiगायब है।422। रिएक्शन हटाने के लिए"emoji": ""भेजें — फ़ील्ड खाली भेजें, छोड़िए मत। अधिकतम 16 अक्षर।
बाकी WhatsApp पर होती हैं, हमारे कॉल स्वीकार कर लेने के बाद। पहले 200 और message.reaction वेबहुक मिलता है, फिर WhatsApp के अस्वीकार करते ही 131009 एरर वाला message.failed।
- मैसेज 30 दिन से पुराना है। रिएक्ट करने की यह WhatsApp की सीमा है, हमारी नहीं — हम उम्र जाँचते ही नहीं।
- मैसेज इस बातचीत का नहीं है। किसी दूसरी चैट का
wamid, या ग़लती से भेजा गया हमारा कोई uuid। - मैसेज हटा दिया गया, या वह ख़ुद एक रिएक्शन है। रिएक्शन पर रिएक्ट नहीं किया जा सकता।
ध्यान दें: अगर भेजना बाद में अस्वीकार होने के बजाय शुरू में ही विफल हो जाए, तो आपको
500और ऐसाmessage.failedमिलता है जिसकाdata.message_idहमारा uuid होता है,wamidनहीं — बताने को कोई WhatsApp id है ही नहीं, क्योंकि WhatsApp ने उसे कभी स्वीकार ही नहीं किया।
ध्यान दें: हर दूसरे एंडपॉइंट की तरह, इसे भी बिना कोड लिखे आज़माया जा सकता है। key खोलें, Test API दबाएँ, और
POST /messages/reactionचुनें — अपने ही फ़ोन पर किसी मैसेज पर रिएक्ट कीजिए और वेबहुक आते हुए देखिए।