laravel/nexmo-notification-channel
Official Laravel notification channel for sending SMS through Vonage (formerly Nexmo). Integrates with Laravel's notification system and the Vonage API, with full documentation, contribution guidelines, and an MIT license.
Installation:
composer require laravel/vonage-notification-channel
Publish the config file:
php artisan vendor:publish --provider="Vonage\LaravelNotificationChannel\VonageServiceProvider"
Configuration:
Add Vonage credentials to .env:
VONAGE_KEY=your_api_key
VONAGE_SECRET=your_api_secret
VONAGE_SMS_FROM=YourApp
First Use Case: Send an SMS notification via a Notification class:
use Vonage\LaravelNotificationChannel\VonageChannel;
use Illuminate\Notifications\Notification;
class OrderPlaced extends Notification
{
public function via($notifiable)
{
return [VonageChannel::class];
}
public function toVonage($notifiable)
{
return 'Your order #12345 has been placed!';
}
}
Trigger it in a controller:
$user->notify(new OrderPlaced());
Multi-Channel Notifications: Combine Vonage SMS with other channels (e.g., Mail, Slack) in a single notification:
public function via($notifiable)
{
return [VonageChannel::class, MailChannel::class];
}
Dynamic Recipients:
Use toVonage() to dynamically construct messages based on user data:
public function toVonage($notifiable)
{
return "Hello {$notifiable->name}, your verification code is: {$this->code}";
}
Queue Integration: Leverage Laravel’s queue system for async SMS delivery:
$user->notify(new OrderPlaced())->onQueue('sms');
Customizing Sender:
Override the default sender in config/services.php:
'vonage' => [
'sms' => [
'from' => 'CustomSenderName',
],
],
Attachments (Media): Send SMS with a link to a media file (e.g., invoice PDF):
public function toVonage($notifiable)
{
return "Your invoice is ready: " . route('invoices.show', $this->invoiceId);
}
Two-Way Messaging: Use Vonage’s Two-Way Messaging API for interactive SMS (requires custom logic outside this package).
Rate Limiting:
Implement rate limiting in AppServiceProvider:
use Illuminate\Support\Facades\RateLimiter;
RateLimiter::for('sms', function ($request) {
return Limit::perMinute(5)->by($request->user()?->id);
});
Fallback Channels: Add a fallback channel if Vonage fails:
public function via($notifiable)
{
return [VonageChannel::class, MailChannel::class];
}
API Credentials:
.env without .gitignore.AppServiceProvider:
if (empty(config('services.vonage.key'))) {
throw new RuntimeException('Vonage API key not configured.');
}
Character Limits:
Str::limit() or a package like spatie/array-to-xml for long messages.Testing:
MockVonage in tests:
$this->actingAs($user)
->fake()
->vonage()
->assertSent(function ($notification) {
return $notification->message === 'Test message';
});
Error Handling:
400 Bad Request for invalid numbers).use Vonage\Client\Exceptions\VonageException;
public function send($notifiable, $message)
{
try {
parent::send($notifiable, $message);
} catch (VonageException $e) {
Log::error("Vonage SMS failed: {$e->getMessage()}");
throw $e;
}
}
Regional Numbers:
config/services.php:
'vonage' => [
'sms' => [
'from' => '1234567890', // US number
'regional' => [
'UK' => '441234567890',
],
],
],
$sender = config("services.vonage.sms.regional.{$notifiable->locale}") ?? config('services.vonage.sms.from');
Unicode Support:
Webhook Validation:
public function handle($request, Closure $next)
{
$signature = $request->header('X-Vonage-Signature');
$expected = hash_hmac('sha1', $request->getContent(), config('services.vonage.secret'));
if (!hash_equals($signature, $expected)) {
abort(403);
}
return $next($request);
}
Custom Channel Logic:
Extend the VonageChannel class to add features like:
Route::post('/vonage-webhook', [VonageWebhookController::class, 'handle']);
Database Logging:
Log sent SMS to a notifications table:
public function send($notifiable, $message)
{
$notifiable->routeNotificationFor('vonage', $notifiable->phone);
$sent = parent::send($notifiable, $message);
$notifiable->notifications()->create([
'type' => 'sms',
'data' => ['message' => $message],
'read_at' => null,
]);
return $sent;
}
Batch Processing:
Use Laravel’s Bus to send bulk SMS efficiently:
$users->each->notify(new OrderPlaced())->onQueue('sms-bulk');
How can I help you explore Laravel packages today?