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

Sinch Notifier Laravel Package

symfony/sinch-notifier

Symfony Notifier integration for Sinch. Send SMS via Sinch using a simple DSN like sinch://SERVICE_PLAN_ID:AUTH_TOKEN@default?from=FROM, where FROM is your sender. Configure with your service plan ID and auth token.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup for Laravel Integration

  1. Install the Package Add the package via Composer (though it’s Symfony-focused, we’ll adapt it):

    composer require symfony/sinch-notifier
    
  2. Configure Sinch DSN Add to .env:

    SINCH_DSN=sinch://SERVICE_PLAN_ID:AUTH_TOKEN@default?from=YOUR_SENDER_ID
    

    Note: Laravel’s .env format differs from Symfony’s parameters.yaml.

  3. Create a Laravel Service Provider Register the Symfony Sinch client as a Laravel binding:

    // app/Providers/SinchServiceProvider.php
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    use Symfony\Component\Notifier\Notifier;
    use Symfony\Component\Notifier\Transport\SinchTransportFactory;
    
    class SinchServiceProvider extends ServiceProvider
    {
        public function register()
        {
            $this->app->singleton('sinch.notifier', function ($app) {
                $dsn = config('services.sinch.dsn');
                $factory = new SinchTransportFactory();
                $transport = $factory->create($dsn);
                return new Notifier([$transport]);
            });
        }
    }
    
  4. First Use Case: Send an SMS Inject the notifier into a controller or command:

    use Symfony\Component\Notifier\Message\SmsMessage;
    use Symfony\Component\Notifier\Notification\Notification;
    
    public function sendWelcomeSms()
    {
        $notifier = app('sinch.notifier');
        $message = new SmsMessage('Welcome to our app!', '1234567890');
        $notification = new Notification('Welcome', $message);
    
        $notifier->send($notification);
    }
    

Implementation Patterns

Core Workflows

  1. Sending Notifications

    • SMS: Use SmsMessage for text messages.
      $message = new SmsMessage('Your OTP is 1234', 'user_phone_number');
      $notifier->send(new Notification('OTP', $message));
      
    • Voice: Use VoiceMessage for call notifications (limited to Sinch’s voice API).
      $message = new VoiceMessage('Hello, this is a test call', 'user_phone_number');
      $notifier->send(new Notification('Voice Alert', $message));
      
    • Chat: Use ChatMessage for platforms like WhatsApp (if supported by Sinch).
      $message = new ChatMessage('Hi!', 'user_chat_id');
      
  2. Handling Responses

    • Attach a callback to track delivery status:
      $message = new SmsMessage('Hello', '1234567890');
      $message->withCallback(function ($response) {
          if ($response->failed()) {
              Log::error('SMS failed', ['error' => $response->getReason()]);
          }
      });
      
  3. Batch Processing

    • Use Laravel’s queues to avoid timeouts for bulk sends:
      foreach ($userPhones as $phone) {
          SendSmsJob::dispatch($phone, 'Your message')->onQueue('sinch');
      }
      
  4. Webhook Integration

    • Register a Laravel route to handle Sinch webhooks (e.g., delivery receipts):
      Route::post('/sinch/webhook', [SinchWebhookController::class, 'handle']);
      
    • Parse Sinch’s payload and update your database:
      public function handle(Request $request)
      {
          $payload = $request->json()->all();
          if ($payload['event'] === 'message.sent') {
              Message::where('sinch_id', $payload['messageId'])->update(['status' => 'delivered']);
          }
      }
      

Integration Tips

  • Laravel Configuration Define Sinch settings in config/services.php:

    'sinch' => [
        'dsn' => env('SINCH_DSN'),
        'timeout' => env('SINCH_TIMEOUT', 30),
    ],
    
  • Dependency Injection Bind the notifier to Laravel’s container for easier testing:

    $this->app->bind(SinchNotifier::class, function ($app) {
        return app('sinch.notifier');
    });
    
  • Testing Mock the Sinch transport in tests:

    $transport = $this->createMock(SinchTransport::class);
    $transport->method('send')->willReturn(new SentMessage());
    $notifier = new Notifier([$transport]);
    
  • Fallback Mechanisms Implement a retry logic for failed sends using Laravel’s retry helper:

    try {
        $notifier->send($notification);
    } catch (TransportException $e) {
        retry(3, function () use ($notifier, $notification) {
            $notifier->send($notification);
        }, function () {
            Log::error('Max retries reached for notification');
        });
    }
    

Gotchas and Tips

Pitfalls

  1. Symfony-Laravel DI Conflicts

    • Issue: Symfony’s Notifier expects a specific DI structure. Laravel’s container may throw errors if not properly bridged.
    • Fix: Use a facade or adapter to wrap the Symfony notifier:
      class SinchFacade {
          public static function send(SmsMessage $message) {
              return app('sinch.notifier')->send(new Notification('SMS', $message));
          }
      }
      
  2. Sinch API Rate Limits

    • Issue: Sinch may throttle requests if sent too quickly. Laravel’s queue system helps, but ensure batch sizes are reasonable.
    • Fix: Use sleep() or Laravel’s afterCommit() to space out sends:
      foreach ($users as $user) {
          SendSmsJob::dispatch($user)->delay(now()->addSeconds(2));
      }
      
  3. Webhook Verification

    • Issue: Sinch webhooks require validation to prevent spoofing. Laravel’s route middleware can handle this:
      Route::post('/sinch/webhook', function () {
          $signature = $request->header('X-Sinch-Signature');
          if (!SinchWebhookValidator::validate($signature, $request->getContent())) {
              abort(403);
          }
          // Process webhook
      });
      
  4. Phone Number Formatting

    • Issue: Sinch expects E.164 format (e.g., +1234567890). Laravel may receive raw inputs like 1234567890.
    • Fix: Normalize numbers before sending:
      $phone = PhoneNumber::parse($rawPhone)->formatE164();
      
  5. Logging and Debugging

    • Issue: Sinch errors may not be descriptive. Enable Symfony’s debug mode or add custom logging:
      $message->withCallback(function ($response) {
          Log::debug('Sinch response', [
              'status' => $response->getStatus(),
              'reason' => $response->getReason(),
          ]);
      });
      

Tips

  1. Environment-Specific Configs Use Laravel’s .env for different Sinch credentials per environment:

    SINCH_DSN_STAGING=sinch://STAGING_ID:TOKEN@default?from=STAGING_SENDER
    SINCH_DSN_PROD=sinch://PROD_ID:TOKEN@default?from=PROD_SENDER
    
  2. Extending the Notifier Create custom message types by extending Symfony’s Message classes:

    class CustomSmsMessage extends SmsMessage {
        public function __construct(string $content, string $recipient, array $options = []) {
            parent::__construct($content, $recipient, $options);
            $this->addOption('custom_key', 'custom_value');
        }
    }
    
  3. Monitoring Costs Track Sinch usage in Laravel’s logs or a database:

    $message->withCallback(function ($response) use ($userId) {
        Log::info('Sinch usage', [
            'user_id' => $userId,
            'cost' => $this->calculateSinchCost($response),
        ]);
    });
    
  4. Fallback to Alternative Providers Implement a strategy pattern to switch providers dynamically:

    class NotificationService {
        public function __construct(private Notifier $sinchNotifier, private Notifier $fallbackNotifier) {}
    
        public function send(SmsMessage $message) {
            try {
                $this->sinchNotifier->send(new Notification('SMS', $message));
            } catch (TransportException $e) {
                $this->fallbackNotifier->send(new Notification('SMS', $message));
            }
        }
    }
    
  5. Testing Webhooks Locally

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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
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