Installation
composer require avtonom/sms-sender
(Note: The package is listed under avtonom/sms-sender but the README references Carpe-Hora/SmsSender. Verify the correct namespace in your project.)
Basic Configuration
Create a service provider (e.g., SmsServiceProvider) and register the adapter/provider:
use Avtonom\SmsSender\Provider\TwilioProvider;
use Avtonom\SmsSender\HttpAdapter\CurlHttpAdapter;
public function register()
{
$this->app->singleton('sms.sender', function ($app) {
$adapter = new CurlHttpAdapter();
$provider = new TwilioProvider($adapter, [
'account_sid' => 'YOUR_TWILIO_SID',
'auth_token' => 'YOUR_TWILIO_TOKEN',
'from' => '+1234567890'
]);
return $provider;
});
}
First Use Case: Sending an SMS
Inject the sms.sender binding into a controller or service:
public function sendWelcomeSms(TwilioProvider $smsSender)
{
$result = $smsSender->send('+15551234567', 'Welcome to our app!');
return $result->isSuccess() ? 'SMS sent!' : 'Failed: ' . $result->getMessage();
}
src/Avtonom/SmsSender/Provider/ for supported gateways (e.g., TwilioProvider, NexmoProvider).src/Avtonom/SmsSender/HttpAdapter/ for HTTP clients (CurlHttpAdapter, BuzzHttpAdapter).src/Avtonom/SmsSender/Result/ for parsing gateway responses (e.g., ResultInterface).Provider Initialization Bind a provider to your container with gateway-specific credentials:
$provider = new NexmoProvider($adapter, [
'api_key' => env('NEXMO_API_KEY'),
'api_secret' => env('NEXMO_API_SECRET'),
'from' => 'YourBrand'
]);
Sending SMS
Use the provider’s send() method:
$result = $smsSender->send('+919876543210', 'Your OTP is 123456');
to: Recipient phone number (string, e.g., '+15551234567').message: SMS body (string, max length depends on gateway).options array (e.g., ['schedule' => '2023-12-31T12:00:00'] for Twilio).Handling Responses
Check $result (implements ResultInterface):
if ($result->isSuccess()) {
$messageId = $result->getMessageId(); // Gateway-specific ID
} else {
$error = $result->getMessage(); // e.g., "Invalid credentials"
}
Laravel Facade: Create a facade for cleaner syntax:
// app/SmsSender.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class SmsSender extends Facade { protected static function getFacadeAccessor() { return 'sms.sender'; } }
Usage:
SmsSender::send('+15551234567', 'Hello!');
Queueable Jobs: Wrap SMS sending in a job for async processing:
use Avtonom\SmsSender\Provider\TwilioProvider;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendSmsJob implements ShouldQueue
{
use Queueable;
public function __construct(
private TwilioProvider $smsSender,
private string $to,
private string $message
) {}
public function handle() { $this->smsSender->send($this->to, $this->message); }
}
Logging Failures: Extend Result to log errors automatically:
$result = $smsSender->send($to, $message);
if (!$result->isSuccess()) {
\Log::error("SMS failed to {$to}: {$result->getMessage()}");
}
Multi-Gateway Fallback: Chain providers for redundancy:
$primary = new TwilioProvider($adapter, [...]);
$fallback = new NexmoProvider($adapter, [...]);
$result = $primary->send($to, $message);
if (!$result->isSuccess()) {
$result = $fallback->send($to, $message);
}
Mock the provider in tests:
$mockProvider = Mockery::mock(TwilioProvider::class);
$mockProvider->shouldReceive('send')
->once()
->with('+15551234567', 'Test')
->andReturn(new Result(true, 'Success', '12345'));
$this->app->instance('sms.sender', $mockProvider);
Adapter Incompatibility
BuzzHttpAdapter requires PHP 5.3+, while CurlHttpAdapter works on older versions.CurlHttpAdapter for broader compatibility.Phone Number Formatting
+15551234567). Malformed numbers cause failures.if (!preg_match('/^\+[1-9]\d{1,14}$/', $phone)) {
throw new \InvalidArgumentException('Invalid phone number format');
}
Rate Limits
$attempts = 0;
while ($attempts < 3) {
$result = $smsSender->send($to, $message);
if ($result->isSuccess()) break;
sleep(2 ** $attempts); // Exponential delay
$attempts++;
}
Provider-Specific Quirks
from number to be verified.api_key/api_secret instead of account_sid/auth_token.SSL/TLS Warnings
CurlHttpAdapter to disable verification (temporarily for testing):
$adapter = new CurlHttpAdapter();
$adapter->setOpt(CURLOPT_SSL_VERIFYPEER, false); // Not recommended for production!
Enable Adapter Logging
Extend CurlHttpAdapter to log requests/responses:
class DebugCurlHttpAdapter extends CurlHttpAdapter
{
public function send($method, $url, $body = null)
{
\Log::debug("SMS Request: {$method} {$url}", ['body' => $body]);
$response = parent::send($method, $url, $body);
\Log::debug("SMS Response: " . $response->getBody(), ['status' => $response->getStatusCode()]);
return $response;
}
}
Gateway-Specific Errors Parse raw responses for debugging:
$result = $smsSender->send($to, $message);
if (!$result->isSuccess()) {
\Log::error("Raw response: " . $result->getRawResponse());
}
Avtonom\SmsSender\Provider\ProviderInterface for unsupported gateways:
class CustomProvider implements ProviderInterface
{
public function send($to, $message, array $options = [])
{
// Your logic here
return new Result(true, 'Custom success', '1
How can I help you explore Laravel packages today?