LaravelPackages.net
Acme Inc.
Toggle sidebar
gr8shivam/laravel-sms-api

A modern, flexible Laravel package for integrating any SMS gateway with REST API support

40.199
101
4.1.0
About gr8shivam/laravel-sms-api

gr8shivam/laravel-sms-api is a Laravel package for a modern, flexible laravel package for integrating any sms gateway with rest api support. It currently has 101 GitHub stars and 40.199 downloads on Packagist (latest version 4.1.0). Install it with composer require gr8shivam/laravel-sms-api. Discover more Laravel packages by gr8shivam or browse all Laravel packages to compare alternatives.

Last updated

Packagist Packagist License Laravel PHP

Laravel SMS API

A modern, flexible Laravel package for integrating any SMS gateway that provides a REST API. Perfect for Laravel 10+ applications with full support for notifications, multiple gateways, and modern authentication methods.

โญ Star this repo to show support!


๐Ÿ“‹ Table of Contents


โœจ Features

  • โœ… Universal Compatibility - Works with any REST API SMS provider
  • โœ… Multiple Gateways - Configure and switch between multiple SMS providers
  • โœ… Laravel Notifications - Full integration with Laravel's notification system
  • โœ… Modern Auth - Support for Bearer tokens, API keys, Basic Auth, and custom headers
  • โœ… Bulk SMS - Send to multiple recipients in a single call
  • โœ… JSON & Form Data - Support for both JSON payloads and form-encoded requests
  • โœ… Request Wrapping - Handle complex API structures with wrapper support
  • โœ… Type Safe - Built with PHP 8.1+ strict types
  • โœ… Dependency Injection - Modern Laravel service container integration
  • โœ… Comprehensive Logging - Built-in request/response logging
  • โœ… Easy Testing - Mock-friendly architecture

๐Ÿ“Œ Requirements

  • PHP 8.1 or higher
  • Laravel 10.x, 11.x, or 12.x
  • Guzzle HTTP Client 7.8+

๐Ÿ“ฆ Installation

1. Install via Composer

composer require gr8shivam/laravel-sms-api

2. Publish Configuration

php artisan vendor:publish --provider="Gr8Shivam\SmsApi\SmsApiServiceProvider"

This creates config/sms-api.php in your application.

3. Configure Your Gateway

Edit config/sms-api.php and add your SMS provider credentials (see Configuration below).


๐Ÿš€ Quick Start

Send Your First SMS

use Gr8Shivam\SmsApi\SmsApiFacade as SmsApi;

// Simple usage
SmsApi::sendMessage("9876543210", "Hello from Laravel!");

// Or using helper
smsapi("9876543210", "Hello from Laravel!");

Send to Multiple Recipients

SmsApi::sendMessage(["9876543210", "9876543211"], "Hello everyone!");

Get Response

$response = SmsApi::sendMessage("9876543210", "Hello!")
    ->response();

$statusCode = SmsApi::sendMessage("9876543210", "Hello!")
    ->getResponseCode();

$isSuccess = SmsApi::sendMessage("9876543210", "Hello!")
    ->isSuccessful(); // Returns true for 2xx status codes

โš™๏ธ Configuration

Open config/sms-api.php after publishing.

Global Settings

return [
    // Default country code (added to numbers automatically)
    'country_code' => env('SMS_API_COUNTRY_CODE', '91'),

    // Default gateway to use
    'default' => env('SMS_API_DEFAULT_GATEWAY', 'your_gateway'),

    // HTTP client timeouts
    'timeout' => env('SMS_API_TIMEOUT', 30),
    'connect_timeout' => env('SMS_API_CONNECT_TIMEOUT', 10),

    // Optional message validation
    'validation' => [
        'enabled' => env('SMS_API_VALIDATION_ENABLED', false),
        'max_length' => env('SMS_API_MAX_LENGTH', 1000),
    ],
];

Basic Gateway Configuration

For simple GET/POST requests:

'your_gateway' => [
    'method' => 'POST',  // GET, POST, PUT, PATCH, DELETE
    'url' => 'https://api.smsgateway.com/send',
    'params' => [
        'send_to_param_name' => 'mobile',    // Your provider's "to" param name
        'msg_param_name' => 'message',       // Your provider's "message" param name
        'others' => [
            'api_key' => env('SMS_GATEWAY_KEY'),
            'sender_id' => env('SMS_SENDER_ID'),
        ],
    ],
    'headers' => [
        'Accept' => 'application/json',
    ],
    'add_code' => true,  // Automatically add country code
],

Advanced Gateway Configuration

For JSON requests with complex structures:

