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

Fake Sms Notifier Laravel Package

symfony/fake-sms-notifier

Symfony Notifier transport that fakes SMS delivery during development. Redirect SMS messages to email (with configurable to/from and optional custom mailer transport) or log them via a logger DSN, without sending real texts.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package (requires Symfony Notifier):
    composer require symfony/notifier symfony/fake-sms-notifier
    
  2. Add DSN to .env (choose one):
    • Email mode (SMS as email):
      FAKE_SMS_DSN=fakesms+email://default?to=dev@example.com&from=TestSMS
      
    • Logger mode (SMS as logs):
      FAKE_SMS_DSN=fakesms+logger://default
      
  3. Configure Symfony Notifier in config/services.php:
    'notifier' => [
        'dsn' => env('FAKE_SMS_DSN'),
    ],
    
  4. Send a test SMS (via Symfony Notifier):
    use Symfony\Component\Notifier\Notifier;
    use Symfony\Component\Notifier\Message\SmsMessage;
    
    $notifier = new Notifier();
    $notifier->send(new SmsMessage('Hello from fake SMS!', '+1234567890'));
    

First Use Case: Debugging OTP Flows

  • Scenario: Testing a 2FA SMS OTP system in Laravel.
  • Steps:
    1. Set FAKE_SMS_DSN=fakesms+email://default?to=your-email@example.com.
    2. Trigger the OTP flow in your app.
    3. Check your email for the "fake SMS" (e.g., From: TestSMS).
    4. Verify the OTP content matches expectations.

Implementation Patterns

Workflow: Local Development

  1. Environment-Specific DSN: Use Laravel’s .env to toggle between fake and real SMS:
    # .env.local (overrides .env)
    FAKE_SMS_DSN=fakesms+email://default?to=dev@example.com
    
  2. Dynamic DSN Switching: Override the DSN in AppServiceProvider:
    public function boot()
    {
        if (app()->environment('local')) {
            config(['services.notifier.dsn' => 'fakesms+email://default?to=dev@example.com']);
        }
    }
    
  3. Logging Fake SMS: For CI/CD, use logger mode and route logs to a dedicated channel:
    FAKE_SMS_DSN=fakesms+logger://default
    
    Configure Laravel’s logging in config/logging.php:
    'channels' => [
        'fakesms' => [
            'driver' => 'single',
            'path'   => storage_path('logs/fake_sms.log'),
            'level'  => 'debug',
        ],
    ],
    

Integration with Laravel Notifications

  1. Create a FakeSmsChannel: Extend Laravel’s NotificationChannel to use Symfony Notifier:
    // app/Channels/FakeSmsChannel.php
    use Symfony\Component\Notifier\Notifier;
    use Symfony\Component\Notifier\Message\SmsMessage;
    
    class FakeSmsChannel
    {
        public function send($notifiable, Notification $notification)
        {
            $notifier = app(Notifier::class);
            $notifier->send(new SmsMessage(
                $notification->toSms($notifiable),
                $notifiable->phone_number
            ));
        }
    }
    
  2. Use in Notifications:
    // app/Notifications/SmsVerification.php
    public function via($notifiable)
    {
        return [FakeSmsChannel::class];
    }
    

Testing Patterns

  1. Unit Tests: Assert fake SMS was "sent" via email or logs:
    public function test_sms_is_sent_via_fake()
    {
        $this->actingAs($user)
             ->post('/verify', ['phone' => '+1234567890']);
    
        $this->assertEmailSent(function ($mail) {
            return $mail->hasTo('dev@example.com')
                 && $mail->subject === 'Fake SMS: Your code';
        });
    }
    
  2. Feature Tests: Use Laravel’s assertLogged for logger mode:
    public function test_sms_logged_in_production()
    {
        config(['services.notifier.dsn' => 'fakesms+logger://default']);
        $this->post('/verify', ['phone' => '+1234567890']);
    
        $this->assertLogged('Your code: 123456');
    }
    

Gotchas and Tips

Pitfalls

  1. Symfony Notifier Dependency:

    • The package requires symfony/notifier, which may conflict with existing Laravel packages (e.g., symfony/mailer).
    • Fix: Use composer why-not symfony/notifier to check conflicts. Isolate dependencies in a custom package if needed.
  2. Email Sender Address:

    • The from parameter in the DSN must be a valid email (e.g., from=test@example.com).
    • Gotcha: Using a phone number (e.g., from=+1234567890) will fail with:
      [Symfony\Component\Notifier\Exception\LogicException]
      The sender email address cannot be a phone number.
      
    • Fix: Always use a valid email for from.
  3. Logger Mode Visibility:

    • Logs may be hidden in Laravel’s default log files.
    • Fix: Configure a dedicated log channel (see Implementation Patterns).
  4. Laravel Notifications vs. Symfony Notifier:

    • Laravel’s Notification facade uses a different API than Symfony Notifier.
    • Gotcha: Directly passing a Laravel Notification to Symfony Notifier will fail.
    • Fix: Use the FakeSmsChannel wrapper (see Implementation Patterns).
  5. Environment-Specific Behavior:

    • Forgetting to override the DSN in .env.local can lead to real SMS being sent in dev.
    • Fix: Always validate the DSN in AppServiceProvider:
      if (app()->environment('local') && !str_starts_with(config('services.notifier.dsn'), 'fakesms')) {
          throw new \RuntimeException('Fake SMS DSN not configured for local environment!');
      }
      

Debugging Tips

  1. Check DSN Parsing:

    • Use php artisan config:clear after changing .env to reload the DSN.
    • Validate the DSN format with:
      php -r "use Symfony\Component\Notifier\Bridge\FakeSms\FakeSmsTransportFactory; echo (new FakeSmsTransportFactory())->supports('fakesms+email://default?to=test@example.com');"
      
  2. Inspect Fake SMS:

    • For email mode, check the to and from addresses in the DSN.
    • For logger mode, search logs for:
      [NOTICE] Fake SMS sent to "+1234567890": "Your message"
      
  3. Common Errors:

    • InvalidArgumentException: Invalid DSN format. Use fakesms+email:// or fakesms+logger://.
    • RuntimeException: Missing to parameter in email mode. Always include ?to=....

Extension Points

  1. Custom Transport: Extend FakeSmsTransport to add a new output (e.g., Slack):

    // app/Transports/CustomFakeSmsTransport.php
    use Symfony\Component\Notifier\Transport\FakeSmsTransport;
    
    class CustomFakeSmsTransport extends FakeSmsTransport
    {
        public function __construct(string $dsn)
        {
            parent::__construct($dsn);
        }
    
        protected function doSend(SmsMessage $message): void
        {
            // Custom logic (e.g., send to Slack)
            \Log::info('Slack SMS: '.$message->getPhoneNumber().' - '.$message->getContent());
        }
    }
    

    Register it in config/services.php:

    'notifier' => [
        'transports' => [
            'custom_fakesms' => \App\Transports\CustomFakeSmsTransport::class,
        ],
    ],
    
  2. Dynamic Recipients: Override the to parameter per environment:

    // In AppServiceProvider
    $dsn = str_replace(
        '?to=dev@example.com',
        '?to='.config('services.fake_sms.recipient'),
        env('FAKE_SMS_DSN')
    );
    config(['services.notifier.dsn' => $dsn]);
    
  3. Testing Helpers: Create a helper to assert fake SMS:

    // tests/TestHelpers/FakeSms.php
    use Symfony\Component\Notifier\Notifier;
    
    class FakeSms
    {
        public static function assertSent(string $phone, string $content)
        {
            $notifier = app
    
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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony