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: Since Laravel doesn’t natively use Symfony’s Messenger, install the standalone Twilio SDK for direct Laravel integration:

    composer require twilio/sdk
    
  2. Configure Environment Variables: Add to .env:

    TWILIO_SID=your_account_sid
    TWILIO_TOKEN=your_auth_token
    TWILIO_FROM=+1234567890  # Your Twilio number
    
  3. First Use Case: Send an SMS Create a service to wrap Twilio’s client (Laravel-style):

    // app/Services/TwilioNotifier.php
    namespace App\Services;
    
    use Twilio\Rest\Client;
    
    class TwilioNotifier
    {
        protected Client $client;
    
        public function __construct()
        {
            $this->client = new Client(
                config('services.twilio.sid'),
                config('services.twilio.token')
            );
        }
    
        public function sendSms(string $to, string $body): void
        {
            $this->client->messages->create(
                $to,
                [
                    'from' => config('services.twilio.from'),
                    'body' => $body,
                ]
            );
        }
    }
    
  4. Register the Service: Bind it in AppServiceProvider:

    public function register()
    {
        $this->app->singleton(TwilioNotifier::class);
    }
    
  5. Usage in Controllers/Jobs:

    use App\Services\TwilioNotifier;
    
    public function sendWelcomeSms()
    {
        $notifier = app(TwilioNotifier::class);
        $notifier->sendSms('+15551234567', 'Welcome to our app!');
    }
    

For Symfony-like workflows (e.g., Messenger integration), see Implementation Patterns.


Implementation Patterns

1. Symfony-Style Messenger Integration (Advanced)

If your Laravel app uses Laravel Echo/Events + Queues, adapt the Symfony Transport pattern:

Step 1: Create a Laravel-Compatible Transport

// app/Notifications/TwilioTransport.php
namespace App\Notifications;

use Symfony\Component\Notifier\Transport\TransportInterface;
use Symfony\Component\Notifier\Message\SmsMessage;
use Twilio\Rest\Client;

class TwilioTransport implements TransportInterface
{
    protected Client $client;

    public function __construct()
    {
        $this->client = new Client(
            config('services.twilio.sid'),
            config('services.twilio.token')
        );
    }

    public function send(SmsMessage $message): void
    {
        $this->client->messages->create(
            $message->getRecipients()[0],
            [
                'from' => config('services.twilio.from'),
                'body' => $message->getSubject(),
            ]
        );
    }

    public function supports(string $transportName): bool
    {
        return 'twilio' === $transportName;
    }
}

Step 2: Register as a Laravel Service

// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->singleton('notifier.transport.twilio', function () {
        return new TwilioTransport();
    });
}

Step 3: Use with Laravel Notifications

use Illuminate\Notifications\Notification;
use Symfony\Component\Notifier\Message\SmsMessage;

class WelcomeSms extends Notification
{
    public function via($notifiable)
    {
        return ['twilio'];
    }

    public function toTwilio($notifiable)
    {
        return (new SmsMessage($notifiable->phone))
            ->subject('Welcome!');
    }
}

2. Webhook Handling (Twilio Events)

Leverage Laravel’s Route::post + middleware for secure webhook validation:

Step 1: Add Webhook Route

// routes/web.php
Route::post('/twilio/webhook', [TwilioWebhookController::class]);

Step 2: Validate and Process

// app/Http/Controllers/TwilioWebhookController.php
use Symfony\Component\Notifier\Bridge\Twilio\Validator\WebhookValidator;

class TwilioWebhookController extends Controller
{
    public function __invoke(Request $request)
    {
        $validator = new WebhookValidator(
            config('services.twilio.token'),
            $request->header('X-Twilio-Signature')
        );

        if (!$validator->isValid($request->getContent())) {
            abort(403, 'Invalid webhook signature');
        }

        // Process event (e.g., message status)
        $event = json_decode($request->getContent(), true);
        // ...
    }
}

3. Dynamic Recipients with Collections

Use Laravel’s Notification facade for batch sends:

use Illuminate\Notifications\Notification;

Notification::send(
    User::where('is_active', true)->get(),
    new WelcomeSms()
);

4. Fallback Channels

Combine Twilio with email fallbacks:

// In Notification class
public function via($notifiable)
{
    return ['twilio', 'mail'];
}

5. Testing Patterns

  • Unit Tests: Mock Twilio\Rest\Client:
    $client = Mockery::mock(Client::class);
    $client->shouldReceive('messages->create')->once();
    $this->app->instance(Client::class, $client);
    
  • Feature Tests: Use Laravel’s HttpTestResponse for webhook validation:
    $response = $this->post('/twilio/webhook', [], [
        'HTTP_X_TWILIO_SIGNATURE' => 'valid_hmac',
    ]);
    $response->assertOk();
    

Gotchas and Tips

Pitfalls

  1. Symfony Abstraction Leakage:

    • The package assumes Symfony’s Message and Transport interfaces. In Laravel, avoid direct dependency injection of Symfony classes. Use adapters (e.g., TwilioTransport above).
  2. Webhook Security:

    • Always validate HMAC signatures (as shown in Implementation Patterns). Twilio’s default security is opt-in—enable it in the Twilio Console.
    • Gotcha: Laravel’s Request object requires explicit header access:
      $signature = $request->header('X-Twilio-Signature'); // Not $request->input()
      
  3. Number Formatting:

    • Twilio expects E.164 format (e.g., +15551234567). Laravel’s Str::of() or libphonenumber can help validate:
      use libphonenumber\PhoneNumberUtil;
      $util = PhoneNumberUtil::getInstance();
      $phone = $util->parse($phoneNumber, 'US');
      $e164 = $util->format($phone, PhoneNumberFormat::E164);
      
  4. Rate Limiting:

    • Twilio has default throttling (e.g., 1 SMS/sec for trial accounts). Use exponential backoff in retries:
      try {
          $notifier->sendSms($to, $body);
      } catch (Exception $e) {
          if ($e->getCode() === 20001) { // "Too Many Requests"
              sleep(2);
              retry();
          }
      }
      
  5. Cost Overruns:

    • Monitor usage via Twilio’s API or Laravel logs. Set up alerts for unexpected spikes:
      // Log all outgoing messages
      $this->client->messages->create(/* ... */)->log();
      

Debugging Tips

  1. Enable Twilio Debugging: Add to .env:

    TWILIO_DEBUG=true
    

    Note: This requires patching the SDK or using a wrapper.

  2. Log Raw Responses: Extend TwilioTransport to log Twilio’s API responses:

    public function send(SmsMessage $message): void
    {
        $response = $this->client->messages->create(/* ... */);
        \Log::debug('Twilio Response:', [
            'sid' => $response->sid,
            'status' => $response->status,
        ]);
    }
    
  3. Test with Sandbox Numbers: Use Twilio’s sandbox numbers (e.g., +15017122661) to avoid costs during development.

  4. Check Twilio’s Status Page: https://www.twilio.com/status for outages.


Extension Points

  1. Custom Message Templates: Create a TwilioMessageBuilder to support:
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.
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views