'advanced_gateway' => [
    'method' => 'POST',
    'url' => 'https://api.provider.com/v2/send',
    'params' => [
        'send_to_param_name' => 'recipient',
        'msg_param_name' => 'text',
        'others' => [
            'priority' => 'high',
            'ttl' => 3600,
        ],
    ],
    'headers' => [
        'Authorization' => 'Bearer ' . env('SMS_API_TOKEN'),
        'Content-Type' => 'application/json',
    ],
    'json' => true,              // Send as JSON payload
    'jsonToArray' => true,       // Send single number as array: ["9876543210"]
    'wrapper' => 'data',         // Wrap payload in {"data": {...}}
    'wrapperParams' => [
        'campaign_id' => 'welcome_sms',
    ],
    'add_code' => true,
],

Result payload example:

{
  "data": [
    {
      "recipient": ["919876543210"],
      "text": "Your message",
      "campaign_id": "welcome_sms"
    }
  ],
  "priority": "high",
  "ttl": 3600
}

Authentication Methods

1. Bearer Token (Most Modern APIs)

'gateway' => [
    'headers' => [
        'Authorization' => 'Bearer ' . env('SMS_API_TOKEN'),
    ],
],

In .env:

SMS_API_TOKEN=your_bearer_token_here

2. API Key in Header

'gateway' => [
    'headers' => [
        'X-API-Key' => env('SMS_API_KEY'),
    ],
],

3. Basic Authentication

'gateway' => [
    'headers' => [
        'Authorization' => 'Basic ' . base64_encode(env('SMS_USERNAME') . ':' . env('SMS_PASSWORD')),
    ],
],

4. API Key in Parameters

'gateway' => [
    'params' => [
        'others' => [
            'api_key' => env('SMS_API_KEY'),
        ],
    ],
],

Special Parameters

json (boolean)

Send parameters as JSON payload instead of query string or form data.

'json' => true,

jsonToArray (boolean)

When json is true, controls whether a single mobile number is sent as:

  • true: ["9876543210"] (array)
  • false: "9876543210" (string)
'jsonToArray' => false,

wrapper (string)

Wraps the JSON request in a named object. Required by some providers.

'wrapper' => 'sms',  // Creates: {"sms": [{...}]}

wrapperParams (array)

Adds parameters inside the wrapper (separate from regular params).

'wrapperParams' => [
    'campaign' => 'summer_sale',
    'priority' => 1,
],

add_code (boolean)

Automatically prepend country code to phone numbers.

'add_code' => true,  // 9876543210 becomes 919876543210

๐Ÿ“ฑ Usage

Using Helper Function

The smsapi() helper provides the most convenient way to send SMS.

Basic Usage

// Quick send
smsapi("9876543210", "Welcome to our platform!");

// Or
smsapi()->sendMessage("9876543210", "Welcome!");

With Extra Parameters

smsapi("9876543210", "Your OTP is 1234", [
    'template_id' => 'OTP_TEMPLATE',
    'priority' => 'high'
]);

With Custom Headers

smsapi("9876543210", "Hello", [], [
    'X-Custom-Header' => 'value',
    'X-Request-ID' => uniqid()
]);

Using Different Gateway

smsapi()->gateway('backup_gateway')
    ->sendMessage("9876543210", "Message via backup gateway");

Using Different Country Code

smsapi()->countryCode('1')  // USA
    ->sendMessage("5551234567", "Hello from USA!");

Bulk SMS

$recipients = ["9876543210", "9876543211", "9876543212"];
smsapi($recipients, "Bulk message to all!");

With Wrapper Parameters

smsapi()->addWrapperParams([
        'campaign' => 'newsletter',
        'tracking_id' => '12345'
    ])
    ->sendMessage("9876543210", "Newsletter message");

Method Chaining

smsapi()
    ->gateway('primary_gateway')
    ->countryCode('91')
    ->addWrapperParams(['campaign' => 'promo'])
    ->sendMessage("9876543210", "Promotional offer!", [
        'template_id' => 'PROMO_123'
    ]);

Using Facade

The facade provides the same functionality with explicit imports.

use Gr8Shivam\SmsApi\SmsApiFacade as SmsApi;

// Basic usage
SmsApi::sendMessage("9876543210", "Hello!");

// With gateway selection
SmsApi::gateway('gateway_name')
    ->sendMessage("9876543210", "Hello!");

// With country code
SmsApi::countryCode('44')  // UK
    ->sendMessage("7911123456", "Hello from UK!");

// Bulk SMS
SmsApi::sendMessage(
    ["9876543210", "9876543211"],
    "Bulk message"
);

// Get response
$response = SmsApi::sendMessage("9876543210", "Test")
    ->response();

// Get status code
$code = SmsApi::sendMessage("9876543210", "Test")
    ->getResponseCode();

// Check success
$success = SmsApi::sendMessage("9876543210", "Test")
    ->isSuccessful();

