WhatsApp-viestien lähetys ja vastaanotto PHP:llä ja Laravelilla
Vastaanotto on Laravel-reitti, joka vastaa Metan vahvistus-GETiin ja ottaa vastaan POST-pyynnöt. Parametrit luetaan nimillä hub_mode, hub_verify_token ja hub_challenge, koska PHP muuttaa pisteet alaviivoiksi. Lähetys on yksi Http::withToken()-POST Cloud API -rajapinnan messages-päätepisteeseen numeron phone number id:llä ja tokenilla. SDK:ta ei tarvita.
PHP muuttaa saapuvien muuttujien nimissä pisteet alaviivoiksi, joten hub.challenge luetaan nimellä hub_challenge.
Laravelin tilattomat API-reitit, jotka install:api luo, tarjoillaan polun /api alla ja web-ryhmän CSRF-suojauksen ulkopuolella.
Graph API -versio, jota Metan nykyiset viestin lähetyksen esimerkit käyttävät, osoitteessa POST /{phone-number-id}/messages.
Miten WhatsApp-viestit vastaanotetaan Laravelissa?
GET- ja POST-reitillä samalla polulla tiedostossa routes/api.php. Aja ensin php artisan install:api, jos tiedostoa ei ole. API-reitit ovat tilattomia ja web-ryhmän ulkopuolella, joten Metan POST-pyyntöä ei hylätä puuttuvan CSRF-tokenin vuoksi, kuten käy reitillä routes/web.php.
GET vastaa Metan vahvistukseen. Meta lähettää arvot hub.mode, hub.verify_token ja hub.challenge, mutta PHP muuttaa saapuvien muuttujien nimissä pisteet alaviivoiksi, joten Laravel näkee nimet hub_mode, hub_verify_token ja hub_challenge. Koodi, joka lukee pisteelliset nimet, saa arvon null eikä vahvistu koskaan. Palauta challenge tavallisena tekstinä, älä response()->json()-kutsulla.
POST antaa payloadin jonotettavalle työlle ja palauttaa heti 200. Laita polkuun pitkä satunnainen avain ja tarkista se molemmilla reiteillä: Meta allekirjoittaa lähetykset Tech Providerin sovelluksen salaisella avaimella, joten allekirjoitusotsikkoa ei voi vahvistaa sinun päässäsi.
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);
});Miten WhatsApp-viesti lähetetään Laravelista?
Laravelin HTTP-asiakkaalla: yksi POST numeron phone number id:n messages-päätepisteeseen, access token Bearer-tokenina. Molemmat arvot tulevat yhteydestä, näkyvät hallintapaneelissa ja palautuvat get_api_credentials-kutsulla. Ne kuuluvat tiedostoon config/services.php ympäristömuuttujien taakse, ei koodiin.
Pyynnön rungon muoto riippuu ajoituksesta. Asiakkaan viimeisestä viestistä 24 tunnin sisällä käy `text`-objekti, kuten alla. Ikkunan jälkeen Meta hyväksyy vain viestipohjaobjektin, jossa on hyväksytyn viestipohjan nimi ja kieli, ja vapaa teksti epäonnistuu virheeseen 131047. Vastauksesta asian näkee: epäonnistunut kutsu palauttaa error-objektin, jonka code kertoo, mikä meni vikaan, joten kirjaa se lokiin äläkä heitä pois.
Mikään pyynnössä ei ole EasyCoexistencelle ominaista. Se on Metan oman dokumentaation kutsu, joten mikä tahansa PHP:n HTTP-asiakas, Guzzle tai pelkkä cURL, toimii samalla tavalla.
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', []));
}Mitä tuotantokäyttöinen Laravel-käsittelijä tarvitsee lisäksi?
Oikean jonon, kaksoiskäsittelyn eston ja ikkunatarkistuksen.
Jono on tärkeä, koska Meta yrittää hidasta vastausta uudelleen. HandleWhatsAppEvent::dispatch() palaa nopeasti vain, kun jonoyhteys on oikea ja worker on käynnissä. Sync-ajurilla työ suoritetaan pyynnön sisällä, ja hidas mallikutsu tai tietokantakirjoitus muuttuu kaksoistoimitukseksi.
Estä kaksoiskäsittely viestin tunnisteen, kunkin viestin wamidin, perusteella, koska uudelleenyritykset ovat normaaleja eivätkä poikkeuksia. Riittää uniikki indeksi tälle sarakkeelle tai sen mukaan avainnettu välimuistilukko.
Tallenna myös, milloin kukin yhteystieto kirjoitti viimeksi. Tämän aikaleiman avulla lähetyspolku valitsee tekstin tai viestipohjan itse, eikä asia selviä vasta virheestä 131047, kun asiakas on jo odottanut. WhatsApp Business -sovelluksessa puhelimella kirjoitetut vastaukset saapuvat echo-tapahtumina samalle reitille, joten käsittelijä näkee myös, milloin ihminen on ottanut keskustelun hoitaakseen.
Yleiset virheet
- hub.challenge luetaan pisteellä. PHP nimesi sen uudelleen hub_challengeksi, joten käsittelijä palauttaa tyhjän rungon eikä Meta vahvista koskaan.
- Webhook on laitettu tiedostoon routes/web.php. Metan POSTissa ei ole CSRF-tokenia, ja se hylätään virheellä 419.
- Työ lähetetään sync-jonoon. Työ ajetaan ennen 200-vastausta, hidas käsittely yritetään uudelleen ja viestit käsitellään kahdesti.
- Challenge palautetaan response()->json()-kutsulla. Arvon ympärillä olevat lainausmerkit rikkovat Metan tarkistuksen.
Yhdistä numero osoitteessa easycoexistence.com, aseta webhookin kohteeksi Laravel-reittisi avaimineen polussa ja lue phone number id ja token hallintapaneelista. Alkaen US$ 9 numerolta kuukaudessa, laskien US$ 1:een numeroita lisätessä, ja ensimmäiset 3 päivää ovat ilmaisia.
Usein kysytyt kysymykset
Onko PHP-SDK:ta olemassa?
Meiltä ei ole, eikä sitä tarvita. API on Metan ja Metan dokumentoima, ja Laravelin HTTP-asiakas tai Guzzle tavoittaa sen suoraan.
Toimiiko tämä ilman Laravelia?
Kyllä. Pelkässä PHP:ssä lue $_GET['hub_challenge'], tulosta se muodossa text/plain ja lähetä viestit cURLilla. Alaviivasääntö koskee jokaista PHP-kehystä.
Miksi URL-osoitteen polussa tarvitaan avain?
Koska se on todennus, joka toimii. Metan allekirjoitus käyttää Tech Providerin sovelluksen salaista avainta, jota ei koskaan jaeta, joten URL-osoitteen salaisuus estää ulkopuolisia lähettämästä vääriä tapahtumia.
Voiko tiimi yhä käyttää puhelinta?
Kyllä. Coexistence pitää WhatsApp Business -sovelluksen toiminnassa numerolla, ja puhelimesta lähetetyt viestit saapuvat reitillesi echo-tapahtumina.
Lue lisää
Valmis aloittamaan?
Ota WhatsApp Coexistence käyttöön minuuteissa, ei kuukausissa. Sovellus toimii edelleen puhelimessa.
Aloita ilmainen kokeiluVahvistettu