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

Sms Handler Laravel Package

moffhub/sms-handler

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require moffhub/sms-handler
    php artisan vendor:publish --provider="Moffhub\SmsHandler\SmsHandlerServiceProvider"
    

    Publish config (config/sms-handler.php) and migrations (php artisan migrate).

  2. Configure Providers: Edit config/sms-handler.php to set up your primary/fallback providers (e.g., Twilio, Africa's Talking). Example:

    'providers' => [
        'twilio' => [
            'active' => true,
            'account_sid' => env('TWILIO_SID'),
            'auth_token' => env('TWILIO_TOKEN'),
            'from' => env('TWILIO_FROM'),
        ],
        'africastalking' => [
            'active' => false, // Fallback
            'username' => env('AT_USERNAME'),
            'api_key' => env('AT_API_KEY'),
        ],
    ],
    
  3. First Use Case: Send an SMS via the facade:

    use Moffhub\SmsHandler\Facades\SmsHandler;
    
    SmsHandler::send([
        'to' => '254712345678',
        'message' => 'Hello, this is a test SMS!',
    ]);
    

Key Files to Review

  • Config: config/sms-handler.php (provider settings, defaults, logging).
  • Migrations: database/migrations/[timestamp]_create_sms_logs_table.php (track sent/failed SMS).
  • Events: app/Events/SmsSent.php, app/Events/SmsFailed.php (extend for custom logic).

Implementation Patterns

Core Workflows

1. Sending SMS

  • Basic Send:

    SmsHandler::send([
        'to' => '254712345678',
        'message' => 'Your OTP is {code}.', // Supports templating
        'data' => ['code' => '123456'], // Interpolated into message
    ]);
    
    • Fallback: Automatically retries with the next active provider if the first fails.
    • Queue: Wrap in a job for async processing:
      SmsHandlerJob::dispatch([
          'to' => '254712345678',
          'message' => 'Hello!',
      ]);
      
  • Bulk SMS:

    SmsHandler::bulk([
        ['to' => '254712345678', 'message' => 'Hello 1'],
        ['to' => '254798765432', 'message' => 'Hello 2'],
    ]);
    
    • Uses Laravel’s queue system for efficiency.

2. Templating

Define templates in config/sms-handler.php:

'templates' => [
    'otp' => 'Your OTP is {code}. Valid for 5 minutes.',
],

Use in code:

SmsHandler::send([
    'to' => '254712345678',
    'template' => 'otp',
    'data' => ['code' => '123456'],
]);

3. Notifications Channel

Extend Laravel’s Notification system:

use Moffhub\SmsHandler\Channels\SmsChannel;

class OtpNotification extends Notification {
    public function via($notifiable) {
        return [SmsChannel::class];
    }

    public function toSms($notifiable) {
        return 'Your OTP is ' . $this->code;
    }
}

4. Delivery Reports

Configure webhook endpoints in config/sms-handler.php:

'webhooks' => [
    'twilio' => [
        'url' => route('sms.webhook'),
        'signature' => env('TWILIO_WEBHOOK_SIGNATURE'),
    ],
],

Handle reports in a controller:

public function handleWebhook(Request $request) {
    return SmsHandler::handleWebhook($request);
}

5. Analytics

Track metrics via:

  • Database: Query sms_logs table.
  • Events: Listen to SmsSent, SmsFailed:
    event(new SmsSent($log));
    

Integration Tips

Provider-Specific Quirks

  • Twilio/Nexmo: Use from numbers compliant with their local/global rules.
  • Africa’s Talking: Requires short_code or sender_id for some regions.
  • Advanta/Onfon: May need DND (Do Not Disturb) opt-out handling.

Rate Limiting

Configure per-provider in config/sms-handler.php:

'rate_limits' => [
    'twilio' => 10, // Max 10 SMS/minute
    'africastalking' => 5,
],

Custom Providers

Extend Moffhub\SmsHandler\Contracts\Provider:

class CustomProvider implements Provider {
    public function send(SmsMessage $message) {
        // Implement logic (e.g., HTTP API call)
        return $this->client->send($message->to, $message->message);
    }
}

Register in config/sms-handler.php:

'providers' => [
    'custom' => [
        'active' => true,
        'class' => \App\Providers\CustomProvider::class,
        'config' => [...],
    ],
],

Gotchas and Tips

Pitfalls

  1. Phone Number Validation:

    • The package validates numbers but defaults to E.164 format (e.g., +254712345678). Ensure your provider supports this or pre-format numbers:
      SmsHandler::send(['to' => '+254712345678', ...]);
      
  2. Fallback Logic:

    • Fallbacks are sequential (not parallel). If Provider A fails, Provider B is tried only after A’s timeout (default: 30s). Adjust in config:
      'fallback' => [
          'timeout' => 15, // seconds
          'max_attempts' => 3,
      ],
      
  3. Webhook Security:

    • Always validate webhook signatures (e.g., Twilio’s X-Twilio-Signature). The package provides handleWebhook() but requires manual route setup.
  4. Cost Estimation:

    • The estimateCost() method uses provider-specific rates from config. Override defaults if needed:
      'providers' => [
          'twilio' => [
              'cost_per_sms' => 0.02, // USD
          ],
      ],
      
  5. Logging Overhead:

    • Database logging is enabled by default. Disable for high-volume systems:
      'logging' => [
          'driver' => 'file', // 'database' | 'file' | 'null'
      ],
      

Debugging Tips

  1. Check Logs:

    • Structured logs in storage/logs/laravel.log (credentials scrubbed). Enable debug mode:
      'logging' => [
          'debug' => env('APP_DEBUG', false),
      ],
      
  2. Provider-Specific Errors:

    • Twilio/Nexmo return HTTP errors (e.g., 403 Forbidden). Use SmsFailed event to log raw responses:
      SmsHandler::failed(function (SmsFailed $event) {
          \Log::error('SMS Failed:', ['provider' => $event->provider, 'error' => $event->response]);
      });
      
  3. Queue Stuck Jobs:

    • If jobs hang, check failed_jobs table. Retry with:
      php artisan queue:retry all
      

Extension Points

  1. Custom Validation: Override Moffhub\SmsHandler\Validators\SmsValidator to add rules (e.g., blacklist numbers):

    public function validate(SmsMessage $message) {
        if (in_array($message->to, ['+254712345678'])) {
            throw new \InvalidArgumentException('Number blocked.');
        }
    }
    
  2. Analytics Middleware: Extend Moffhub\SmsHandler\Middleware\Analytics to track custom metrics (e.g., campaign IDs):

    public function handle(SmsMessage $message, Closure $next) {
        $message->setMetadata(['campaign' => 'signup']);
        return $next($message);
    }
    
  3. Provider Retry Logic: Customize retries

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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle