Installation
composer require docdocdoc/nexmo-bundle
Add to config/bundles.php (Symfony 4.4+):
return [
DocDocDoc\NexmoBundle\DocDocDocNexmoBundle::class => ['all' => true],
];
Or register in AppKernel.php (Symfony <4.4):
new DocDocDoc\NexmoBundle\DocDocDocNexmoBundle(),
Configure API Credentials
Add to config/packages/doc_doc_doc_nexmo.yaml:
doc_doc_doc_nexmo:
api_key: "%env(NEXMO_API_KEY)%"
api_secret: "%env(NEXMO_API_SECRET)%"
First SMS Send Inject the service and use it in a controller/service:
use DocDocDoc\NexmoBundle\Message\Simple;
use DocDocDoc\NexmoBundle\NexmoService;
public function sendSms(NexmoService $nexmo)
{
$message = new Simple('MyApp', '+1234567890', 'Hello from Laravel!');
$response = $nexmo->send($message);
return $response->getMessages()[0]->getStatus();
}
Message Creation
Use Simple for basic SMS:
$message = new Simple('SenderID', 'recipient', 'content');
For Unicode/long messages, extend AbstractMessage or use MessageBuilder (if available).
Service Integration
NexmoService and call send().Symfony\Validator\Constraints\PhoneNumber.Response Handling
Check $response->getMessages()[0]->getStatus() for:
0: Success.1: Error (e.g., invalid number).
Log errors for debugging:if ($response->getMessages()[0]->getErrorCode()) {
$this->logger->error('Nexmo error: ' . $response->getMessages()[0]->getErrorText());
}
Batch Sending Loop through a collection and send sequentially (avoid rate limits):
foreach ($users as $user) {
$message = new Simple('SenderID', $user->phone, 'Your OTP: ' . $user->otp);
$nexmo->send($message);
}
// config/services.yaml
services:
App\Listener\SmsSentListener:
tags:
- { name: kernel.event_listener, event: docdocdoc.nexmo.message.sent, method: onSmsSent }
AbstractProvider for custom logic (e.g., logging to DB)..env for credentials:
NEXMO_API_KEY=your_key
NEXMO_API_SECRET=your_secret
API Key/Secret Mismatch
AuthenticationError or empty responses.config/packages/doc_doc_doc_nexmo.yaml and .env values.APP_DEBUG=true) to see raw Nexmo API errors.Phone Number Formatting
InvalidNumber error.+1234567890, not 123-456-7890).# config/validator/constraints.yaml
App\Validator\Constraints\E164Phone:
message: 'Phone number must be in E.164 format.'
Rate Limits
Throttled errors or delayed deliveries.$attempts = 0;
while ($attempts < 3) {
try {
$nexmo->send($message);
break;
} catch (\Exception $e) {
$attempts++;
sleep(2 ** $attempts); // Exponential delay
}
}
Provider Misconfiguration
noop or send_mail not working).provider key in config:
doc_doc_doc_nexmo:
provider: doc_doc_doc_nexmo.send_mail # For testing
mail_to: test@example.com
NexmoService to log responses:
public function send(MessageInterface $message)
{
$response = parent::send($message);
$this->logger->debug('Nexmo response:', ['data' => $response->toArray()]);
return $response;
}
noop Provider
Disable actual sends in config/packages/doc_doc_doc_nexmo.yaml:
doc_doc_doc_nexmo:
provider: doc_doc_doc_nexmo.noop
Custom Message Types
Extend AbstractMessage for structured data (e.g., templates):
class TemplateMessage extends AbstractMessage {
public function __construct(string $templateName, array $variables) {
parent::__construct('SenderID', $variables['to'], $this->renderTemplate($templateName, $variables));
}
}
Async Sending Use Symfony Messenger or queues (e.g., RabbitMQ) to offload SMS sending:
// Dispatch a message
$this->messageBus->dispatch(new SendSmsMessage($message));
// Handler
public function __invoke(SendSmsMessage $message) {
$this->nexmoService->send($message->getMessage());
}
Webhook Integration
Listen for Nexmo inbound SMS via docdocdoc.nexmo.webhook.received event:
public function onWebhookReceived(WebhookEvent $event) {
$this->handleInboundSms($event->getMessage());
}
Fallback Providers Chain providers for redundancy (e.g., Nexmo + Twilio):
doc_doc_doc_nexmo:
providers:
- doc_doc_doc_nexmo.nexmo
- doc_doc_doc_nexmo.twilio # Custom provider
How can I help you explore Laravel packages today?