लॉग इनमुफ़्त ट्रायल शुरू करें
Meta Tech Provider

PHP और Laravel से WhatsApp मैसेज भेजें और पाएँ

मैसेज पाना एक Laravel रूट से होता है, जो Meta के पुष्टि वाले GET का जवाब देता है और POST स्वीकार करता है। पैरामीटर hub_mode, hub_verify_token और hub_challenge नाम से पढ़े जाते हैं, क्योंकि PHP बिंदु को अंडरस्कोर में बदल देता है। भेजना एक Http::withToken() POST है, जो Cloud API के messages एंडपॉइंट पर उस नंबर की फ़ोन नंबर आईडी और टोकन के साथ जाता है। किसी एसडीके की ज़रूरत नहीं।

hub_challenge

PHP आने वाले वेरिएबल नामों के बिंदु को अंडरस्कोर में बदल देता है, इसलिए hub.challenge को hub_challenge के रूप में पढ़ा जाता है।

routes/api.php

Laravel के स्टेटलेस एपीआई रूट, जो install:api से बनते हैं, /api के तहत चलते हैं और web ग्रुप की CSRF सुरक्षा के बाहर रहते हैं।

v25.0

Meta के मौजूदा send message उदाहरणों में दिया Graph API वर्शन, POST /{phone-number-id}/messages पर।

Laravel में WhatsApp मैसेज कैसे पाएँ?

routes/api.php में एक ही पाथ पर GET और POST रखें। फ़ाइल न हो तो पहले php artisan install:api चलाएँ। एपीआई रूट स्टेटलेस होते हैं और web ग्रुप के बाहर रहते हैं, इसलिए CSRF टोकन न होने पर Meta का POST ख़ारिज नहीं होता, जबकि routes/web.php के रूट पर ऐसा होता है।

GET Meta की पुष्टि का जवाब देता है। Meta hub.mode, hub.verify_token और hub.challenge भेजता है, पर PHP आने वाले वेरिएबल नामों के बिंदु को अंडरस्कोर में बदल देता है, इसलिए Laravel को hub_mode, hub_verify_token और hub_challenge दिखते हैं। बिंदु वाले नाम पढ़ने वाला कोड null पाता है और पुष्टि कभी पूरी नहीं होती। challenge को प्लेन टेक्स्ट में लौटाएँ, response()->json() से नहीं।

POST पेलोड को क्यू वाले जॉब को सौंपकर तुरंत 200 लौटा देता है। पाथ में एक लंबी रैंडम कुंजी रखें और दोनों रूट पर उसे जाँचें: Meta अपनी डिलीवरी पर Tech Provider के ऐप सीक्रेट से सिग्नेचर करता है, इसलिए सिग्नेचर हेडर को आपकी ओर से मान्य नहीं किया जा सकता।

routes/api.php: verification and event intake
use App\Jobs\HandleWhatsAppEvent;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::get('/whatsapp/{key}', function (Request $request, string $key) {
    abort_unless(hash_equals(config('services.whatsapp.url_key'), $key), 404);

    // PHP turns hub.mode into hub_mode: read the underscored names
    if ($request->query('hub_mode') === 'subscribe'
        && hash_equals(config('services.whatsapp.verify_token'),
                       (string) $request->query('hub_verify_token'))) {
        return response((string) $request->query('hub_challenge'), 200)
            ->header('Content-Type', 'text/plain');
    }

    abort(403);
});

Route::post('/whatsapp/{key}', function (Request $request, string $key) {
    abort_unless(hash_equals(config('services.whatsapp.url_key'), $key), 404);

    HandleWhatsAppEvent::dispatch($request->json()->all());

    return response('', 200);
});

Laravel से WhatsApp मैसेज कैसे भेजें?

Laravel के एचटीटीपी क्लाइंट से: फ़ोन नंबर आईडी वाले messages एंडपॉइंट पर एक POST, जिसमें एक्सेस टोकन बियरर टोकन के रूप में जाए। दोनों मान कनेक्शन से मिलते हैं, डैशबोर्ड में दिखते हैं और get_api_credentials से लौटते हैं। इन्हें कोड में न रखकर एनवायरनमेंट वेरिएबल पर आधारित config/services.php में रखें।

बॉडी का रूप समय पर निर्भर है। ग्राहक के आख़िरी मैसेज के 24 घंटे के भीतर text ऑब्जेक्ट चलता है, जैसा नीचे है। उस विंडो के बाहर Meta सिर्फ़ template ऑब्जेक्ट लेता है, जिसमें मंज़ूर टेम्पलेट और उसकी भाषा हो, और फ़्री टेक्स्ट गड़बड़ी 131047 के साथ विफल होता है। इसे जवाब में देखा जा सकता है: विफल कॉल एक error ऑब्जेक्ट लौटाती है, जिसका code बताता है कि क्या गड़बड़ हुई, इसलिए उसे फेंकें नहीं, लॉग करें।

अनुरोध में कुछ भी EasyCoexistence के लिए ख़ास नहीं है। यह वही कॉल है जो Meta के अपने दस्तावेज़ में है, इसलिए कोई भी PHP एचटीटीपी क्लाइंट, Guzzle या सीधा cURL, उसी तरह काम करता है.

