Installation:
composer require djunehor/laravel-sms
Publish the config file:
php artisan vendor:publish --provider="Djunehor\LaravelSms\LaravelSmsServiceProvider" --tag="config"
Add the SMS facade to your config/app.php:
'aliases' => [
// ...
'SMS' => Djunehor\LaravelSms\Facades\SMS::class,
],
Configure Provider:
Edit config/sms.php and set your preferred provider (e.g., twilio, nexmo, clickatell). Example for Twilio:
'twilio' => [
'account_sid' => env('TWILIO_SID'),
'auth_token' => env('TWILIO_TOKEN'),
'from' => env('TWILIO_FROM'),
],
First Use Case: Send an SMS via the facade:
use SMS;
SMS::send('twilio', '+1234567890', 'Hello from Laravel!');
Or use a queueable job:
php artisan make:job SendSmsJob
// In SendSmsJob.php
public function handle()
{
SMS::send('twilio', '+1234567890', 'Hello from a job!');
}
Provider-Specific Configuration:
TWILIO_SID, NEXMO_KEY).config/sms.php per environment (e.g., sms.php for staging vs. production).Sending SMS:
SMS::send($provider, $to, $message, $options = []);
Example with options (e.g., Twilio media URL):
SMS::send('twilio', '+1234567890', 'Check this out!', [
'media_url' => 'https://example.com/image.jpg'
]);
dispatch(new SendSmsJob('nexmo', '+1234567890', 'Async message'));
Custom Providers:
Extend the base Provider class to integrate with unsupported services:
namespace App\Providers;
use Djunehor\LaravelSms\Providers\Provider;
class CustomProvider extends Provider
{
public function send($to, $message, array $options = [])
{
// Custom logic (e.g., HTTP request to your SMS API)
return $this->client->send($to, $message);
}
}
Register in config/sms.php:
'providers' => [
'custom' => \App\Providers\CustomProvider::class,
],
Logging and Retries:
php artisan queue:work --sleep=3 --tries=3
SMS::fail() or use Laravel’s default job failure channels.Testing:
SMS::setProvider('mock');
SMS::send('mock', '+1234567890', 'Test message');
$this->assertEquals('Test message', SMS::getLastMessage());
Provider-Specific Quirks:
from number is verified in Twilio console. Use E.164 format for phone numbers (e.g., +1234567890).Rate Limits:
retry-after middleware for queues.Character Limits:
SMS::send('twilio', '+1234567890', Str::of($message)->limit(150));
Environment Mismatches:
config/sms.php points to the correct provider for each environment (e.g., mock for local, twilio for production).Queue Stuck Jobs:
php artisan queue:failed-table
php artisan queue:retry <job-id>
Enable Logging:
Add to config/sms.php:
'log' => true,
Check storage/logs/laravel.log for SMS-related entries.
Provider-Specific Errors:
http_errors in logs for HTTP 4xx/5xx responses.message-id in responses to confirm delivery.Network Issues:
curl to test provider APIs directly:
curl -X POST https://api.twilio.com/2010-04-01/Accounts/{SID}/Messages.json \
-d "To=+1234567890" \
-d "From=+1987654321" \
-d "Body=Test" \
-u {SID}:{TOKEN}
Custom Responses:
Extend the Provider class to handle provider-specific responses (e.g., Nexmo’s message-uuid):
public function send($to, $message, array $options = [])
{
$response = $this->client->send($to, $message);
return [
'success' => true,
'message_id' => $response->message_uuid ?? null,
];
}
Webhook Handling:
For delivery receipts, create a route to handle provider webhooks (e.g., Twilio’s MessageStatus):
Route::post('/sms/webhook', function (Request $request) {
SMS::handleWebhook($request->all());
});
Fallback Providers:
Implement a fallback chain in config/sms.php:
'fallback' => ['twilio', 'nexmo', 'clickatell'],
The package will attempt providers in order until one succeeds.
Template Messages: Use Blade templates for dynamic SMS content:
$message = view('emails.sms-template', ['name' => 'John'])->render();
SMS::send('twilio', '+1234567890', $message);
Batch Sending: For bulk SMS, loop through recipients and use batch processing:
foreach ($recipients as $phone) {
SMS::send('twilio', $phone, 'Batch message')->onQueue('sms');
}
Process queues in parallel with Laravel Horizon or multiple queue workers.
How can I help you explore Laravel packages today?