Installation:
composer require creonit/sms-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Creonit\SmsBundle\CreonitSmsBundle::class => ['all' => true],
];
Configuration:
Add credentials to config/packages/creonit_sms.yaml:
creonit_sms:
transport: Creonit\SmsBundle\Transport\SmsTrafficTransport
transport_config:
login: '%env(SMS_LOGIN)%'
password: '%env(SMS_PASSWORD)%'
Define env vars in .env:
SMS_LOGIN=your_login
SMS_PASSWORD=your_password
First Use Case: Send a basic SMS via a controller:
use Creonit\SmsBundle\Message\SmsMessage;
use Creonit\SmsBundle\Mime\Phone;
$message = new SmsMessage();
$message
->setContent('Hello via SMS!')
->setTo(new Phone('1234567890'));
$this->get('messenger.default_bus')->dispatch($message);
Message Creation:
Use SmsMessage to construct messages with:
setContent(): Message body (supports Unicode).setTo()/addTo(): Recipients (accepts Phone objects or raw strings).setFrom() for sender ID (if supported by provider).Dispatching:
MessageBusInterface and dispatch directly.SmsSender class (as shown in README) for reusable logic.Command component for CLI-based sends.Batch Processing: Loop through recipients and dispatch individually:
foreach ($phoneNumbers as $number) {
$message->addTo(new Phone($number));
}
$this->messageBus->dispatch($message);
libphonenumber).RetryMiddleware) for failed sends.SmsMessage to log sends/errors via Symfony’s logger.async transport in Messenger for background processing:
messenger:
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
Dynamic Content: Use Twig to render message content:
$message->setContent($this->twig->render('sms_template.html.twig', ['user' => $user]));
Provider Abstraction: Create a custom transport class to support multiple providers:
class MultiProviderTransport implements TransportInterface {
public function send(SmsMessage $message) {
if ($this->isProviderA()) {
$providerA->send($message);
} else {
$providerB->send($message);
}
}
}
Webhook Responses:
Extend SmsMessage to handle delivery receipts via Messenger’s FailedMessage handling.
Phone Number Formatting:
+1234567890). The bundle does not auto-format.Phone objects first to avoid silent failures.Transport Configuration:
SmsTrafficTransport is hardcoded in the example. If switching providers, ensure the transport class exists and is properly configured.Character Limits:
Synchronous Blocking:
dispatch() is synchronous by default. For long-running sends, use Messenger’s async transport.Failed Messages:
Enable Messenger’s failed_message transport to inspect failures:
messenger:
failure_transport: failed
Check var/message/failed/ for details.
Logging:
Add debug logging to SmsMessage:
use Psr\Log\LoggerInterface;
class SmsMessage {
public function __construct(private LoggerInterface $logger) {}
public function dispatch() {
$this->logger->debug('Sending SMS', ['content' => $this->content, 'to' => $this->to]);
}
}
Provider-Specific Errors:
SmsTrafficException).Custom Transports:
Implement Creonit\SmsBundle\Transport\TransportInterface for new providers:
class TwilioTransport implements TransportInterface {
public function send(SmsMessage $message) {
$client = new Client($this->config);
$client->messages->create($message->to, [
'body' => $message->content,
]);
}
}
Message Events: Dispatch events for pre/post-send logic:
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class SmsMessage {
public function __construct(private EventDispatcherInterface $dispatcher) {}
public function dispatch() {
$this->dispatcher->dispatch(new SmsSendEvent($this));
// Send logic
}
}
Validation:
Override SmsMessage::validate() to add custom rules (e.g., blacklisted numbers):
public function validate(): void {
if (in_array($this->to, $this->blacklistedNumbers)) {
throw new \InvalidArgumentException('Number blacklisted');
}
}
Environment Variables:
The bundle expects login/password in transport_config. Use %env() for security:
transport_config:
login: '%env(SMS_LOGIN)%'
password: '%env(SMS_PASSWORD)%'
Default Transport:
If transport is omitted, the bundle will not send messages. Always specify it.
Messenger Dependency: The bundle relies on Symfony Messenger. Ensure it’s installed and configured:
composer require symfony/messenger
How can I help you explore Laravel packages today?