asanak/laravel-sms-client
Laravel package for sending SMS via Asanak API. Supports simple send, P2P messages, OTP templates, and message status reports. Includes config publishing, .env credentials, optional logging, and auto-registered service provider and facade.
Installation
composer require asanak/laravel-sms-client
php artisan vendor:publish --provider="Asanak\SmsClient\SmsClientServiceProvider" --tag="config"
config/sms-client.php for provider configuration.Configuration
config/sms-client.php to define your SMS provider (e.g., twilio, nexmo, custom).'providers' => [
'twilio' => [
'account_sid' => env('TWILIO_SID'),
'auth_token' => env('TWILIO_TOKEN'),
'from' => env('TWILIO_FROM'),
],
],
First Use Case: Sending an SMS
use Asanak\SmsClient\Facades\SmsClient;
$response = SmsClient::send([
'provider' => 'twilio',
'to' => '+1234567890',
'message' => 'Hello from Laravel!',
]);
// Check response
if ($response->success()) {
// Log or handle success
}
config/sms-client.php: Provider configurations.app/Providers/SmsClientServiceProvider.php: Service binding and boot logic.src/Facades/SmsClient.php: Primary facade for sending SMS.SmsClient::send([
'provider' => 'nexmo', // Switch providers without code changes
'to' => '+1234567890',
'message' => 'Your OTP: 1234',
]);
$recipients = ['+1234567890', '+9876543210'];
foreach ($recipients as $phone) {
SmsClient::send(['provider' => 'twilio', 'to' => $phone, 'message' => 'Batch message']);
}
Messages::create with multiple to fields).sms_templates table) and fetch dynamically:
$template = DB::table('sms_templates')->where('key', 'welcome')->first();
SmsClient::send([
'provider' => 'twilio',
'to' => $user->phone,
'message' => str_replace(['{name}'], [$user->name], $template->body),
]);
Registered, PasswordReset):
// In EventServiceProvider
protected $listen = [
\App\Events\UserRegistered::class => [
\Asanak\SmsClient\Listeners\SendWelcomeSms::class,
],
];
public function handle(UserRegistered $event) {
SmsClient::send([
'provider' => 'twilio',
'to' => $event->user->phone,
'message' => "Welcome, {$event->user->name}!",
]);
}
database, redis):
use Asanak\SmsClient\Jobs\SendSmsJob;
SendSmsJob::dispatch([
'provider' => 'twilio',
'to' => '+1234567890',
'message' => 'Queued message',
]);
namespace Asanak\SmsClient\Jobs;
use Asanak\SmsClient\Facades\SmsClient;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendSmsJob implements ShouldQueue {
use Queueable;
public $data;
public function __construct(array $data) {
$this->data = $data;
}
public function handle() {
SmsClient::send($this->data);
}
}
.env for sensitive provider credentials:
TWILIO_SID=your_sid
TWILIO_TOKEN=your_token
TWILIO_FROM=+1234567890
config/sms-client.php:
'providers' => [
'twilio' => [
'account_sid' => env('TWILIO_SID'),
// ...
],
],
$response = SmsClient::send([...]);
\Log::info('SMS Response', ['data' => $response->getData()]);
failed queue job or a custom observer.$this->mock(SmsClient::class)->shouldReceive('send')->once()->andReturn(new \Asanak\SmsClient\Response(true, []));
phpunit.xml to exclude the database queue connection during tests:
<env name="QUEUE_CONNECTION" value="sync"/>
namespace App\Providers;
use Asanak\SmsClient\Contracts\ProviderInterface;
class CustomProvider implements ProviderInterface {
public function send(array $message) {
// Custom logic (e.g., HTTP request to your SMS gateway)
return new \Asanak\SmsClient\Response(true, ['message_id' => 'custom123']);
}
}
config/sms-client.php:
'providers' => [
'custom' => [
'class' => \App\Providers\CustomProvider::class,
],
],
parts in the message array to split text:
SmsClient::send([
'provider' => 'twilio',
'to' => '+1234567890',
'message' => ['Hello', 'This is a long message split into parts.'],
]);
429 Too Many Requests responses gracefully:
try {
$response = SmsClient::send([...]);
} catch (\Asanak\SmsClient\Exceptions\RateLimitExceeded $e) {
\Log::warning('Rate limit exceeded. Retrying in 30s...');
sleep(30);
retry();
}
failed table is monitored. Failed SMS jobs may indicate:
Validator::make($data, ['to' => 'required|phone:international'])).app(SmsClient::class)). Use the facade for consistency and easier mocking in tests.MessageStatus callbacks), verify the request signature:
use Asanak\SmsClient\Http\Middleware\VerifyTwilioSignature;
// In routes/web.php
Route::post('/sms/webhook', [SmsWebhookController::class, 'handle'])
->middleware(VerifyTwilioSignature::class);
debug to true in config/sms-client.php to log raw API responses:
'debug
How can I help you explore Laravel packages today?