Using Notifications

Laravel SMS API integrates seamlessly with Laravel's notification system.

Step 1: Add Route to Your Model

In your User model (or any Notifiable model):

use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Route notifications for SMS API channel
     */
    public function routeNotificationForSmsApi()
    {
        return $this->phone;  // Return the phone number column
    }
}

Step 2: Create Notification

php artisan make:notification WelcomeNotification
namespace App\Notifications;

use Illuminate\Notifications\Notification;
use Gr8Shivam\SmsApi\Notifications\SmsApiChannel;
use Gr8Shivam\SmsApi\Notifications\SmsApiMessage;

class WelcomeNotification extends Notification
{
    public function via($notifiable)
    {
        return [SmsApiChannel::class];
    }

    public function toSmsApi($notifiable)
    {
        return (new SmsApiMessage)
            ->content("Welcome {$notifiable->name}!");
    }
}

Step 3: Send Notification

$user = User::find(1);
$user->notify(new WelcomeNotification());

Advanced Notification Examples

With Parameters:

public function toSmsApi($notifiable)
{
    return (new SmsApiMessage)
        ->content("Your OTP is: {$this->otp}")
        ->params([
            'template_id' => 'OTP_VERIFY',
            'priority' => 'high'
        ]);
}

With Headers:

public function toSmsApi($notifiable)
{
    return (new SmsApiMessage)
        ->content($this->message)
        ->params(['campaign' => 'marketing'])
        ->headers(['X-Campaign-ID' => '12345']);
}

Unicode Message:

public function toSmsApi($notifiable)
{
    return (new SmsApiMessage)
        ->content("เคจเคฎเคธเฅเคคเฅ‡! Welcome")
        ->unicode();
}

Using Static Constructor:

public function toSmsApi($notifiable)
{
    return SmsApiMessage::create("Hello {$notifiable->name}!")
        ->addParam('template_id', 'WELCOME_001')
        ->addHeader('X-Priority', 'high');
}

Return String (Shorthand):

public function toSmsApi($notifiable)
{
    return "Welcome to our platform!";  // Automatically converted to SmsApiMessage
}

๐Ÿ”ฅ Advanced Features

1. Safe Sending Helper

Use send_sms() for operations where you want to catch exceptions:

if (send_sms("9876543210", "Hello!")) {
    echo "SMS sent successfully!";
} else {
    echo "SMS failed. Error logged.";
}

2. Response Handling

$sms = smsapi()->sendMessage("9876543210", "Hello!");

// Get raw response
$response = $sms->response();

// Get status code
$code = $sms->getResponseCode();

// Check if successful
if ($sms->isSuccessful()) {
    // 2xx status code
}

3. Message Validation

$message = new SmsApiMessage("Your message here");

// Get message length
$length = $message->length();

// Check if empty
if ($message->isEmpty()) {
    // Handle empty message
}

// Estimate SMS segments (for cost calculation)
$segments = $message->estimateSegments();  // Returns 1, 2, 3...

// Get preview
$preview = $message->preview(50);  // First 50 characters

Enable validation in config:

'validation' => [
    'enabled' => true,
    'max_length' => 1000,
],

Then validate:

try {
    $message->validate();
} catch (\InvalidArgumentException $e) {
    // Handle validation error
}

4. Dynamic Gateway Selection

$gateway = $user->isPremium() ? 'premium_gateway' : 'basic_gateway';

smsapi()->gateway($gateway)
    ->sendMessage($user->phone, "Relevant message");

5. Environment-based Configuration

// .env
SMS_API_DEFAULT_GATEWAY=twilio
SMS_API_COUNTRY_CODE=1
SMS_API_TIMEOUT=60
TWILIO_ACCOUNT_SID=your_sid
TWILIO_AUTH_TOKEN=your_token
TWILIO_FROM_NUMBER=+15551234567

6. Multiple Recipients Handling

// Array of numbers
$recipients = User::where('notify_sms', true)
    ->pluck('phone')
    ->toArray();

smsapi($recipients, "Important announcement!");

7. Logging

All requests and responses are automatically logged using Laravel's logging system:

// Check logs/laravel.log for:
// [INFO] SMS Gateway Response Code: 200
// [INFO] SMS Gateway Response Body: {...}
// [ERROR] SMS Gateway Response Code: 400
// [ERROR] SMS Gateway Response Body: {...}

๐ŸŒ Real Provider Examples

Twilio

'twilio' => [
    'method' => 'POST',
    'url' => 'https://api.twilio.com/2010-04-01/Accounts/' . env('TWILIO_ACCOUNT_SID') . '/Messages.json',
    'params' => [
        'send_to_param_name' => 'To',
        'msg_param_name' => 'Body',
        'others' => [
            'From' => env('TWILIO_FROM_NUMBER'),
        ],
    ],
    'headers' => [
        'Authorization' => 'Basic ' . base64_encode(env('TWILIO_ACCOUNT_SID') . ':' . env('TWILIO_AUTH_TOKEN')),
    ],
    'add_code' => true,
],

