Laravel WhatsApp: Send Messages via Meta Cloud API and whatsapp-web.js Behind One Facade
Laravel Composer Pacakge #Laravel #WhatsApp #Composer Package #Meta Cloud API #whatsapp-web.js

Laravel WhatsApp: Send Messages via Meta Cloud API and whatsapp-web.js Behind One Facade

4 min read Mohamed Said Mohamed Said

Overview

Laravel WhatsApp is a package by Md Mostafijur Rahman that integrates WhatsApp messaging into Laravel applications. Its defining feature is a dual-backend architecture: Meta's official Cloud API for business messaging, and an unofficial Node-based whatsapp-web.js sidecar that drives a headless Chromium instance to communicate via the WhatsApp Web protocol. Both backends sit behind the same WhatsApp:: facade, so your application code stays consistent regardless of which transport is in use. The package supports Laravel 11, 12, and 13 on PHP 8.2 or higher.

Two Backends, One Facade

The Cloud API and the web sidecar serve different use cases, and the package is transparent about the trade-offs:

| Capability | Cloud API | Web Sidecar | |---|---|---| | QR pairing | No | Yes | | Groups | No | Yes | | Free-form messaging | 24h template window | Yes | | Business templates | Yes | No | | Official support | Yes | Unofficial |

The Cloud API is the right choice for templated business messages with official backing. The web sidecar removes the 24-hour reply window restriction and adds group management and status updates, but it operates against a personal account without Meta's official support.

Sending Messages

Routing is determined by the recipient format. An E.164 phone number targets the Cloud API; a @c.us identifier targets the web sidecar:

WhatsApp::send('+14155550123', 'Your order has shipped.');
WhatsApp::send('14155550123@c.us', 'Thanks for your message!');

For business templates, use the Cloud API's sendTemplate method directly:

WhatsApp::messages()->sendTemplate('+14155550123', 'order_update', 'en_US', [
    ['type' => 'body', 'parameters' => [['type' => 'text', 'text' => 'Order #1042']]],
]);

The web sidecar supports named sessions, so you can run multiple personal accounts simultaneously:

WhatsApp::web('main')->groups()->create('Team Leads', ['14155550123@c.us']);
WhatsApp::web('main')->messages()->sendImage('14155550123@c.us', [
    'url' => 'https://example.com/report.png',
    'caption' => 'Q2 summary'
]);

Queued Sends and Inbound Events

Outbound messages can be dispatched as queued jobs to keep sending off the request cycle:

SendMessage::dispatch('+14155550123', 'Your invoice is ready.');

Inbound messages from the sidecar are bridged into Laravel's event system via a long-running listener process. You subscribe to typed events like any other Laravel event:

use \Kstmostofa\LaravelWhatsApp\Events\Web\MessageReceived;

Event::listen(MessageReceived::class, function ($event) {
    Log::info('Message received', ['from' => $event->from(), 'body' => $event->body()]);
});

Cloud API inbound traffic is handled through webhooks with HMAC signature verification using your Meta app secret.

Optional Admin UI and Persistence

Installing the optional Livewire and Flux dependencies mounts an admin interface at /whatsapp with a dashboard, messaging screen, conversation views, and pages for groups, contacts, and webhook logs. Adding Laravel Reverb enables real-time conversation updates.

Persistence is opt-in via three Eloquent models — WaSession, WaMessage, and WaContact — which can be placed on a separate database connection to keep WhatsApp data isolated from your primary schema.

Getting Started

composer require kstmostofa/laravel-whatsapp
php artisan vendor:publish --tag=laravel-whatsapp-config
php artisan vendor:publish --tag=laravel-whatsapp-migrations
php artisan migrate

Add your Meta credentials to .env for the Cloud API path, then install and start the sidecar for the web backend:

php artisan whatsapp:sidecar:install
php artisan whatsapp:sidecar:start
php artisan whatsapp:web:listen main &

Key Takeaways

  • A single WhatsApp:: facade abstracts both the Meta Cloud API and the whatsapp-web.js sidecar.
  • Recipient format (E.164 vs @c.us) determines which backend handles each message.
  • The web sidecar supports groups, QR pairing, and free-form messaging; the Cloud API provides official business template support.
  • Outbound messages can be queued; inbound sidecar messages fire typed Laravel events.
  • An optional Livewire-based admin UI and opt-in Eloquent persistence layer are available.
  • Requires Laravel 11–13 and PHP 8.2+.

Source: Laravel WhatsApp: Two Backends Behind One Facade — Laravel News

Found this useful?

Frequently Asked Questions

3 questions
Q01 What is the difference between the Cloud API and the web sidecar in laravel-whatsapp?
The Cloud API is Meta's official channel for business messaging. It supports templated messages but restricts free-form replies to a 24-hour window and does not support groups. The web sidecar uses whatsapp-web.js with headless Chromium to connect via the WhatsApp Web protocol, enabling free-form messaging, group creation, and QR pairing, but it operates against a personal account without official Meta support.
Q02 How does laravel-whatsapp decide which backend to use when sending a message?
The recipient format determines the backend. Passing an E.164 phone number (e.g., '+14155550123') routes the message through the Cloud API. Passing a '@c.us' identifier (e.g., '14155550123@c.us') routes it through the web sidecar session.
Q03 Does laravel-whatsapp support receiving inbound WhatsApp messages?
Yes. Inbound messages from the web sidecar are bridged into Laravel's event system via a long-running 'whatsapp:web:listen' artisan process, firing typed events such as MessageReceived. Inbound Cloud API traffic is handled through webhooks with HMAC signature verification.

Continue reading

More Articles

View all