Installation:
composer require mr-rijal/laravel-sms
Publish the config file:
php artisan vendor:publish --provider="MrRijal\LaravelSms\SmsServiceProvider"
Configuration:
Edit config/sms.php to define your preferred gateway (e.g., nexmo, twilio, aws-sns) and credentials.
First Use Case: Send a basic SMS via a controller:
use MrRijal\LaravelSms\Facades\Sms;
public function sendWelcomeSms()
{
Sms::send([
'to' => '1234567890',
'body' => 'Welcome to our platform!'
]);
}
Key Files:
config/sms.php: Gateway and channel configurations.app/Providers/SmsServiceProvider.php: Extend or override default behavior.routes/sms.php: Predefined routes for testing (if enabled).Gateway-Specific Configuration:
Define gateways in config/sms.php:
'gateways' => [
'nexmo' => [
'key' => env('NEXMO_KEY'),
'secret' => env('NEXMO_SECRET'),
'from' => env('NEXMO_FROM'),
],
'twilio' => [
'sid' => env('TWILIO_SID'),
'token' => env('TWILIO_TOKEN'),
'from' => env('TWILIO_FROM'),
],
],
Sending SMS:
Sms::send(['to' => '1234567890', 'body' => 'Hello']);
Sms::send(['to' => '1234567890', 'body' => 'Hello'], 'nexmo');
Sms::queue(['to' => '1234567890', 'body' => 'Hello']);
Templates and Variables:
Use named templates in config/sms.php:
'templates' => [
'welcome' => [
'body' => 'Hi {name}, welcome to {app}!',
],
],
Send with variables:
Sms::send([
'to' => '1234567890',
'template' => 'welcome',
'variables' => ['name' => 'John', 'app' => 'MyApp'],
]);
Events and Listeners:
Listen for SMS events (e.g., SmsSent, SmsFailed):
// In EventServiceProvider
protected $listen = [
'MrRijal\LaravelSms\Events\SmsSent' => [
'App\Listeners\LogSmsSent',
],
];
Testing:
Use the log channel for testing:
'channels' => [
'log' => [
'driver' => 'log',
],
],
Then send via:
Sms::send(['to' => '1234567890', 'body' => 'Test'], 'log');
Queue Management: Ensure your queue worker is running:
php artisan queue:work
For large volumes, consider batching or delayed queues.
Fallback Gateways:
Configure fallback gateways in config/sms.php:
'fallback' => ['nexmo', 'twilio'],
The package will attempt secondary gateways if the primary fails.
Logging:
Enable logging in config/sms.php:
'log' => true,
Logs will appear in storage/logs/laravel-sms.log.
API Integration: For custom APIs, create a custom gateway:
// app/Providers/SmsServiceProvider.php
public function register()
{
$this->app->extend('sms.gateways', function ($gateways) {
$gateways['custom'] = new \App\Sms\CustomGateway();
return $gateways;
});
}
Rate Limiting: Use Laravel's rate limiting middleware for SMS endpoints:
Route::middleware(['throttle:60,1'])->group(function () {
// SMS-related routes
});
Environment Variables:
Ensure all gateway credentials are set in .env before sending. Missing keys will throw InvalidArgumentException.
Queue Stuck Jobs: If jobs are stuck, check the queue table for failed jobs and retry manually:
php artisan queue:retry all
Character Limits: Some gateways (e.g., Twilio) enforce strict character limits (~1600 chars for Unicode). Test long messages in staging.
Timeouts:
Gateway timeouts (default: 30s) may cause jobs to fail silently. Increase in config/sms.php:
'timeout' => 60,
International Numbers:
Ensure numbers are in E.164 format (e.g., +1234567890). Use the e164 package for validation:
use E164\PhoneNumber;
$number = PhoneNumber::parse('1234567890')->formatE164();
Enable Debug Mode:
Set debug: true in config/sms.php to log raw API responses:
'debug' => env('APP_DEBUG', false),
Check Logs:
Inspect storage/logs/laravel-sms.log for gateway-specific errors (e.g., Twilio API rejections).
Gateway-Specific Issues:
from number is verified in your Nexmo dashboard.from number is purchased in your Twilio console.Common Errors:
SmsException: Catch and handle gateway-specific exceptions:
try {
Sms::send([...]);
} catch (\MrRijal\LaravelSms\Exceptions\SmsException $e) {
Log::error('SMS failed: ' . $e->getMessage());
}
Custom Gateways:
Extend the MrRijal\LaravelSms\Contracts\Gateway interface:
class CustomGateway implements Gateway
{
public function send($message)
{
// Custom logic
}
}
Register in SmsServiceProvider.
Override Default Behavior:
Bind the SmsManager interface to a custom implementation:
$this->app->bind(\MrRijal\LaravelSms\Contracts\SmsManager::class, function ($app) {
return new \App\Sms\CustomSmsManager($app);
});
Add Custom Fields:
Extend the Message class:
class CustomMessage extends \MrRijal\LaravelSms\Message
{
protected $customField;
public function setCustomField($value)
{
$this->customField = $value;
return $this;
}
}
Update the SmsManager to handle the new field.
Webhooks:
Listen for gateway webhooks (e.g., Twilio's message.created) to update delivery status:
Route::post('/sms/webhook', [SmsWebhookController::class, 'handle']);
Batch Processing:
Use Laravel's chunk method for bulk SMS:
User::chunk(100, function ($users) {
foreach ($users as $user) {
Sms::queue(['to' => $user->phone, 'body' => 'Your message']);
}
});
Cache Gateways: Cache gateway instances to reduce overhead:
$this->app->singleton(\MrRijal\LaravelSms\Contracts\Gateway::class, function ($app) {
return new \MrRijal\LaravelSms\Gateways\NexmoGateway(config('sms.gateways.nexmo'));
});
Async Validation: Validate phone numbers asynchronously to
How can I help you explore Laravel packages today?