symfony/free-mobile-notifier
Symfony Notifier integration for Free Mobile SMS. Configure a freemobile:// DSN with your Free Mobile login, API key, and phone number to send notifications to your personal mobile via Free Mobile’s SMS notification service.
Install the Package
composer require symfony/free-mobile-notifier
Configure the DSN
Add to .env:
FREE_MOBILE_DSN=freemobile://LOGIN:API_KEY@default?phone=PHONE_NUMBER
Replace:
LOGIN: Your Free Mobile account login.API_KEY: Found in Free Mobile account settings.PHONE_NUMBER: Your Free Mobile phone number (e.g., +33612345678).Register the Transport in Laravel
Create a service provider (e.g., FreeMobileServiceProvider) and bind the Symfony Notifier transport:
use Symfony\Component\Notifier\Notifier;
use Symfony\Component\Notifier\Transport\FreeMobileTransport;
public function register()
{
$this->app->singleton('freemobile.transport', function ($app) {
$dsn = $app['config']['services.freemobile.dsn'];
return new FreeMobileTransport($dsn);
});
}
Send Your First SMS
Use Laravel’s Notifier facade (or inject the transport directly):
use Illuminate\Notifications\Notifiable;
use Symfony\Component\Notifier\Notifier;
class User extends Model implements Notifiable
{
public function routeNotificationForFreeMobile()
{
return '+33612345678'; // Override phone if needed
}
}
// In a controller or command:
$user = User::find(1);
$notifier = new Notifier([$this->app->make('freemobile.transport')]);
$notifier->send(new FreeMobileMessage('Hello from Laravel!'), $user);
Use Case: Order confirmations, password resets, or OTPs.
Pattern: Extend Laravel’s Notification class to support Free Mobile:
use Illuminate\Notifications\Notification;
use Symfony\Component\Notifier\Message\SmsMessage;
class FreeMobileNotification implements Notification
{
public function via($notifiable)
{
return ['freemobile'];
}
public function toFreeMobile($notifiable)
{
return (new SmsMessage('Your OTP is: 123456'))
->from('Laravel App', '+33123456789');
}
}
Trigger:
$user->notify(new FreeMobileNotification());
Use Case: Real-time fraud alerts or system failures. Pattern: Listen to Laravel events and dispatch SMS via Notifier:
use Illuminate\Support\Facades\Event;
use Symfony\Component\Notifier\Notifier;
Event::listen('fraud.detected', function ($fraudEvent) {
$notifier = app(Notifier::class);
$notifier->send(
new SmsMessage("Fraud alert! IP: {$fraudEvent->ip}"),
'+33612345678'
);
});
Use Case: Ensure critical messages are delivered even if SMS fails. Pattern: Combine Free Mobile with email/Slack:
use Symfony\Component\Notifier\Notifier;
use Symfony\Component\Notifier\Bridge\Slack\SlackTransport;
$notifier = new Notifier([
$this->app->make('freemobile.transport'),
new SlackTransport('slack://token@channel'),
]);
$notifier->send(new SmsMessage('Critical alert!'), $user);
Use Case: Avoid hitting Free Mobile’s API limits (e.g., 1 SMS/sec). Pattern: Use Laravel’s queue system with throttling:
use Illuminate\Bus\Queueable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Symfony\Component\Notifier\Message\SmsMessage;
class SendSmsJob implements Queueable, InteractsWithQueue, SerializesModels
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
$notifier = app(Notifier::class);
$notifier->send(new SmsMessage('Throttled alert'), $this->phone);
}
}
// Dispatch with delay:
SendSmsJob::dispatch($phone)->delay(now()->addSeconds(10));
Service Provider Binding
Override Symfony’s Notifier to work with Laravel’s container:
public function register()
{
$this->app->bind('notifier', function ($app) {
$transports = [
$app->make('freemobile.transport'),
// Add other transports (e.g., Slack, Email)
];
return new Notifier($transports);
});
}
Configuration Publishing
Publish Symfony’s config to Laravel’s config/services.php:
public function boot()
{
$this->publishes([
__DIR__.'/config/freemobile.php' => config_path('services/freemobile.php'),
], 'freemobile-config');
}
Event Listeners
Bridge Symfony events to Laravel’s Event system:
use Symfony\Component\Notifier\EventListener\NotificationFailedListener;
use Illuminate\Support\Facades\Log;
$this->app->make(NotificationFailedListener::class)
->setOnNotificationFailed(function ($event) {
Log::error("SMS failed: {$event->getMessage()}");
});
Mocking the Transport
Use Laravel’s Mockery or PHPUnit’s createMock:
$transport = $this->createMock(FreeMobileTransport::class);
$transport->expects($this->once())
->method('send')
->with($this->isInstanceOf(SmsMessage::class));
$notifier = new Notifier([$transport]);
Environment-Based Testing
Use Laravel’s .env.testing to switch DSNs:
FREE_MOBILE_DSN=freemobile://test:key@default?phone=+33600000000
DSN Validation
phone parameter. Omitting it throws cryptic errors.?phone=PHONE_NUMBER in the DSN, even if defaulted in config.Character Limits
SmsMessage::withUnicode() for extended characters (e.g., emojis) and check length:
if (strlen($message) > 160) {
throw new \RuntimeException('Message exceeds 160 characters');
}
API Rate Limits
throttle middleware or use queues with delays:
$notifier->send(/* ... */)->delay(1000); // 1-second delay
Phone Number Validation
+33612345678). Invalid numbers fail silently.Validator:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make(['phone' => $phone], [
'phone' => 'required|regex:/^\+33[67]\d{8}$/',
]);
Webhook Security
Route::middleware(['web', 'ip:123.45.67.89'])->post('/free-mobile/webhook', [FreeMobileWebhookController::class, 'handle']);
Symfony Dependency Conflicts
http-client or event-dispatcher.replace directive or aliases:
"replace": {
How can I help you explore Laravel packages today?