Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Twilio Notifier Laravel Package

symfony/twilio-notifier

Symfony Notifier bridge for Twilio. Configure via TWILIO_DSN (SID, token, from) to send SMS, and customize messages with TwilioOptions such as webhook URL and other provider-specific settings.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup for Laravel

  1. Install the Package (via Composer):

    composer require symfony/twilio-notifier
    

    Note: Laravel doesn’t natively use Symfony’s Messenger, so this package will require adaptation.

  2. Configure Twilio DSN in .env:

    TWILIO_DSN=twilio://SID:TOKEN@default?from=+1234567890
    

    Replace SID, TOKEN, and from with your Twilio credentials.

  3. Create a Symfony Messenger Transport Adapter (Laravel doesn’t use Messenger natively, so wrap it):

    // app/Providers/AppServiceProvider.php
    use Symfony\Component\Notifier\Notifier;
    use Symfony\Component\Notifier\Transport\TwilioDsn;
    
    public function register()
    {
        $this->app->singleton('twilio.notifier', function ($app) {
            $dsn = new TwilioDsn($_ENV['TWILIO_DSN']);
            return new Notifier([$dsn]);
        });
    }
    
  4. First Use Case: Send an SMS

    use Symfony\Component\Notifier\Message\SmsMessage;
    
    $notifier = app('twilio.notifier');
    $message = new SmsMessage('+15551234567', 'Hello from Laravel!');
    $notifier->send($message);
    

Implementation Patterns

1. Message Customization

Use TwilioOptions for advanced features like media, webhooks, or status callbacks:

use Symfony\Component\Notifier\Bridge\Twilio\TwilioOptions;

$sms = new SmsMessage('+15551234567', 'Your OTP: 123456');
$options = (new TwilioOptions())
    ->mediaUrl('https://example.com/verification.png')
    ->statusCallback('https://your-app.com/twilio/callback')
    ->statusCallbackMethod('POST');

$sms->options($options);
$notifier->send($sms);

2. Integration with Laravel Queues

Wrap the notifier in a Laravel job for async processing:

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Symfony\Component\Notifier\Message\SmsMessage;

class SendSmsJob implements ShouldQueue
{
    use Queueable;

    public function handle()
    {
        $notifier = app('twilio.notifier');
        $message = new SmsMessage('+15551234567', 'Queued message!');
        $notifier->send($message);
    }
}

3. Webhook Handling

Leverage Symfony’s webhook validation for security:

// routes/web.php
use Symfony\Component\Notifier\Bridge\Twilio\WebhookValidator;

Route::post('/twilio/webhook', function (Request $request) {
    $validator = new WebhookValidator($_ENV['TWILIO_AUTH_TOKEN']);
    if ($validator->validate($request->headers->all(), $request->getContent())) {
        // Process webhook
    }
});

4. Dynamic Recipients

Use Laravel’s collections or Eloquent to batch-send messages:

use Symfony\Component\Notifier\Message\SmsMessage;

$users = User::where('needs_notification', true)->get();
$notifier = app('twilio.notifier');

foreach ($users as $user) {
    $notifier->send(new SmsMessage($user->phone, "Hello, {$user->name}!"));
}

5. Fallback Channels

Combine Twilio with other channels (e.g., email) for reliability:

use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Message\Email;

$notifier = app('twilio.notifier');
$notifier->send([
    new SmsMessage('+15551234567', 'Primary SMS'),
    new Email('user@example.com', 'Fallback Email', 'Backup content'),
]);

Gotchas and Tips

Pitfalls

  1. Symfony Dependency Overhead

    • The package assumes Symfony’s Messenger component. In Laravel, you’ll need to:
      • Manually handle message serialization/deserialization.
      • Mock Symfony’s Transport interface for testing.
    • Workaround: Create a thin Laravel facade to hide Symfony dependencies.
  2. Queue Integration Quirks

    • Laravel Queues expect ShouldQueue jobs, but Symfony’s Notifier is synchronous by default.
    • Workaround: Wrap the notifier in a job (as shown above) and ensure retries are configured.
  3. Webhook Security

    • The package validates HMAC signatures, but Laravel’s routing may interfere.
    • Tip: Use middleware to validate signatures before processing:
      Route::post('/webhook', function () {
          $validator = new WebhookValidator($_ENV['TWILIO_AUTH_TOKEN']);
          if (!$validator->validate(request()->headers, request()->getContent())) {
              abort(403);
          }
          // Process
      })->middleware('throttle:60,1');
      
  4. Number Validation

    • Twilio enforces strict number formats (e.g., E.164). Laravel’s input validation may not catch this.
    • Tip: Use a validator rule:
      use Symfony\Component\Notifier\Bridge\Twilio\Validator\PhoneNumberValidator;
      
      $validator = new PhoneNumberValidator();
      if (!$validator->validate('+15551234567')) {
          throw new \InvalidArgumentException('Invalid phone number');
      }
      
  5. Rate Limiting

    • Twilio has default rate limits (e.g., 1 SMS/sec). The package doesn’t handle this.
    • Tip: Use Laravel’s throttle middleware or a queue with batching:
      Queue::later(now()->addSeconds(1), new SendSmsJob());
      

Debugging Tips

  1. Enable Symfony Notifier Logging Add to config/logging.php:

    'channels' => [
        'notifier' => [
            'driver' => 'single',
            'path' => storage_path('logs/notifier.log'),
            'level' => 'debug',
        ],
    ],
    

    Then configure the notifier to use this channel.

  2. Inspect Raw Twilio Requests Use a debug transport to log outgoing requests:

    $notifier = new Notifier([
        new DebugTransport(new TwilioDsn($_ENV['TWILIO_DSN'])),
    ]);
    
  3. Test with Twilio Sandbox Use Twilio’s sandbox for development to avoid costs:

    TWILIO_DSN=twilio://SID:TOKEN@sandbox?from=+1234567890
    

Extension Points

  1. Custom Transports Extend Symfony\Component\Notifier\Transport\TransportInterface to support non-Twilio channels:

    class CustomTransport implements TransportInterface
    {
        public function __invoke(MessageInterface $message, array $failedRecipients = []): void
        {
            // Custom logic
        }
    }
    
  2. Message Transformers Modify message content before sending:

    $message = new SmsMessage('+15551234567', 'Default content');
    $message->setContent(fn ($content) => strtoupper($content));
    
  3. Event Listeners Hook into Symfony’s MessageSentEvent (requires Symfony’s EventDispatcher):

    $dispatcher->addListener(MessageSentEvent::class, function (MessageSentEvent $event) {
        // Log or analyze sent messages
    });
    

Laravel-Specific Quirks

  1. Service Container Binding Avoid circular dependencies by binding the notifier as a singleton:

    $this->app->singleton('twilio.notifier', function ($app) {
        return new Notifier([new TwilioDsn($_ENV['TWILIO_DSN'])]);
    });
    
  2. Configuration Management Use Laravel’s config system to centralize Twilio settings:

    // config/services.php
    'twilio' => [
        'dsn' => env('TWILIO_DSN'),
        'from' => env('TWILIO_FROM'),
    ],
    

    Then inject via constructor:

    public function __construct(public array $config) {}
    
  3. Testing Mock the notifier in tests:

    $notifier = Mockery::mock(Notifier::class);
    $notifier->shouldReceive('send')->once();
    $this->app->instance('twilio.notifier', $notifier);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity