composer require akanunov/easy-sms-bundle
config/bundles.php (Symfony 5.4+):
return [
// ...
Akanunov\EasySmsBundle\AkanunovEasySmsBundle::class => ['all' => true],
];
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']
use Akanunov\EasySmsBundle\EasySms;
class MyController extends AbstractController
{
public function sendSms(EasySms $sms)
{
$result = $sms->send('+1234567890', 'Hello from Laravel!');
return new JsonResponse($result);
}
}
$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]);
Gateway Selection:
default config to set a fallback gateway.gateway parameter:
$this->easySms->send('+1234567890', 'Hello', ['gateway' => 'mygateway']);
Batch Sending:
$this->easySms->batchSend([
['phone' => '+1234567890', 'message' => 'Hello 1'],
['phone' => '+1987654321', 'message' => 'Hello 2'],
]);
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'));
Validator to validate phone numbers before sending:
use Symfony\Component\Validator\Constraints\PhoneNumber;
$constraint = new PhoneNumber(['strict' => true]);
$errors = $validator->validate($phoneNumber, $constraint);
# config/packages/monolog.yaml
handlers:
sms:
type: stream
path: "%kernel.logs_dir%/sms.log"
level: debug
EasySms service in PHPUnit:
$this->mock(EasySms::class)
->shouldReceive('send')
->once()
->andReturn(['success' => true]);
Configuration Overrides:
aliyun in both gateways and custom_gateways, the latter takes precedence.array_merge in a custom compiler pass if needed.Environment Variables:
%env(KEY)% syntax, but Symfony 6+ uses %env(KEY)% or %kernel.env(KEY)%. Ensure your .env file is loaded:
php bin/console cache:clear
Gateway Timeouts:
Gateway class:
class CustomAliyunGateway extends \Overtrue\EasySms\Gateway\AliyunGateway
{
protected $timeout = 60; // Increase timeout
}
Rate Limiting:
spatie/flysystem-circuit-breaker) for retries.# config/packages/akanunov_easy_sms.yaml
akanunov_easy_sms:
debug: true
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']);
}
Custom Gateways:
\Overtrue\EasySms\Gateway\Gateway and register via custom_gateways:
custom_gateways:
twilio:
gateway_class: App\EasySms\Gateways\TwilioGateway
GatewayFactoryInterface for config validation (as shown in README).Middleware:
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()}");
}
}
Database Logging:
$this->easySms->send('+1234567890', 'Hello', [
'log' => true, // Auto-saves to DB
]);
Logger service bound to akanunov_easy_sms.logger.template parameter to avoid hardcoding messages:
$this->easySms->send('+1234567890', null, [
'template' => 'SMS_10001', // Pre-approved template ID
'data' => ['code' => $otp],
]);
default.gateways to retry on failure:
default:
gateways: ['aliyun', 'twilio'] # Tries aliyun first, falls back to twilio
use Overtrue\EasySms\Webhook\WebhookValidator;
$validator = new WebhookValidator($this->easySms);
if ($validator->validate($request)) {
$this->easySms->handleWebhook($request);
}
How can I help you explore Laravel packages today?