Installation:
composer require artox-lab/sms-bundle
Ensure your config/bundles.php includes:
ArtoxLab\Bundle\SmsBundle\ArtoxLabSmsBundle::class => ['all' => true],
Configure a Provider:
Edit config/packages/artox_lab_sms.yaml (auto-generated after installation).
Example for sms_line:
providers:
sms_line:
api_key: "%env(SMS_LINE_API_KEY)%"
sender: "YourSender"
First Use Case: Send an SMS in a controller:
use ArtoxLab\Bundle\SmsBundle\Service\ProviderManager;
use ArtoxLab\Bundle\SmsBundle\Sms\Sms;
public function sendSms(ProviderManager $providerManager)
{
$sms = new Sms('+1234567890', 'Hello from Laravel!');
$provider = $providerManager->getProvider('sms_line');
$provider->send($sms);
}
Resources/docs/providers/ for provider-specific docs (e.g., sms_line.md).config/packages/artox_lab_sms.yaml after installation.log provider for testing (see Gotchas).Provider Selection:
Inject ProviderManager and fetch a provider by name:
$provider = $providerManager->getProvider('lets_ads');
Supports dynamic switching (e.g., fallback providers).
SMS Composition:
Use the Sms class to structure messages:
$sms = new Sms(
recipient: '+1234567890',
message: 'Your OTP is 12345',
options: ['priority' => 'high'] // Provider-specific
);
Batch Sending: Loop through recipients and send via the same provider:
foreach ($recipients as $phone) {
$provider->send(new Sms($phone, 'Batch message'));
}
Async Sending (Manual):
Use Symfony’s Messenger component to queue SMS jobs:
$this->messenger->dispatch(new SendSms($sms, 'sms_line'));
Environment Variables:
Store API keys in .env (e.g., SMS_LINE_API_KEY=your_key).
Reference them in YAML:
providers:
sms_line:
api_key: "%env(SMS_LINE_API_KEY)%"
Validation:
Validate phone numbers before sending (e.g., with libphonenumber):
use libphonenumber\PhoneNumberUtil;
$phoneUtil = PhoneNumberUtil::getInstance();
$phone = $phoneUtil->parse($phoneNumber);
if (!$phoneUtil->isValidNumber($phone)) {
throw new \InvalidArgumentException('Invalid phone number');
}
Logging:
Enable the log provider for debugging:
providers:
log:
enabled: true
log_file: "%kernel.log_dir%/sms.log"
Fallback Providers: Configure multiple providers and handle failures gracefully:
try {
$provider->send($sms);
} catch (\Exception $e) {
$fallbackProvider = $providerManager->getProvider('infobip');
$fallbackProvider->send($sms);
}
Provider-Specific Quirks:
sender to be a registered short code or alphanumeric sender.from instead of sender in the API payload.Character Limits: Most providers enforce SMS length limits (e.g., 160 chars for GSM). Split long messages:
if (strlen($message) > 153) { // Account for 7-bit encoding
$parts = str_split($message, 153);
foreach ($parts as $part) {
$provider->send(new Sms($phone, $part));
}
}
Rate Limits:
Unhandled exceptions may indicate rate limits. Use the log provider to monitor:
providers:
log:
enabled: true
log_level: debug
Symfony Version Compatibility:
Swiftmailer deprecations).Log Provider: Enable to inspect sent messages and errors:
providers:
log:
enabled: true
log_file: "%kernel.log_dir%/sms.log"
Check logs for raw API responses/errors.
Mail Provider: Redirect SMS to email for testing:
providers:
mail:
enabled: true
to: "dev@example.com"
Slack Provider: Alert on failures:
providers:
slack:
enabled: true
webhook_url: "%env(SLACK_WEBHOOK_URL)%"
channel: "#alerts"
Custom Providers:
Extend ArtoxLab\Bundle\SmsBundle\Provider\AbstractProvider to add new services:
class CustomProvider extends AbstractProvider {
public function send(Sms $sms) {
// Implement custom logic
}
}
Register in config/packages/artox_lab_sms.yaml:
providers:
custom:
class: App\Provider\CustomProvider
config: { /* ... */ }
Middleware: Add preprocessing/validation via Symfony’s event system:
// config/services.yaml
services:
App\EventListener\SmsListener:
tags:
- { name: kernel.event_listener, event: sms.send, method: onSend }
Testing:
Mock ProviderManager in PHPUnit:
$providerManager = $this->createMock(ProviderManager::class);
$providerManager->method('getProvider')->willReturn($mockProvider);
$this->container->set(ProviderManager::class, $providerManager);
Environment Variables:
Prefix keys with ARTX_SMS_ for consistency:
providers:
sms_line:
api_key: "%env(ARTX_SMS_SMS_LINE_API_KEY)%"
Default Provider:
Set a default in config/packages/artox_lab_sms.yaml:
default_provider: sms_line
Access via:
$provider = $providerManager->getDefaultProvider();
Provider Chaining: Combine providers for redundancy (e.g., primary + fallback):
providers:
primary:
class: ArtoxLab\Bundle\SmsBundle\Provider\SmsLineProvider
api_key: "%env(ARTX_SMS_PRIMARY_API_KEY)%"
fallback:
class: ArtoxLab\Bundle\SmsBundle\Provider\InfoBipProvider
api_key: "%env(ARTX_SMS_FALLBACK_API_KEY)%"
How can I help you explore Laravel packages today?