SMS Framework

Integrates the Texter and SMS channel capabilities of Symfony Notifier with Drupal, providing SMS sending and phone number verification features.

smsframework
1,786 sites
49
drupal.org

Overview

SMS Framework provides comprehensive SMS messaging capabilities for Drupal by integrating Symfony's Notifier component. The module supports sending SMS messages through 60+ SMS vendors including Twilio, Vonage, Bandwidth, Brevo, Clickatell, Nexmo, Plivo, Sinch, and many more.

A key feature is the phone number verification system, which allows site administrators to require users to verify their phone numbers via SMS verification codes. The verification system includes configurable expiration times, unique phone number enforcement, automatic cleanup of expired verifications, and flood protection to prevent brute force attacks.

The module provides a specialized telephone field widget that displays verification status and instructions, guiding users through the verification process. Configuration is done entirely through YAML parameters rather than a UI, giving developers full control over transport settings, verification behavior, and entity field mappings.

When Symfony Messenger is available, SMS messages are dispatched asynchronously via queues for improved performance and reliability.

Features

  • Send SMS messages through 60+ SMS vendors via Symfony Notifier DSN configuration
  • Phone number verification system with configurable verification codes and expiration times
  • Entity-to-phone-number field mapping for automatic verification on entity creation/update
  • Specialized telephone field widget showing verification status, countdown timer, and instructions
  • Unique phone number enforcement to prevent the same number being verified on multiple accounts
  • Flood protection limiting verification attempts (5 per 6 hours by default)
  • Automatic cleanup of expired verification records via cron and queue workers
  • Token support for customizing verification messages ([sms-message:verification-code], [sms:verification-url])
  • Async SMS dispatch via Symfony Messenger when available
  • Event-driven architecture allowing custom code to intercept verification creation
  • Configurable verification route path and success redirect URL
  • Support for Chrome Web OTP autocomplete on verification form

Use Cases

User Phone Number Verification

Add a telephone field to user accounts and configure entity mapping to enable automatic phone verification. When users enter their phone number, they receive an SMS with a verification code. The field widget shows verification status and a countdown timer. Users visit /sms/verify to enter their code and complete verification.

Sending Transactional SMS

Use the NotifierInterface service to send SMS notifications programmatically. Create a Notification with subject text, create a Recipient with phone number, and call $notifier->send($notification, $recipient). The message is routed through configured SMS transports.

Order Confirmation SMS for E-commerce

After order completion, retrieve customer's verified phone number from their user account using SmsPhoneNumberInterface::getPhoneNumbers(). Send order confirmation via NotifierInterface. Verifications ensure messages reach legitimate recipients.

Two-Factor Authentication via SMS

Require users to verify their phone number as part of account security. Enable unique phone number enforcement to prevent same number on multiple accounts. Use the verification system as a building block for 2FA implementations.

Bulk SMS Notifications

Query users with verified phone numbers using entity queries filtered by sms_phone_number_verification entities. Send notifications to multiple recipients by passing multiple recipients to $notifier->send(). Messages queue automatically when Symfony Messenger is installed.

Development and Testing

Install symfony/fake-sms-notifier and configure DSN as 'fakesms+logger://default' to log all SMS messages instead of sending them. Useful for development environments and testing verification flows without incurring SMS costs.

Tips

  • Use fakesms+logger://default DSN during development to see SMS content in Drupal logs without sending real messages
  • Configure notifier.channel_policy to control which importance levels trigger SMS messages
  • The verification message template supports all Drupal tokens in addition to SMS-specific tokens
  • Set sms.verification.unique to false if you need to allow the same phone number on multiple accounts
  • Override logger.channel.sms.phone_number_verification with Psr\Log\NullLogger if you don't want phone numbers logged
  • Install SM (Symfony Messenger) module for automatic async SMS queueing in high-traffic sites
  • Use QueryOptions with VerificationRequirement::Verified when fetching phone numbers to only get verified numbers

Technical Details

Admin Pages 1
Verify phone number /sms/verify

Phone number verification form where users enter the verification code they received via SMS. The form validates the code against stored verification records and marks the phone number as verified upon successful submission.

Permissions 1
Verify phone number

Allows users to access the phone number verification form at /sms/verify to verify their phone numbers.

Hooks 6
hook_entity_insert

Triggers phone verification creation when a new entity with a mapped phone number field is created.

hook_entity_update

Updates phone verifications when entity phone numbers change. Creates new verifications for added numbers, deletes verifications for removed numbers.

hook_entity_delete

Deletes all phone number verifications associated with a deleted entity.

hook_cron

Purges expired phone number verification records during cron execution.

hook_token_info

Defines SMS Framework token types: sms, sms-message, sms-recipient, sms-verification-code.

hook_tokens

Provides token value replacements for SMS Framework tokens used in verification messages.

Troubleshooting 6
SMS messages not being sent

Verify your services.local.yml is included in settings.php. Check that sms.transports parameter has a valid DSN. Ensure you installed the correct Symfony Notifier bridge for your vendor (e.g., composer require symfony/twilio-notifier). Clear cache after any configuration changes.

Verification codes expire too quickly

Increase sms.verification.unverified.lifetime parameter in services.local.yml. Default is 900 seconds (15 minutes). Remember to clear cache after changes.

Phone number field is locked/disabled

This is expected behavior when a verification is pending. Users must complete verification at /sms/verify before the field unlocks. If verification expired, save the entity to trigger a new verification code.

Too many failed verification attempts error

Flood protection limits to 5 attempts per 6 hours. Wait for the flood window to pass, or clear flood table entries manually for the 'sms.verify_phone_number' event.

Phone number verifications not created automatically

Ensure notifier.field_mapping.sms parameter maps your entity type, bundle, and field name correctly. Set verifications: true in the mapping. The field must exist and be a telephone field type.

Verification route returns 404

Check that sms.verification.enabled is true in configuration. The route is conditionally removed when verification is disabled. Clear cache to rebuild routes.

Security Notes 6
  • Flood protection limits verification attempts to prevent brute force attacks (5 attempts per 6 hours)
  • Verification codes are stored in the database and should be treated as sensitive data
  • Phone numbers are logged by default - override the logger service to prevent logging if needed
  • Enable unique phone number enforcement to prevent account takeover via shared phone numbers
  • SMS transport DSNs contain API credentials - ensure services.local.yml is not committed to version control
  • The verification form uses Chrome Web OTP autocomplete attribute for secure code entry