Usage:

smsapi()->gateway('twilio')->sendMessage("5551234567", "Hello from Twilio!");

MSG91

'msg91' => [
    'method' => 'POST',
    'url' => 'https://control.msg91.com/api/v2/sendsms',
    'params' => [
        'send_to_param_name' => 'to',
        'msg_param_name' => 'message',
        'others' => [
            'authkey' => env('MSG91_AUTH_KEY'),
            'sender' => env('MSG91_SENDER_ID'),
            'route' => '4',
            'country' => '91',
        ],
    ],
    'json' => true,
    'wrapper' => 'sms',
    'add_code' => false,
],

Usage:

smsapi()->gateway('msg91')->sendMessage("9876543210", "Hello from MSG91!");

AWS SNS (via REST API)

'aws_sns' => [
    'method' => 'POST',
    'url' => 'https://sns.us-east-1.amazonaws.com/',
    'params' => [
        'send_to_param_name' => 'PhoneNumber',
        'msg_param_name' => 'Message',
        'others' => [
            'Action' => 'Publish',
        ],
    ],
    'headers' => [
        'Authorization' => 'AWS4-HMAC-SHA256 ...',  // Use AWS SDK for proper signing
    ],
    'add_code' => true,
],

Nexmo/Vonage

'nexmo' => [
    'method' => 'POST',
    'url' => 'https://rest.nexmo.com/sms/json',
    'params' => [
        'send_to_param_name' => 'to',
        'msg_param_name' => 'text',
        'others' => [
            'api_key' => env('NEXMO_API_KEY'),
            'api_secret' => env('NEXMO_API_SECRET'),
            'from' => env('NEXMO_FROM'),
        ],
    ],
    'json' => true,
    'add_code' => true,
],

Generic Bearer Token API

'generic_api' => [
    'method' => 'POST',
    'url' => 'https://api.smsprovider.com/v1/send',
    'params' => [
        'send_to_param_name' => 'to',
        'msg_param_name' => 'message',
        'others' => [
            'sender' => 'YourApp',
        ],
    ],
    'headers' => [
        'Authorization' => 'Bearer ' . env('SMS_BEARER_TOKEN'),
        'Content-Type' => 'application/json',
        'Accept' => 'application/json',
    ],
    'json' => true,
    'add_code' => true,
],

๐Ÿงช Testing

Running Tests

composer test

Writing Tests

use Gr8Shivam\SmsApi\Tests\AbstractTestCase;
use Gr8Shivam\SmsApi\SmsApiFacade as SmsApi;

class MyFeatureTest extends AbstractTestCase
{
    /** @test */
    public function it_sends_sms()
    {
        $this->mockSmsGateway(200, 'Success');

        $response = SmsApi::sendMessage("9876543210", "Test");

        $this->assertEquals(200, $response->getResponseCode());
        $this->assertTrue($response->isSuccessful());
    }
}

๐Ÿ“š Changelog

See CHANGELOG.md for version history and breaking changes.

Latest Version: 4.0.0

  • PHP 8.1+ and Laravel 10+ support
  • Modern type hints and strict types
  • Bearer token and modern auth support
  • Optional message validation
  • Enhanced notification system
  • Comprehensive test suite

๐Ÿ› Troubleshooting

SMS Not Sending

  1. Check logs: storage/logs/laravel.log
  2. Verify config: Ensure gateway credentials are correct
  3. Test manually:
    php artisan tinker
    >>> smsapi()->sendMessage("YOUR_NUMBER", "Test")->response();
    

Invalid Response

$sms = smsapi()->sendMessage("9876543210", "Test");
dd([
    'code' => $sms->getResponseCode(),
    'response' => $sms->response(),
    'success' => $sms->isSuccessful()
]);

Configuration Not Loading

php artisan config:clear
php artisan cache:clear

๐Ÿ’ก Best Practices

  1. Store credentials in .env, never hardcode
  2. Use queued notifications for bulk SMS:
    $user->notify(new WelcomeNotification());  // Use ShouldQueue trait
    
  3. Implement retry logic for critical messages
  4. Monitor costs using estimateSegments()
  5. Test with mock gateway before production
  6. Log all SMS for audit trail

๐Ÿค Support


๐Ÿ™ Credits

Developed by Shivam Agarwal


๐Ÿ“„ License

MIT License - see LICENSE file for details.


โญ Show Your Support

If this package helps you, please give it a star on GitHub!


Made with โค๏ธ for the Laravel community

Star History Chart