Send a text reply inside the 24 hour window
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.whatsapp.token'))
    ->post('https://graph.facebook.com/v25.0/'
        . config('services.whatsapp.phone_number_id') . '/messages', [
        'messaging_product' => 'whatsapp',
        'to' => '14155550188', // digits only, with country code
        'type' => 'text',
        'text' => ['body' => 'Thanks, we are on it.'],
    ]);

if ($response->failed()) {
    // error.code 131047: outside the window, send a template instead
    logger()->warning('WhatsApp send failed', $response->json('error', []));
}

प्रोडक्शन Laravel हैंडलर को इसके अलावा क्या चाहिए?

असली क्यू, डुप्लिकेट से बचाव और विंडो की जाँच।

क्यू इसलिए ज़रूरी है कि धीमा जवाब मिलने पर Meta दोबारा भेजता है। HandleWhatsAppEvent::dispatch() तभी जल्दी लौटता है जब क्यू कनेक्शन असली हो और वर्कर चल रहा हो। sync ड्राइवर पर जॉब अनुरोध के भीतर ही चलता है, और धीमा मॉडल कॉल या डेटाबेस राइट एक डुप्लिकेट डिलीवरी बन जाता है।

डुप्लिकेट की पहचान मैसेज आईडी पर करें, यानी हर मैसेज के wamid पर, क्योंकि दोबारा भेजना अपवाद नहीं, आम बात है। उस कॉलम पर यूनीक इंडेक्स या उसी पर बना कैश लॉक काफ़ी है।

और हर संपर्क ने आख़िरी बार कब लिखा, यह सहेजें। उस टाइमस्टैंप से भेजने वाला हिस्सा खुद तय कर लेता है कि text भेजना है या टेम्पलेट, बजाय इसके कि ग्राहक के इंतज़ार के बाद गड़बड़ी 131047 से पता चले। WhatsApp Business ऐप में फ़ोन से टाइप किए गए जवाब उसी रूट पर echo इवेंट बनकर आते हैं, इसलिए हैंडलर यह भी देख सकता है कि कब किसी व्यक्ति ने बातचीत संभाल ली।

आम गड़बड़ियाँ

  • hub.challenge को बिंदु के साथ पढ़ना। PHP ने उसका नाम hub_challenge कर दिया, इसलिए हैंडलर खाली बॉडी लौटाता है और Meta कभी पुष्टि नहीं करता।
  • वेबहुक को routes/web.php में रखना। Meta के POST में CSRF टोकन नहीं होता और उसे 419 के साथ ख़ारिज कर दिया जाता है।
  • sync क्यू पर डिस्पैच करना। जॉब 200 से पहले चल जाता है, धीमी प्रोसेसिंग पर Meta दोबारा भेजता है और मैसेज दो बार प्रोसेस होते हैं।
  • challenge को response()->json() से लौटाना। मान के चारों ओर के उद्धरण चिह्न Meta की जाँच को फ़ेल कर देते हैं।
EasyCoexistence के साथ ऐसा करना

easycoexistence.com पर नंबर कनेक्ट करें, वेबहुक डेस्टिनेशन को अपने Laravel रूट पर सेट करें जिसके पाथ में कुंजी हो, और डैशबोर्ड से फ़ोन नंबर आईडी और टोकन पढ़ें। US$ 9 प्रति नंबर प्रति माह से शुरू, नंबर बढ़ने के साथ घटकर US$ 1, और पहले 3 दिन मुफ़्त ट्रायल।

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

क्या कोई PHP एसडीके है?

हमारी ओर से नहीं, और ज़रूरत भी नहीं। एपीआई Meta की है और Meta ने ही उसके दस्तावेज़ बनाए हैं, और Laravel का एचटीटीपी क्लाइंट या Guzzle उस तक सीधे पहुँचता है।

क्या यह Laravel के बिना चलता है?

हाँ। सादे PHP में $_GET['hub_challenge'] पढ़ें, उसे text/plain के रूप में echo करें और cURL से भेजें। अंडरस्कोर का नियम हर PHP फ्रेमवर्क पर लागू होता है।

यूआरएल के पाथ में कुंजी क्यों चाहिए?

क्योंकि वही प्रमाणीकरण है जो काम करता है। Meta का सिग्नेचर Tech Provider के ऐप सीक्रेट से बनता है, जो कभी साझा नहीं होता, इसलिए यूआरएल की गोपनीय कुंजी ही अजनबियों को नकली इवेंट पोस्ट करने से रोकती है।

क्या टीम फ़ोन इस्तेमाल करना जारी रख सकती है?

हाँ। Coexistence नंबर पर WhatsApp Business ऐप को चालू रखता है, और फ़ोन से भेजे मैसेज echo इवेंट बनकर आपके रूट तक पहुँचते हैं।

पढ़ना जारी रखें

शुरू करने के लिए तैयार हैं?

WhatsApp Coexistence को महीनों में नहीं, मिनटों में कॉन्फ़िगर करें। ऐप्लिकेशन मोबाइल पर काम करता रहता है।

मुफ़्त ट्रायल शुरू करें

इस तारीख को सत्यापित

PHP और Laravel से WhatsApp मैसेज भेजें