A simple, unified SMS integration library for Laravel. Send SMS messages through multiple providers with a consistent API.
- Send SMS
- Send Scheduled SMS
- Send Bulk SMS
- Log SMS messages (database or file)
- Multiple provider support
- Custom provider extensibility
- Advanta - Kenya SMS gateway
- Africa's Talking - Pan-African SMS gateway
- Twilio - Global SMS provider
- Nexmo/Vonage - Global SMS provider
- Onfon Media - Kenya SMS gateway
- Custom - Build your own provider
composer require moffhub/sms-handlerPublish the config and migrations:
php artisan vendor:publish --provider="Moffhub\SmsHandler\SmsHandlerServiceProvider" --tag=config
php artisan vendor:publish --tag=migrations
php artisan migrateAdd the following to your .env file based on your provider:
# Provider selection
SMS_PROVIDER=at # Options: advanta, at, onfon, twilio, nexmo
# Africa's Talking
AT_USERNAME=sandbox # Use 'sandbox' for testing, your app username for production
AT_API_KEY=your_api_key
AT_FROM=YOUR_SENDER_ID # Optional: Your registered sender ID/short code
AT_API_URL= # Optional: Custom API URL (auto-detected based on username)
# Advanta
ADVANTA_API_KEY=
ADVANTA_API_URL=
ADVANTA_BULK_API_URL=
ADVANTA_PARTNER_ID=
ADVANTA_SHORT_CODE=
# Onfon Media
ONFON_API_KEY=
ONFON_API_URL=
ONFON_SENDER_ID=
ONFON_CLIENT_ID=
# Nexmo/Vonage
NEXMO_KEY=
NEXMO_SECRET=
NEXMO_FROM=NEXMO
NEXMO_API_URL=https://rest.nexmo.com/sms/json
# Twilio
TWILIO_SID=
TWILIO_TOKEN=
TWILIO_FROM=
TWILIO_API_URL=https://api.twilio.com
# Logging
SMS_LOG_CHANNEL=log # Options: log, modeluse Moffhub\SmsHandler\Facades\Sms;
// Send a single SMS
Sms::sendSms('+254712345678', 'Hello World');
// Send bulk SMS
Sms::sendBulkSms(['+254712345678', '+254712345679'], 'Hello everyone!');
// Send scheduled SMS
Sms::sendScheduledSms('+254712345678', 'Reminder!', '2024-12-25 09:00:00');
// Check delivery status
$status = Sms::getSmsDeliveryStatus('message_id_here');use Moffhub\SmsHandler\Services\SmsService;
class NotificationController extends Controller
{
public function __construct(protected SmsService $smsService) {}
public function notify(Request $request)
{
$this->smsService->sendSms(
$request->phone,
$request->message
);
}
}use Moffhub\SmsHandler\SmsManager;
$manager = app(SmsManager::class);
// Use Africa's Talking for this message
$manager->driver('at')->sendSms('+254712345678', 'Via AT');
// Use Twilio for this message
$manager->driver('twilio')->sendSms('+1234567890', 'Via Twilio');The library fully supports the Africa's Talking Bulk SMS API:
AT_USERNAME=sandbox
AT_API_KEY=your_sandbox_api_keyAT_USERNAME=your_app_username
AT_API_KEY=your_production_api_key
AT_FROM=YOUR_SENDER_ID- Automatic sandbox/production URL detection
- Phone number formatting (supports 0712..., 254712..., +254712...)
- Bulk SMS with enqueue support
- Sender ID/Short code support
- Detailed response handling with message IDs and costs
Create your own provider by extending CustomProvider:
use Moffhub\SmsHandler\Providers\CustomProvider;
use Illuminate\Support\Collection;
class MySmsProvider extends CustomProvider
{
protected function getApiUrl(): string
{
return 'https://api.custom.com/send';
}
protected function buildPayload(string $to, string $message): array
{
return [
'to' => $to,
'text' => $message,
'api_key' => $this->config['key'],
];
}
protected function handleResponse(mixed $response): ?Collection
{
return collect([
'status' => $response['status'] ?? 'unknown',
]);
}
}Register your provider:
// In a service provider
use Moffhub\SmsHandler\SmsManager;
$this->app->make(SmsManager::class)->extend('custom', function ($app) {
return new MySmsProvider([
'key' => config('sms.providers.custom.key'),
]);
});Add config:
// config/sms.php
'providers' => [
'custom' => [
'key' => env('MY_CUSTOM_API_KEY'),
],
],Update .env:
SMS_PROVIDER=custom
MY_CUSTOM_API_KEY=super-secretUse SMS in Laravel notifications:
use Moffhub\SmsHandler\Notifications\SmsChannel;
class OrderShipped extends Notification
{
public function via($notifiable): array
{
return [SmsChannel::class];
}
public function toSms($notifiable): string
{
return 'Your order has been shipped!';
}
}Ensure your notifiable model has a routeNotificationForSms method:
public function routeNotificationForSms(): string
{
return $this->phone;
}SMS messages can be logged to file or database:
# Log to Laravel's log file
SMS_LOG_CHANNEL=log
# Log to database (requires migration)
SMS_LOG_CHANNEL=modelcomposer testMIT License. See LICENSE for details.