Integrating WhatsApp Message Laravel 12 functionality into your web application opens up powerful communication possibilities with your users. This comprehensive guide walks you through the complete process of sending WhatsApp messages using Laravel 12, from basic setup to advanced features like scheduling and handling incoming messages.
Whether you’re building a customer support system, notification service, or marketing automation tool, learning to implement WhatsApp Message Laravel 12 integration will enhance your application’s communication capabilities. You’ll discover how to leverage Laravel 12’s robust features alongside WhatsApp’s Business API to create seamless messaging experiences.
Introduction to WhatsApp Messaging with Laravel
Understanding the fundamentals of WhatsApp integration with Laravel applications helps you make informed decisions about implementation strategies and architecture.
Why Use WhatsApp for Laravel Applications
WhatsApp has become an essential communication channel for businesses worldwide, making WhatsApp Message Laravel 12 integration crucial for modern web applications.
Key Benefits of WhatsApp Integration:
- Higher Engagement Rates: WhatsApp messages have 98% open rates compared to 20% for emails
- Real-time Communication: Instant message delivery and read receipts
- Global Reach: Over 2 billion users worldwide across all demographics
- Rich Media Support: Send images, videos, documents, and interactive content
- Cost-Effective: Lower costs compared to traditional SMS services
- Business Verification: Official business accounts build customer trust
Use Cases for WhatsApp Message Laravel 12:
- Order confirmations and shipping notifications
- Appointment reminders and scheduling
- Customer support and helpdesk automation
- Marketing campaigns and promotional messages
- Two-factor authentication and security alerts
- Event notifications and updates
WhatsApp Business API Overview
The WhatsApp Business API provides programmatic access to WhatsApp messaging capabilities, enabling developers to integrate WhatsApp Message Laravel 12 functionality seamlessly.
API Features:
- Message Templates: Pre-approved message formats for business communications
- Session Messaging: 24-hour window for free-form conversations
- Media Messages: Support for images, videos, audio, and documents
- Interactive Messages: Buttons, lists, and quick replies
- Webhook Support: Real-time message delivery and status updates
- Group Messaging: Broadcast messages to multiple recipients
API Providers for WhatsApp Message Laravel 12:
- Twilio WhatsApp API: Enterprise-grade solution with global coverage
- Meta WhatsApp Business API: Direct integration with Facebook’s platform
- 360Dialog: European WhatsApp Business Solution Provider
- Vonage (Nexmo): Comprehensive communication platform
- Chat API: Developer-friendly WhatsApp integration service
Setup and Configuration
Setting up WhatsApp Message Laravel 12 integration requires proper Laravel installation, API configuration, and webhook setup for optimal functionality.
Install Laravel 12
Before implementing WhatsApp messaging, ensure you have Laravel 12 properly installed and configured.
Create New Laravel 12 Project:
# Install Laravel 12 via Composer
composer create-project laravel/laravel whatsapp-messaging
# Navigate to project directory
cd whatsapp-messaging
# Install additional dependencies
composer require spatie/laravel-permission
# Generate application key
php artisan key:generate
# Set up database
php artisan migrate
# Start development server
php artisan serve
Configure Environment Variables:
# .env file configuration
APP_NAME="WhatsApp Laravel App"
APP_ENV=local
APP_KEY=base64:generated_key_here
APP_DEBUG=true
APP_URL=http://localhost:8000
# Database configuration
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=whatsapp_laravel
DB_USERNAME=root
DB_PASSWORD=
# WhatsApp API Configuration
WHATSAPP_API_URL=https://api.twilio.com/2010-04-01
WHATSAPP_ACCOUNT_SID=your_account_sid
WHATSAPP_AUTH_TOKEN=your_auth_token
WHATSAPP_FROM_NUMBER=whatsapp:+14155238886
WhatsApp API Configuration
Configure your chosen WhatsApp API provider to enable WhatsApp Message Laravel 12 functionality in your application.
Install Twilio SDK for Laravel:
# Install Twilio PHP SDK
composer require twilio/sdk
# Publish configuration
php artisan vendor:publish --provider="TwilioServiceProvider"
Create WhatsApp Service Class:
<?php
// app/Services/WhatsAppService.php
namespace App\Services;
use Twilio\Rest\Client;
use Illuminate\Support\Facades\Log;
class WhatsAppService
{
protected $client;
protected $from;
public function __construct()
{
$accountSid = config('services.twilio.account_sid');
$authToken = config('services.twilio.auth_token');
$this->from = config('services.twilio.whatsapp_from');
$this->client = new Client($accountSid, $authToken);
}
public function sendMessage($to, $message, $mediaUrl = null)
{
try {
$messageData = [
'from' => $this->from,
'body' => $message
];
if ($mediaUrl) {
$messageData['mediaUrl'] = [$mediaUrl];
}
$message = $this->client->messages->create(
"whatsapp:$to",
$messageData
);
Log::info('WhatsApp message sent successfully', [
'sid' => $message->sid,
'to' => $to,
'status' => $message->status
]);
return [
'success' => true,
'message_sid' => $message->sid,
'status' => $message->status
];
} catch (\Exception $e) {
Log::error('WhatsApp message failed', [
'error' => $e->getMessage(),
'to' => $to
]);
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
public function sendTemplate($to, $templateId, $parameters = [])
{
try {
$message = $this->client->messages->create(
"whatsapp:$to",
[
'from' => $this->from,
'contentSid' => $templateId,
'contentVariables' => json_encode($parameters)
]
);
return [
'success' => true,
'message_sid' => $message->sid,
'status' => $message->status
];
} catch (\Exception $e) {
Log::error('WhatsApp template message failed', [
'error' => $e->getMessage(),
'to' => $to,
'template' => $templateId
]);
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
}
Configure Services Configuration:
<?php
// config/services.php
return [
// Other services...
'twilio' => [
'account_sid' => env('TWILIO_ACCOUNT_SID'),
'auth_token' => env('TWILIO_AUTH_TOKEN'),
'whatsapp_from' => env('TWILIO_WHATSAPP_FROM', 'whatsapp:+14155238886'),
],
];
Environment & Webhook Setup
Webhooks enable real-time processing of message delivery status and incoming messages for WhatsApp Message Laravel 12 integration.
Create Webhook Controller:
<?php
// app/Http/Controllers/WhatsAppWebhookController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Models\WhatsAppMessage;
class WhatsAppWebhookController extends Controller
{
public function handleWebhook(Request $request)
{
$payload = $request->all();
Log::info('WhatsApp webhook received', $payload);
// Handle message status updates
if (isset($payload['MessageStatus'])) {
$this->handleMessageStatus($payload);
}
// Handle incoming messages
if (isset($payload['Body'])) {
$this->handleIncomingMessage($payload);
}
return response('OK', 200);
}
protected function handleMessageStatus($payload)
{
$messageSid = $payload['MessageSid'] ?? null;
$status = $payload['MessageStatus'] ?? null;
if ($messageSid && $status) {
WhatsAppMessage::where('message_sid', $messageSid)
->update(['status' => $status]);
}
}
protected function handleIncomingMessage($payload)
{
$from = str_replace('whatsapp:', '', $payload['From'] ?? '');
$body = $payload['Body'] ?? '';
$messageSid = $payload['MessageSid'] ?? '';
WhatsAppMessage::create([
'message_sid' => $messageSid,
'from_number' => $from,
'to_number' => str_replace('whatsapp:', '', $payload['To'] ?? ''),
'body' => $body,
'status' => 'received',
'direction' => 'inbound'
]);
// Process incoming message logic here
$this->processIncomingMessage($from, $body);
}
protected function processIncomingMessage($from, $body)
{
// Implement your incoming message processing logic
// For example: auto-replies, customer support routing, etc.
}
}
Create Database Migration for Messages:
<?php
// database/migrations/create_whatsapp_messages_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('whatsapp_messages', function (Blueprint $table) {
$table->id();
$table->string('message_sid')->unique();
$table->string('from_number');
$table->string('to_number');
$table->text('body');
$table->string('status')->default('sent');
$table->enum('direction', ['inbound', 'outbound'])->default('outbound');
$table->json('media_urls')->nullable();
$table->string('template_id')->nullable();
$table->json('template_variables')->nullable();
$table->timestamp('sent_at')->nullable();
$table->timestamp('delivered_at')->nullable();
$table->timestamp('read_at')->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('whatsapp_messages');
}
};
Configure Webhook Routes:
<?php
// routes/web.php
use App\Http\Controllers\WhatsAppWebhookController;
Route::post('/webhooks/whatsapp', [WhatsAppWebhookController::class, 'handleWebhook']);
Sending Messages
Implementing different types of message sending capabilities is central to WhatsApp Message Laravel 12 functionality.
Send Text Messages via WhatsApp in Laravel 12
Create a comprehensive system for sending text messages through your Laravel application.
Create WhatsApp Message Controller:
<?php
// app/Http/Controllers/WhatsAppController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Services\WhatsAppService;
use App\Models\WhatsAppMessage;
use Illuminate\Support\Facades\Validator;
class WhatsAppController extends Controller
{
protected $whatsAppService;
public function __construct(WhatsAppService $whatsAppService)
{
$this->whatsAppService = $whatsAppService;
}
public function sendMessage(Request $request)
{
$validator = Validator::make($request->all(), [
'phone_number' => 'required|string|min:10|max:15',
'message' => 'required|string|max:1600',
'schedule_at' => 'nullable|date|after:now'
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->errors()
], 422);
}
$phoneNumber = $this->formatPhoneNumber($request->phone_number);
$message = $request->message;
$scheduleAt = $request->schedule_at;
// Store message in database
$whatsappMessage = WhatsAppMessage::create([
'to_number' => $phoneNumber,
'body' => $message,
'status' => $scheduleAt ? 'scheduled' : 'pending',
'direction' => 'outbound',
'sent_at' => $scheduleAt
]);
if ($scheduleAt) {
// Schedule message for later
return $this->scheduleMessage($whatsappMessage, $scheduleAt);
}
// Send immediately
$result = $this->whatsAppService->sendMessage($phoneNumber, $message);
if ($result['success']) {
$whatsappMessage->update([
'message_sid' => $result['message_sid'],
'status' => $result['status'],
'sent_at' => now()
]);
return response()->json([
'success' => true,
'message' => 'WhatsApp message sent successfully',
'data' => [
'message_id' => $whatsappMessage->id,
'message_sid' => $result['message_sid'],
'status' => $result['status']
]
]);
} else {
$whatsappMessage->update(['status' => 'failed']);
return response()->json([
'success' => false,
'message' => 'Failed to send WhatsApp message',
'error' => $result['error']
], 500);
}
}
protected function formatPhoneNumber($phoneNumber)
{
// Remove any non-numeric characters
$phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
// Add country code if not present
if (!str_starts_with($phoneNumber, '1') && strlen($phoneNumber) === 10) {
$phoneNumber = '1' . $phoneNumber;
}
return '+' . $phoneNumber;
}
public function getMessageStatus($messageId)
{
$message = WhatsAppMessage::find($messageId);
if (!$message) {
return response()->json([
'success' => false,
'message' => 'Message not found'
], 404);
}
return response()->json([
'success' => true,
'data' => [
'id' => $message->id,
'status' => $message->status,
'sent_at' => $message->sent_at,
'delivered_at' => $message->delivered_at,
'read_at' => $message->read_at
]
]);
}
}
Create API Routes:
<?php
// routes/api.php
use App\Http\Controllers\WhatsAppController;
Route::prefix('whatsapp')->group(function () {
Route::post('/send-message', [WhatsAppController::class, 'sendMessage']);
Route::get('/message-status/{messageId}', [WhatsAppController::class, 'getMessageStatus']);
Route::post('/send-media', [WhatsAppController::class, 'sendMediaMessage']);
Route::post('/send-template', [WhatsAppController::class, 'sendTemplateMessage']);
});
Send Media Files (Images, Videos, PDFs)
Extend WhatsApp Message Laravel 12 functionality to support rich media content.
Media Message Service Method:
<?php
// Add to WhatsAppService class
public function sendMediaMessage($to, $message, $mediaUrl, $mediaType = 'image')
{
try {
$messageData = [
'from' => $this->from,
'body' => $message,
'mediaUrl' => [$mediaUrl]
];
// Validate media type and URL
if (!$this->isValidMediaUrl($mediaUrl, $mediaType)) {
throw new \Exception("Invalid media URL or type: $mediaType");
}
$message = $this->client->messages->create(
"whatsapp:$to",
$messageData
);
Log::info('WhatsApp media message sent successfully', [
'sid' => $message->sid,
'to' => $to,
'media_url' => $mediaUrl,
'media_type' => $mediaType
]);
return [
'success' => true,
'message_sid' => $message->sid,
'status' => $message->status
];
} catch (\Exception $e) {
Log::error('WhatsApp media message failed', [
'error' => $e->getMessage(),
'to' => $to,
'media_url' => $mediaUrl
]);
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
protected function isValidMediaUrl($url, $type)
{
$allowedTypes = [
'image' => ['jpg', 'jpeg', 'png', 'gif'],
'video' => ['mp4', '3gp'],
'audio' => ['aac', 'amr', 'mpeg', 'mp3', 'ogg'],
'document' => ['pdf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx']
];
$extension = strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION));
return isset($allowedTypes[$type]) && in_array($extension, $allowedTypes[$type]);
}
Media Upload Controller Method:
<?php
// Add to WhatsAppController class
public function sendMediaMessage(Request $request)
{
$validator = Validator::make($request->all(), [
'phone_number' => 'required|string|min:10|max:15',
'message' => 'required|string|max:1600',
'media_file' => 'required|file|max:16384', // 16MB max
'media_type' => 'required|in:image,video,audio,document'
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->errors()
], 422);
}
$phoneNumber = $this->formatPhoneNumber($request->phone_number);
$message = $request->message;
$mediaType = $request->media_type;
// Upload media file
$mediaFile = $request->file('media_file');
$mediaPath = $mediaFile->store('whatsapp-media', 'public');
$mediaUrl = asset('storage/' . $mediaPath);
// Store message in database
$whatsappMessage = WhatsAppMessage::create([
'to_number' => $phoneNumber,
'body' => $message,
'status' => 'pending',
'direction' => 'outbound',
'media_urls' => [$mediaUrl]
]);
// Send media message
$result = $this->whatsAppService->sendMediaMessage($phoneNumber, $message, $mediaUrl, $mediaType);
if ($result['success']) {
$whatsappMessage->update([
'message_sid' => $result['message_sid'],
'status' => $result['status'],
'sent_at' => now()
]);
return response()->json([
'success' => true,
'message' => 'WhatsApp media message sent successfully',
'data' => [
'message_id' => $whatsappMessage->id,
'message_sid' => $result['message_sid'],
'media_url' => $mediaUrl
]
]);
} else {
$whatsappMessage->update(['status' => 'failed']);
return response()->json([
'success' => false,
'message' => 'Failed to send WhatsApp media message',
'error' => $result['error']
], 500);
}
}
Send Message Templates and Buttons
Implement interactive WhatsApp Message Laravel 12 templates with buttons and quick replies.
Template Message Service:
<?php
// Add to WhatsAppService class
public function sendInteractiveMessage($to, $templateData)
{
try {
$messageData = [
'from' => $this->from,
'contentSid' => $templateData['template_id'],
'contentVariables' => json_encode($templateData['variables'] ?? [])
];
$message = $this->client->messages->create(
"whatsapp:$to",
$messageData
);
return [
'success' => true,
'message_sid' => $message->sid,
'status' => $message->status
];
} catch (\Exception $e) {
Log::error('WhatsApp interactive message failed', [
'error' => $e->getMessage(),
'to' => $to,
'template' => $templateData['template_id']
]);
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
public function sendListMessage($to, $body, $listData)
{
try {
$message = $this->client->messages->create(
"whatsapp:$to",
[
'from' => $this->from,
'body' => $body,
'persistentAction' => [
'sections' => $listData['sections']
]
]
);
return [
'success' => true,
'message_sid' => $message->sid,
'status' => $message->status
];
} catch (\Exception $e) {
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
Template Controller Method:
<?php
// Add to WhatsAppController class
public function sendTemplateMessage(Request $request)
{
$validator = Validator::make($request->all(), [
'phone_number' => 'required|string|min:10|max:15',
'template_id' => 'required|string',
'variables' => 'nullable|array'
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->errors()
], 422);
}
$phoneNumber = $this->formatPhoneNumber($request->phone_number);
$templateData = [
'template_id' => $request->template_id,
'variables' => $request->variables ?? []
];
// Store template message
$whatsappMessage = WhatsAppMessage::create([
'to_number' => $phoneNumber,
'template_id' => $templateData['template_id'],
'template_variables' => $templateData['variables'],
'status' => 'pending',
'direction' => 'outbound'
]);
// Send template message
$result = $this->whatsAppService->sendInteractiveMessage($phoneNumber, $templateData);
if ($result['success']) {
$whatsappMessage->update([
'message_sid' => $result['message_sid'],
'status' => $result['status'],
'sent_at' => now()
]);
return response()->json([
'success' => true,
'message' => 'WhatsApp template message sent successfully',
'data' => [
'message_id' => $whatsappMessage->id,
'message_sid' => $result['message_sid']
]
]);
} else {
$whatsappMessage->update(['status' => 'failed']);
return response()->json([
'success' => false,
'message' => 'Failed to send WhatsApp template message',
'error' => $result['error']
], 500);
}
}
Advanced Features
Enhance your WhatsApp Message Laravel 12 implementation with scheduling, automation, and advanced messaging capabilities.
Schedule WhatsApp Messages in Laravel
Implement message scheduling using Laravel’s queue system for timed message delivery.
Create Scheduled Message Job:
<?php
// app/Jobs/SendScheduledWhatsAppMessage.php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Services\WhatsAppService;
use App\Models\WhatsAppMessage;
class SendScheduledWhatsAppMessage implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $messageId;
public function __construct($messageId)
{
$this->messageId = $messageId;
}
public function handle(WhatsAppService $whatsAppService)
{
$message = WhatsAppMessage::find($this->messageId);
if (!$message || $message->status !== 'scheduled') {
return;
}
$result = $whatsAppService->sendMessage(
$message->to_number,
$message->body,
$message->media_urls ? $message->media_urls[0] : null
);
if ($result['success']) {
$message->update([
'message_sid' => $result['message_sid'],
'status' => $result['status'],
'sent_at' => now()
]);
} else {
$message->update(['status' => 'failed']);
}
}
}
Schedule Message Method:
<?php
// Add to WhatsAppController class
protected function scheduleMessage($whatsappMessage, $scheduleAt)
{
$delay = \Carbon\Carbon::parse($scheduleAt)->diffInSeconds(now());
SendScheduledWhatsAppMessage::dispatch($whatsappMessage->id)
->delay($delay);
return response()->json([
'success' => true,
'message' => 'WhatsApp message scheduled successfully',
'data' => [
'message_id' => $whatsappMessage->id,
'scheduled_at' => $scheduleAt,
'status' => 'scheduled'
]
]);
}
public function cancelScheduledMessage($messageId)
{
$message = WhatsAppMessage::find($messageId);
if (!$message || $message->status !== 'scheduled') {
return response()->json([
'success' => false,
'message' => 'Message not found or not scheduled'
], 404);
}
$message->update(['status' => 'cancelled']);
return response()->json([
'success' => true,
'message' => 'Scheduled message cancelled successfully'
]);
}
Handle Incoming WhatsApp Messages
Process and respond to incoming messages automatically in your WhatsApp Message Laravel 12 system.
Enhanced Webhook Handler:
<?php
// Enhanced WhatsAppWebhookController
protected function processIncomingMessage($from, $body)
{
$body = strtolower(trim($body));
// Simple command processing
switch ($body) {
case 'hello':
case 'hi':
$this->sendAutoReply($from, "Hello! Welcome to our service. How can I help you today?");
break;
case 'help':
$helpMessage = "Available commands:\n" .
"• HELLO - Get a greeting\n" .
"• HELP - Show this help menu\n" .
"• STATUS - Check your account status\n" .
"• SUPPORT - Contact customer support";
$this->sendAutoReply($from, $helpMessage);
break;
case 'status':
$this->handleStatusRequest($from);
break;
case 'support':
$this->forwardToSupport($from, $body);
break;
default:
// Handle unrecognized messages
$this->handleUnknownCommand($from, $body);
break;
}
}
protected function sendAutoReply($to, $message)
{
$whatsAppService = app(WhatsAppService::class);
$result = $whatsAppService->sendMessage($to, $message);
if ($result['success']) {
WhatsAppMessage::create([
'message_sid' => $result['message_sid'],
'from_number' => config('services.twilio.whatsapp_from'),
'to_number' => $to,
'body' => $message,
'status' => 'sent',
'direction' => 'outbound',
'sent_at' => now()
]);
}
}
protected function handleStatusRequest($from)
{
// Check user status in your system
$user = \App\Models\User::where('phone_number', $from)->first();
if ($user) {
$statusMessage = "Account Status: Active\n" .
"Member since: " . $user->created_at->format('M Y') . "\n" .
"Last login: " . ($user->last_login_at ? $user->last_login_at->format('M d, Y') : 'Never');
} else {
$statusMessage = "No account found for this number. Please register on our website.";
}
$this->sendAutoReply($from, $statusMessage);
}
protected function forwardToSupport($from, $originalMessage)
{
// Create support ticket or forward to support team
$supportMessage = "Thank you for contacting support. Your message has been forwarded to our team. " .
"Ticket ID: " . strtoupper(substr(md5($from . time()), 0, 8)) .
"\n\nWe'll respond within 24 hours.";
$this->sendAutoReply($from, $supportMessage);
// Notify support team
$this->notifySupportTeam($from, $originalMessage);
}
Multi-user Messaging and Notifications
Implement broadcast messaging and notification systems for WhatsApp Message Laravel 12.
Broadcast Message Service:
<?php
// app/Services/WhatsAppBroadcastService.php
namespace App\Services;
use App\Services\WhatsAppService;
use App\Models\WhatsAppMessage;
use App\Jobs\SendBulkWhatsAppMessage;
use Illuminate\Support\Facades\Log;
class WhatsAppBroadcastService
{
protected $whatsAppService;
public function __construct(WhatsAppService $whatsAppService)
{
$this->whatsAppService = $whatsAppService;
}
public function sendBroadcast($recipients, $message, $scheduleAt = null, $batchSize = 50)
{
$broadcastId = uniqid('broadcast_');
$batches = array_chunk($recipients, $batchSize);
Log::info('Starting WhatsApp broadcast', [
'broadcast_id' => $broadcastId,
'total_recipients' => count($recipients),
'batch_count' => count($batches),
'scheduled_at' => $scheduleAt
]);
foreach ($batches as $index => $batch) {
$delay = $scheduleAt
? \Carbon\Carbon::parse($scheduleAt)->addSeconds($index * 2)
: now()->addSeconds($index * 2);
SendBulkWhatsAppMessage::dispatch($batch, $message, $broadcastId)
->delay($delay);
}
return [
'success' => true,
'broadcast_id' => $broadcastId,
'total_recipients' => count($recipients),
'estimated_duration' => count($batches) * 2 . ' seconds'
];
}
public function getBroadcastStatus($broadcastId)
{
$messages = WhatsAppMessage::where('broadcast_id', $broadcastId)->get();
$statusCounts = $messages->groupBy('status')->map->count();
return [
'broadcast_id' => $broadcastId,
'total_messages' => $messages->count(),
'status_breakdown' => $statusCounts,
'completion_rate' => $messages->count() > 0
? round(($statusCounts['delivered'] ?? 0) / $messages->count() * 100, 2)
: 0
];
}
}
Bulk Message Job:
<?php
// app/Jobs/SendBulkWhatsAppMessage.php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Services\WhatsAppService;
use App\Models\WhatsAppMessage;
class SendBulkWhatsAppMessage implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $recipients;
protected $message;
protected $broadcastId;
public function __construct($recipients, $message, $broadcastId)
{
$this->recipients = $recipients;
$this->message = $message;
$this->broadcastId = $broadcastId;
}
public function handle(WhatsAppService $whatsAppService)
{
foreach ($this->recipients as $recipient) {
try {
// Create message record
$whatsappMessage = WhatsAppMessage::create([
'to_number' => $recipient,
'body' => $this->message,
'status' => 'pending',
'direction' => 'outbound',
'broadcast_id' => $this->broadcastId
]);
// Send message
$result = $whatsAppService->sendMessage($recipient, $this->message);
if ($result['success']) {
$whatsappMessage->update([
'message_sid' => $result['message_sid'],
'status' => $result['status'],
'sent_at' => now()
]);
} else {
$whatsappMessage->update(['status' => 'failed']);
}
// Add delay between messages to respect rate limits
sleep(1);
} catch (\Exception $e) {
\Log::error('Bulk WhatsApp message failed', [
'recipient' => $recipient,
'error' => $e->getMessage(),
'broadcast_id' => $this->broadcastId
]);
}
}
}
}
Integrations
Enhance your WhatsApp Message Laravel 12 system with Laravel’s built-in features and third-party services.
WhatsApp with Laravel Notifications
Integrate WhatsApp messaging with Laravel’s notification system for seamless communication.
Create WhatsApp Notification Channel:
<?php
// app/Channels/WhatsAppChannel.php
namespace App\Channels;
use Illuminate\Notifications\Notification;
use App\Services\WhatsAppService;
class WhatsAppChannel
{
protected $whatsAppService;
public function __construct(WhatsAppService $whatsAppService)
{
$this->whatsAppService = $whatsAppService;
}
public function send($notifiable, Notification $notification)
{
$whatsappData = $notification->toWhatsApp($notifiable);
if (!$whatsappData) {
return;
}
$phoneNumber = $notifiable->routeNotificationFor('whatsapp')
?? $notifiable->phone_number;
if (!$phoneNumber) {
throw new \Exception('No WhatsApp phone number available for notification');
}
return $this->whatsAppService->sendMessage(
$phoneNumber,
$whatsappData['message'],
$whatsappData['media_url'] ?? null
);
}
}
Create WhatsApp Notification Class:
<?php
// app/Notifications/OrderConfirmation.php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use App\Channels\WhatsAppChannel;
class OrderConfirmation extends Notification
{
use Queueable;
protected $order;
public function __construct($order)
{
$this->order = $order;
}
public function via($notifiable)
{
return [WhatsAppChannel::class, 'mail'];
}
public function toWhatsApp($notifiable)
{
$message = "🎉 Order Confirmed!\n\n" .
"Order #: {$this->order->id}\n" .
"Total: $" . number_format($this->order->total, 2) . "\n" .
"Estimated delivery: {$this->order->estimated_delivery}\n\n" .
"Track your order: " . route('orders.track', $this->order->id);
return [
'message' => $message
];
}
public function toMail($notifiable)
{
// Email notification implementation
return (new \Illuminate\Notifications\Messages\MailMessage)
->subject('Order Confirmation #' . $this->order->id)
->line('Your order has been confirmed and is being processed.');
}
}
Use Notification in Your Application:
<?php
// In your controller or service
use App\Notifications\OrderConfirmation;
class OrderController extends Controller
{
public function store(Request $request)
{
// Create order logic
$order = Order::create($request->validated());
// Send WhatsApp notification
$order->user->notify(new OrderConfirmation($order));
return response()->json([
'success' => true,
'message' => 'Order created and confirmation sent via WhatsApp',
'order_id' => $order->id
]);
}
}
Laravel Queues for WhatsApp Messages
Optimize WhatsApp Message Laravel 12 performance using Laravel’s queue system for asynchronous processing.
Configure Queue for WhatsApp:
<?php
// config/queue.php
'connections' => [
'whatsapp' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'whatsapp',
'retry_after' => 90,
],
],
Create Queue-Aware WhatsApp Service:
<?php
// app/Services/QueuedWhatsAppService.php
namespace App\Services;
use App\Jobs\SendWhatsAppMessage;
use App\Models\WhatsAppMessage;
class QueuedWhatsAppService
{
public function queueMessage($to, $message, $delay = null, $priority = 'normal')
{
$whatsappMessage = WhatsAppMessage::create([
'to_number' => $to,
'body' => $message,
'status' => 'queued',
'direction' => 'outbound'
]);
$job = SendWhatsAppMessage::dispatch($whatsappMessage->id)
->onQueue($this->getQueueByPriority($priority));
if ($delay) {
$job->delay($delay);
}
return [
'success' => true,
'message_id' => $whatsappMessage->id,
'status' => 'queued'
];
}
protected function getQueueByPriority($priority)
{
$queues = [
'high' => 'whatsapp-high',
'normal' => 'whatsapp',
'low' => 'whatsapp-low'
];
return $queues[$priority] ?? 'whatsapp';
}
public function queueBulkMessages($recipients, $message, $batchSize = 100)
{
$batches = array_chunk($recipients, $batchSize);
$batchIds = [];
foreach ($batches as $index => $batch) {
$batchId = uniqid('batch_');
$batchIds[] = $batchId;
SendBulkWhatsAppMessage::dispatch($batch, $message, $batchId)
->onQueue('whatsapp-bulk')
->delay(now()->addSeconds($index * 5));
}
return [
'success' => true,
'batch_ids' => $batchIds,
'total_batches' => count($batches)
];
}
}
Process Queues with Workers:
# Start queue workers for different priorities
php artisan queue:work --queue=whatsapp-high,whatsapp,whatsapp-low,whatsapp-bulk
# Monitor queue status
php artisan queue:monitor whatsapp-high whatsapp whatsapp-low
# Restart workers after code changes
php artisan queue:restart
Integrating Twilio/Chat API for WhatsApp
Enhance your WhatsApp Message Laravel 12 system with advanced Twilio features and Chat API integration.
Advanced Twilio Configuration:
<?php
// app/Services/AdvancedWhatsAppService.php
namespace App\Services;
use Twilio\Rest\Client;
use Twilio\Rest\Chat\V2\ServiceContext;
class AdvancedWhatsAppService extends WhatsAppService
{
protected $chatService;
public function __construct()
{
parent::__construct();
$this->chatService = $this->client->chat->v2->services(
config('services.twilio.chat_service_sid')
);
}
public function createWhatsAppConversation($participantPhoneNumber, $friendlyName = null)
{
try {
$conversation = $this->chatService->conversations->create([
'friendlyName' => $friendlyName ?: "WhatsApp Chat - $participantPhoneNumber",
'attributes' => json_encode([
'channel' => 'whatsapp',
'participant_phone' => $participantPhoneNumber,
'created_at' => now()->toISOString()
])
]);
// Add participant to conversation
$participant = $conversation->participants->create([
'identity' => $participantPhoneNumber,
'attributes' => json_encode([
'phone_number' => $participantPhoneNumber,
'channel' => 'whatsapp'
])
]);
return [
'success' => true,
'conversation_sid' => $conversation->sid,
'participant_sid' => $participant->sid
];
} catch (\Exception $e) {
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
public function sendRichMediaMessage($to, $contentSid, $variables = [])
{
try {
$message = $this->client->messages->create(
"whatsapp:$to",
[
'from' => $this->from,
'contentSid' => $contentSid,
'contentVariables' => json_encode($variables)
]
);
return [
'success' => true,
'message_sid' => $message->sid,
'status' => $message->status
];
} catch (\Exception $e) {
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
public function getMessageDeliveryStatus($messageSid)
{
try {
$message = $this->client->messages($messageSid)->fetch();
return [
'success' => true,
'status' => $message->status,
'error_code' => $message->errorCode,
'error_message' => $message->errorMessage,
'date_sent' => $message->dateSent,
'date_updated' => $message->dateUpdated
];
} catch (\Exception $e) {
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
}
Troubleshooting and Best Practices
Implement robust error handling and optimization strategies for your WhatsApp Message Laravel 12 system.
Debugging Common Errors
Identify and resolve common issues in WhatsApp Message Laravel 12 implementations.
Error Handling Service:
<?php
// app/Services/WhatsAppErrorHandler.php
namespace App\Services;
use Illuminate\Support\Facades\Log;
class WhatsAppErrorHandler
{
protected $errorCodes = [
21211 => 'Invalid To phone number',
21212 => 'Invalid From phone number',
21408 => 'Permission to send an SMS/MMS has not been enabled',
21610 => 'Message exceeds size limit',
21614 => 'Message contains prohibited content',
63007 => 'WhatsApp number not opted in',
63016 => 'Message failed to send after all retries'
];
public function handleError($errorCode, $errorMessage, $context = [])
{
$friendlyMessage = $this->errorCodes[$errorCode] ?? $errorMessage;
Log::error('WhatsApp API Error', [
'error_code' => $errorCode,
'error_message' => $errorMessage,
'friendly_message' => $friendlyMessage,
'context' => $context
]);
return [
'error_code' => $errorCode,
'error_message' => $friendlyMessage,
'resolution' => $this->getResolutionSteps($errorCode)
];
}
protected function getResolutionSteps($errorCode)
{
$resolutions = [
21211 => 'Verify the phone number format includes country code (+1234567890)',
21212 => 'Check your Twilio WhatsApp sender number configuration',
21408 => 'Enable WhatsApp messaging in your Twilio console',
21610 => 'Reduce message content to stay within limits (1600 characters)',
21614 => 'Review message content for prohibited terms or links',
63007 => 'User must opt-in by messaging your WhatsApp number first',
63016 => 'Check API credentials and network connectivity'
];
return $resolutions[$errorCode] ?? 'Contact support for assistance';
}
public function validatePhoneNumber($phoneNumber)
{
// Remove all non-numeric characters
$cleaned = preg_replace('/[^0-9]/', '', $phoneNumber);
// Check minimum length
if (strlen($cleaned) < 10) {
return [
'valid' => false,
'error' => 'Phone number too short'
];
}
// Add country code if missing
if (strlen($cleaned) === 10) {
$cleaned = '1' . $cleaned; // Default to US
}
return [
'valid' => true,
'formatted' => '+' . $cleaned
];
}
public function validateMessageContent($message)
{
$issues = [];
// Check length
if (strlen($message) > 1600) {
$issues[] = 'Message exceeds 1600 character limit';
}
// Check for prohibited content patterns
$prohibitedPatterns = [
'/bitcoin|crypto|investment opportunity/i',
'/click here|act now|limited time/i',
'/free money|get rich quick/i'
];
foreach ($prohibitedPatterns as $pattern) {
if (preg_match($pattern, $message)) {
$issues[] = 'Message contains potentially prohibited content';
break;
}
}
return [
'valid' => empty($issues),
'issues' => $issues
];
}
}
Rate Limits and Delivery Issues
Implement proper rate limiting and delivery optimization for WhatsApp Message Laravel 12.
Rate Limiting Service:
<?php
// app/Services/WhatsAppRateLimiter.php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
class WhatsAppRateLimiter
{
protected $limits = [
'messages_per_second' => 1,
'messages_per_minute' => 20,
'messages_per_hour' => 1000,
'messages_per_day' => 10000
];
public function canSendMessage($phoneNumber = null)
{
$checks = [
$this->checkGlobalRate(),
$this->checkPhoneNumberRate($phoneNumber)
];
foreach ($checks as $check) {
if (!$check['allowed']) {
return $check;
}
}
return ['allowed' => true];
}
protected function checkGlobalRate()
{
$key = 'whatsapp:global:rate_limit';
// Check messages per second
$currentSecond = Cache::get($key . ':second:' . date('Y-m-d-H-i-s'), 0);
if ($currentSecond >= $this->limits['messages_per_second']) {
return [
'allowed' => false,
'reason' => 'Global rate limit exceeded (per second)',
'retry_after' => 1
];
}
// Check messages per minute
$currentMinute = Cache::get($key . ':minute:' . date('Y-m-d-H-i'), 0);
if ($currentMinute >= $this->limits['messages_per_minute']) {
return [
'allowed' => false,
'reason' => 'Global rate limit exceeded (per minute)',
'retry_after' => 60
];
}
return ['allowed' => true];
}
protected function checkPhoneNumberRate($phoneNumber)
{
if (!$phoneNumber) {
return ['allowed' => true];
}
$key = 'whatsapp:phone:' . $phoneNumber . ':rate_limit';
// Limit messages per phone number (anti-spam)
$currentHour = Cache::get($key . ':hour:' . date('Y-m-d-H'), 0);
if ($currentHour >= 10) { // Max 10 messages per hour per number
return [
'allowed' => false,
'reason' => 'Phone number rate limit exceeded',
'retry_after' => 3600
];
}
return ['allowed' => true];
}
public function recordMessage($phoneNumber = null)
{
$this->incrementGlobalCounters();
if ($phoneNumber) {
$this->incrementPhoneNumberCounters($phoneNumber);
}
}
protected function incrementGlobalCounters()
{
$key = 'whatsapp:global:rate_limit';
Cache::increment($key . ':second:' . date('Y-m-d-H-i-s'), 1);
Cache::expire($key . ':second:' . date('Y-m-d-H-i-s'), 2);
Cache::increment($key . ':minute:' . date('Y-m-d-H-i'), 1);
Cache::expire($key . ':minute:' . date('Y-m-d-H-i'), 61);
Cache::increment($key . ':hour:' . date('Y-m-d-H'), 1);
Cache::expire($key . ':hour:' . date('Y-m-d-H'), 3601);
}
protected function incrementPhoneNumberCounters($phoneNumber)
{
$key = 'whatsapp:phone:' . $phoneNumber . ':rate_limit';
Cache::increment($key . ':hour:' . date('Y-m-d-H'), 1);
Cache::expire($key . ':hour:' . date('Y-m-d-H'), 3601);
}
}
Secure Your WhatsApp Messaging Flow
Implement security best practices for WhatsApp Message Laravel 12 to protect user data and prevent abuse.
Security Middleware:
<?php
// app/Http/Middleware/WhatsAppSecurityMiddleware.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class WhatsAppSecurityMiddleware
{
public function handle(Request $request, Closure $next)
{
// Verify webhook signature for incoming requests
if ($request->is('webhooks/whatsapp')) {
if (!$this->verifyWebhookSignature($request)) {
Log::warning('Invalid WhatsApp webhook signature', [
'ip' => $request->ip(),
'user_agent' => $request->userAgent()
]);
return response('Unauthorized', 401);
}
}
// Rate limiting for API requests
if ($request->is('api/whatsapp/*')) {
$clientId = $request->user()->id ?? $request->ip();
if (!$this->checkApiRateLimit($clientId)) {
return response()->json([
'error' => 'Rate limit exceeded',
'retry_after' => 60
], 429);
}
}
return $next($request);
}
protected function verifyWebhookSignature(Request $request)
{
$signature = $request->header('X-Twilio-Signature');
if (!$signature) {
return false;
}
$expectedSignature = base64_encode(hash_hmac(
'sha1',
$request->getContent(),
config('services.twilio.auth_token'),
true
));
return hash_equals($signature, $expectedSignature);
}
protected function checkApiRateLimit($clientId)
{
$key = "whatsapp_api_rate_limit:$clientId";
$limit = 100; // requests per hour
$window = 3600; // 1 hour in seconds
$current = \Cache::get($key, 0);
if ($current >= $limit) {
return false;
}
\Cache::put($key, $current + 1, $window);
return true;
}
}
Input Sanitization Service:
<?php
// app/Services/WhatsAppSanitizer.php
namespace App\Services;
class WhatsAppSanitizer
{
public function sanitizePhoneNumber($phoneNumber)
{
// Remove all non-numeric characters
$cleaned = preg_replace('/[^0-9+]/', '', $phoneNumber);
// Validate format
if (!preg_match('/^\+?[1-9]\d{7,14}$/', $cleaned)) {
throw new \InvalidArgumentException('Invalid phone number format');
}
// Ensure country code is present
if (!str_starts_with($cleaned, '+')) {
$cleaned = '+' . $cleaned;
}
return $cleaned;
}
public function sanitizeMessage($message)
{
// Remove potential XSS content
$message = strip_tags($message);
// Remove excessive whitespace
$message = preg_replace('/\s+/', ' ', trim($message));
// Limit message length
if (strlen($message) > 1600) {
$message = substr($message, 0, 1597) . '...';
}
return $message;
}
public function validateMediaUrl($url)
{
// Check if URL is valid
if (!filter_var($url, FILTER_VALIDATE_URL)) {
return false;
}
// Check if URL uses HTTPS
if (!str_starts_with($url, 'https://')) {
return false;
}
// Check file extension
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'mp4', 'pdf', 'doc', 'docx'];
$extension = strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION));
return in_array($extension, $allowedExtensions);
}
}
Key Takeaways
Successfully implementing WhatsApp Message Laravel 12 integration requires careful planning, proper security measures, and adherence to best practices. This comprehensive guide provides you with the foundation to build robust WhatsApp messaging functionality into your Laravel applications.
Essential implementation principles:
- Always validate and sanitize user inputs before sending messages
- Implement proper rate limiting to comply with API restrictions
- Use Laravel’s queue system for high-volume messaging
- Secure webhook endpoints with proper signature verification
- Monitor message delivery status and handle failures gracefully
Best practices for WhatsApp Message Laravel 12:
- Store message history for analytics and debugging purposes
- Implement opt-in/opt-out functionality for compliance
- Use message templates for better delivery rates
- Set up proper error handling and logging
- Regular monitoring of API usage and costs
- Test thoroughly in sandbox environment before production
By following this guide, you’ll have a production-ready WhatsApp messaging system that enhances user engagement and provides reliable communication channels for your Laravel 12 applications.