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

Easy Sms Bundle Laravel Package

akanunov/easy-sms-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require akanunov/easy-sms-bundle
    
  2. Enable the bundle in config/bundles.php (Symfony 5.4+):
    return [
        // ...
        Akanunov\EasySmsBundle\AkanunovEasySmsBundle::class => ['all' => true],
    ];
    
  3. Configure a gateway (e.g., Alibaba Cloud SMS) in config/packages/akanunov_easy_sms.yaml:
    akanunov_easy_sms:
        gateways:
            aliyun:
                access_key_id: "%env(AK_ACCESS_KEY_ID)%"
                access_key_secret: "%env(AK_ACCESS_SECRET)%"
                sign_name: "Your Company"
        default:
            gateways: ['aliyun']
    
  4. Send your first SMS in a controller or service:
    use Akanunov\EasySmsBundle\EasySms;
    
    class MyController extends AbstractController
    {
        public function sendSms(EasySms $sms)
        {
            $result = $sms->send('+1234567890', 'Hello from Laravel!');
            return new JsonResponse($result);
        }
    }
    

First Use Case: One-Time Password (OTP)

$sms = $this->easySms->send('+1234567890', 'Your OTP is: 123456');

Use the overtrue/easy-sms template variables for dynamic content:

$sms = $this->easySms->send('+1234567890', 'Your OTP is: {$code}', ['code' => $otpCode]);

Implementation Patterns

Core Workflows

  1. Gateway Selection:

    • Use the default config to set a fallback gateway.
    • Override per-message with the gateway parameter:
      $this->easySms->send('+1234567890', 'Hello', ['gateway' => 'mygateway']);
      
  2. Batch Sending:

    $this->easySms->batchSend([
        ['phone' => '+1234567890', 'message' => 'Hello 1'],
        ['phone' => '+1987654321', 'message' => 'Hello 2'],
    ]);
    
  3. Async Processing (via Symfony Messenger):

    # config/packages/messenger.yaml
    framework:
        messenger:
            transports:
                sms: '%env(MESSENGER_TRANSPORT_DSN)%'
            routing:
                'Akanunov\EasySmsBundle\Message\SendSmsMessage': sms
    

    Then dispatch messages:

    $this->messageBus->dispatch(new SendSmsMessage('+1234567890', 'Hello'));
    

Integration Tips

  • Validation: Use Symfony’s Validator to validate phone numbers before sending:
    use Symfony\Component\Validator\Constraints\PhoneNumber;
    
    $constraint = new PhoneNumber(['strict' => true]);
    $errors = $validator->validate($phoneNumber, $constraint);
    
  • Logging: Enable Monolog for SMS events:
    # config/packages/monolog.yaml
    handlers:
        sms:
            type: stream
            path: "%kernel.logs_dir%/sms.log"
            level: debug
    
  • Testing: Mock the EasySms service in PHPUnit:
    $this->mock(EasySms::class)
         ->shouldReceive('send')
         ->once()
         ->andReturn(['success' => true]);
    

Gotchas and Tips

Pitfalls

  1. Configuration Overrides:

    • The bundle does not merge gateway configs by default. If you define aliyun in both gateways and custom_gateways, the latter takes precedence.
    • Fix: Use array_merge in a custom compiler pass if needed.
  2. Environment Variables:

    • The README assumes %env(KEY)% syntax, but Symfony 6+ uses %env(KEY)% or %kernel.env(KEY)%. Ensure your .env file is loaded:
      php bin/console cache:clear
      
  3. Gateway Timeouts:

    • Default timeouts (e.g., 30s for Alibaba) may cause issues for slow networks. Extend the Gateway class:
      class CustomAliyunGateway extends \Overtrue\EasySms\Gateway\AliyunGateway
      {
          protected $timeout = 60; // Increase timeout
      }
      
  4. Rate Limiting:

    • Some gateways (e.g., Twilio) throttle requests. Implement a circuit breaker (e.g., spatie/flysystem-circuit-breaker) for retries.

Debugging

  • Enable Verbose Logging:
    # config/packages/akanunov_easy_sms.yaml
    akanunov_easy_sms:
        debug: true
    
  • Check Raw Responses: The send() method returns an array with success, message, and data. Inspect data for gateway-specific errors:
    $result = $this->easySms->send('+1234567890', 'Hello');
    if (!$result['success']) {
        \Log::error('SMS Error:', $result['data']);
    }
    

Extension Points

  1. Custom Gateways:

    • Extend \Overtrue\EasySms\Gateway\Gateway and register via custom_gateways:
      custom_gateways:
          twilio:
              gateway_class: App\EasySms\Gateways\TwilioGateway
      
    • Implement GatewayFactoryInterface for config validation (as shown in README).
  2. Middleware:

    • Add pre/post-send logic via a subscriber:
      class SmsSubscriber implements EventSubscriberInterface
      {
          public static function getSubscribedEvents()
          {
              return [
                  EasySmsEvents::PRE_SEND => 'onPreSend',
                  EasySmsEvents::POST_SEND => 'onPostSend',
              ];
          }
      
          public function onPreSend(PreSendEvent $event)
          {
              $event->setMessage("PREFIX: {$event->getMessage()}");
          }
      }
      
  3. Database Logging:

    • Store sent SMS in a table:
      $this->easySms->send('+1234567890', 'Hello', [
          'log' => true, // Auto-saves to DB
      ]);
      
    • Requires a custom Logger service bound to akanunov_easy_sms.logger.

Pro Tips

  • Template Management: Use the template parameter to avoid hardcoding messages:
    $this->easySms->send('+1234567890', null, [
        'template' => 'SMS_10001', // Pre-approved template ID
        'data' => ['code' => $otp],
    ]);
    
  • Fallback Gateways: Configure multiple gateways in default.gateways to retry on failure:
    default:
        gateways: ['aliyun', 'twilio'] # Tries aliyun first, falls back to twilio
    
  • Webhook Validation: For gateways supporting delivery reports (e.g., Twilio), validate webhooks with:
    use Overtrue\EasySms\Webhook\WebhookValidator;
    
    $validator = new WebhookValidator($this->easySms);
    if ($validator->validate($request)) {
        $this->easySms->handleWebhook($request);
    }
    
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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle