crenspire / laravel-whatsapp
Laravel WhatsApp Business API package
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.0
- illuminate/contracts: ^10.0|^11.0|^12.0
- nesbot/carbon: ^2.0|^3.0
- spatie/laravel-package-tools: ^1.14
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0
- pestphp/pest: ^2.0
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2025-09-08 17:45:30 UTC
README
A comprehensive Laravel package for integrating with the WhatsApp Business Cloud API. This package provides a clean, easy-to-use interface for sending messages, handling webhooks, managing media, and supporting multi-tenant applications.
Features
- ✅ Complete Message Types: Text, media, templates, interactive messages (buttons, lists), contacts, location, stickers, reactions, flows, and product messages
- ✅ Fluent API: Builder patterns for easy message construction with
MessageBuilder
andTemplateBuilder
- ✅ Webhook Support: Secure webhook handling with signature verification and comprehensive message type processing
- ✅ Media Management: Upload, download, info retrieval, and deletion with automatic type detection via
MediaManager
- ✅ Business Profile Management: Get and update business profile information via
BusinessProfileManager
- ✅ Multi-tenant Support: Per-tenant configuration for phone numbers and access tokens
- ✅ Rate Limiting: Built-in rate limiting to respect WhatsApp API limits
- ✅ Event System: Laravel events for message status updates and incoming messages
- ✅ Comprehensive Testing: Full test coverage with realistic scenarios
- ✅ Security: Webhook verification and signature validation
- ✅ Logging: Detailed logging for debugging and monitoring
- ✅ Clean Architecture: Separated concerns with dedicated managers and builders
Installation
1. Install the Package
composer require crenspire/laravel-whatsapp
2. Publish Configuration
php artisan vendor:publish --tag=config --provider="Crenspire\\Whatsapp\\WhatsappServiceProvider"
3. Configure Environment Variables
Add these variables to your .env
file:
# WhatsApp Business API Configuration WHATSAPP_BASE_URI=https://graph.facebook.com/v20.0 WHATSAPP_PHONE_NUMBER_ID=your_phone_number_id WHATSAPP_ACCESS_TOKEN=your_access_token # Webhook Configuration WHATSAPP_WEBHOOK_VERIFY_TOKEN=your_webhook_verify_token WHATSAPP_WEBHOOK_SECRET=your_webhook_secret # Optional Configuration WHATSAPP_RATE_LIMIT=30 WHATSAPP_DEBUG=false
4. Set Up Webhook Routes
The package automatically registers webhook routes. Make sure your webhook URL is configured in your WhatsApp Business API settings:
- Verification URL:
https://yourdomain.com/whatsapp/webhook
- Webhook URL:
https://yourdomain.com/whatsapp/webhook
Quick Start
Basic Usage
use Crenspire\Whatsapp\Facades\Whatsapp; // Send a text message $response = Whatsapp::sendTextMessage('1234567890', 'Hello from Laravel!'); // Send a media message $response = Whatsapp::sendMediaMessage('1234567890', 'media_id_123', 'image', 'Check this out!'); // Send a template message $response = Whatsapp::sendTemplateMessage('1234567890', 'hello_world', ['John', 'Doe']);
Using the Service Directly
use Crenspire\Whatsapp\WhatsappService; $whatsapp = app(WhatsappService::class); $response = $whatsapp->sendTextMessage('1234567890', 'Hello World!');
Message Types
Text Messages
Whatsapp::sendTextMessage('1234567890', 'Hello World!');
Media Messages
// Send image with caption Whatsapp::sendMediaMessage('1234567890', 'media_id_123', 'image', 'Check this out!'); // Send video Whatsapp::sendMediaMessage('1234567890', 'media_id_456', 'video', 'Watch this video'); // Send document Whatsapp::sendMediaMessage('1234567890', 'media_id_789', 'document', 'Important document');
Template Messages
// Send template with parameters Whatsapp::sendTemplateMessage( '1234567890', 'hello_world', ['John', 'Doe'], 'en_US' );
Interactive Messages
Button Messages
$buttons = [ ['id' => 'btn1', 'title' => 'Option 1'], ['id' => 'btn2', 'title' => 'Option 2'], ['id' => 'btn3', 'title' => 'Option 3'] ]; Whatsapp::sendButtonMessage( '1234567890', 'Choose an option:', $buttons, 'Header Text', 'Footer Text' );
List Messages
$sections = [ [ 'title' => 'Category 1', 'rows' => [ [ 'id' => 'row1', 'title' => 'Option 1', 'description' => 'Description for option 1' ], [ 'id' => 'row2', 'title' => 'Option 2', 'description' => 'Description for option 2' ] ] ] ]; Whatsapp::sendListMessage( '1234567890', 'Choose from the list:', 'View Options', $sections, 'Header Text', 'Footer Text' );
Media Management
Upload Media
$response = Whatsapp::uploadMedia('/path/to/image.jpg', 'image'); $mediaId = $response['id']; // Use the media ID to send the image Whatsapp::sendMediaMessage('1234567890', $mediaId, 'image', 'Uploaded image');
Download Media
$filePath = Whatsapp::downloadMedia('media_id_123'); // File is saved to storage/app/whatsapp-media/media_id_123.jpg
Multi-tenant Support
Configure multiple WhatsApp Business accounts:
// In config/whatsapp.php 'tenants' => [ 'company1' => [ 'phone_number_id' => 'phone_number_1', 'access_token' => 'access_token_1' ], 'company2' => [ 'phone_number_id' => 'phone_number_2', 'access_token' => 'access_token_2' ] ]
Use tenant-specific configuration:
// Send message using specific tenant Whatsapp::sendTextMessage('1234567890', 'Hello!', 'company1');
Webhook Handling
Event Listeners
The package dispatches several events that you can listen to:
// In your EventServiceProvider protected $listen = [ \Crenspire\Whatsapp\Events\MessageSent::class => [ // Your listener ], \Crenspire\Whatsapp\Events\MessageDelivered::class => [ // Your listener ], \Crenspire\Whatsapp\Events\MessageRead::class => [ // Your listener ], \Crenspire\Whatsapp\Events\MessageReceived::class => [ // Your listener ], \Crenspire\Whatsapp\Events\MessageFailed::class => [ // Your listener ], ];
Example Event Listener
<?php namespace App\Listeners; use Crenspire\Whatsapp\Events\MessageReceived; use Illuminate\Contracts\Queue\ShouldQueue; class HandleIncomingMessage implements ShouldQueue { public function handle(MessageReceived $event) { // Handle incoming message $messageId = $event->messageId; $from = $event->from; $message = $event->message; $timestamp = $event->timestamp; // Your logic here } }
Error Handling
The package throws WhatsappException
for various error conditions:
use Crenspire\Whatsapp\Exceptions\WhatsappException; try { Whatsapp::sendTextMessage('1234567890', 'Hello!'); } catch (WhatsappException $e) { // Handle WhatsApp API errors logger('WhatsApp error: ' . $e->getMessage()); }
Rate Limiting
The package includes built-in rate limiting to respect WhatsApp API limits:
// Configure rate limit in config/whatsapp.php 'rate_limit' => 30, // messages per minute
Logging
Enable debug logging:
// In config/whatsapp.php 'debug' => true,
Or set in your .env
:
WHATSAPP_DEBUG=true
Testing
Run the test suite:
composer test
The package includes comprehensive tests covering all functionality.
Security
Webhook Verification
The package automatically verifies webhook signatures when WHATSAPP_WEBHOOK_SECRET
is configured:
WHATSAPP_WEBHOOK_SECRET=your_webhook_secret
Phone Number Validation
All phone numbers are validated before sending messages to ensure they meet WhatsApp's requirements.
🔧 Custom Headers Support
The package now supports custom headers for all API requests, allowing you to add authentication, tracking, or other custom headers:
Basic Usage
// Using custom headers with individual requests $customHeaders = [ 'X-Request-ID' => 'req_12345', 'X-Client-Version' => '2.0.0', 'X-Custom-Auth' => 'custom_token' ]; Whatsapp::sendTextMessage('+1234567890', 'Hello!', null, $customHeaders); // Using custom headers with media upload Whatsapp::uploadMedia('/path/to/file.jpg', 'image', null, $customHeaders); // Using custom headers with media download $filePath = Whatsapp::downloadMedia('media_id_123', null, $customHeaders);
Multi-tenant Headers
Configure per-tenant headers in your configuration:
// config/whatsapp.php 'tenants' => [ 'tenant1' => [ 'phone_number_id' => '123456789', 'access_token' => 'token1', 'headers' => [ 'X-Tenant-ID' => 'tenant1', 'X-API-Version' => 'v2.0', 'X-Custom-Header' => 'tenant1-value' ] ], 'tenant2' => [ 'phone_number_id' => '987654321', 'access_token' => 'token2', 'headers' => [ 'X-Tenant-ID' => 'tenant2', 'X-API-Version' => 'v1.5' ] ] ]
Default Headers
Set default headers for all requests:
// config/whatsapp.php 'default_headers' => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'User-Agent' => 'Laravel-WhatsApp-Package/1.0.0', 'X-Client-Name' => 'MyApp', 'X-Client-Version' => '1.0.0' ],
Header Priority
Headers are merged in the following order (later overrides earlier):
- Default headers from configuration
- Tenant-specific headers
- Custom headers passed to individual methods
Configuration Reference
See Configuration for detailed configuration options.
API Reference
See API Reference for complete method documentation.
Enhanced Features
New Message Types
The package now supports all WhatsApp Cloud API message types:
- Contact Messages: Send contact cards
- Location Messages: Share location with optional name and address
- Sticker Messages: Send stickers
- Reaction Messages: React to existing messages
- Flow Messages: Send interactive flows
- Product Messages: Single and multi-product catalogs
Fluent API
Use the new builder patterns for cleaner code:
// Template builder $template = Whatsapp::template('welcome_template', 'en_US') ->header([['type' => 'text', 'text' => 'Welcome!']]) ->body([['type' => 'text', 'text' => 'Hello {{1}}!']]) ->footer([['type' => 'text', 'text' => 'Thank you']]) ->build(); // Message builder $message = Whatsapp::message()::text('Hello with preview!', true);
Business Profile Management
// Get business profile $profile = Whatsapp::getBusinessProfile(); // Update business profile Whatsapp::updateBusinessProfile([ 'messaging_product' => 'whatsapp', 'about' => 'Updated business description' ]);
Enhanced Media Management
// Get media information $info = Whatsapp::getMediaInfo('media_id_123'); // Delete media Whatsapp::deleteMedia('media_id_123');
Examples
See Examples for real-world usage examples.
Troubleshooting
See Troubleshooting for common issues and solutions.
Contributing
Contributions are welcome! Please see Contributing for guidelines.
License
This package is open-sourced software licensed under the MIT license.