PHP code example of moffhub / sms-handler

1. Go to this page and download the library: Download moffhub/sms-handler library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

moffhub / sms-handler example snippets


use Moffhub\SmsHandler\Facades\Sms;

// Send a single SMS
Sms::sendSms('+254712345678', 'Hello World');

// Send bulk SMS
Sms::sendBulkSms(['+254712345678', '+254712345679'], 'Hello everyone!');

// Send scheduled SMS
Sms::sendScheduledSms('+254712345678', 'Reminder!', '2024-12-25 09:00:00');

// Check delivery status
$status = Sms::getSmsDeliveryStatus('message_id_here');

use Moffhub\SmsHandler\Services\SmsService;

class NotificationController extends Controller
{
    public function __construct(protected SmsService $smsService) {}

    public function notify(Request $request)
    {
        $this->smsService->sendSms(
            $request->phone,
            $request->message
        );
    }
}

use Moffhub\SmsHandler\SmsManager;

$manager = app(SmsManager::class);

// Use Africa's Talking for this message
$manager->driver('at')->sendSms('+254712345678', 'Via AT');

// Use Twilio for this message
$manager->driver('twilio')->sendSms('+1234567890', 'Via Twilio');

'providers' => [
    'advanta' => [
        // ...credentials...
        'fallback' => 'africastalking',
    ],
],

'providers' => [
    'advanta' => [
        // ...credentials...
        'rate_limit' => 100, // messages per minute, null = unlimited
    ],
],

use Moffhub\SmsHandler\Facades\Sms;

// Check remaining attempts
$remaining = Sms::rateLimiter()->remainingAttempts('advanta');

// Clear the rate limiter for a provider
Sms::rateLimiter()->clear('advanta');

// config/sms.php
'templates' => [
    'otp' => 'Your verification code is {{ code }}. Valid for {{ minutes }} minutes.',
    'welcome' => 'Welcome {{ name }}! Thanks for joining us.',
    'order_shipped' => ['body' => 'Hi {{ name }}, your order #{{ order_id }} has shipped.'],
],

use Moffhub\SmsHandler\Facades\Sms;

// Fluent API
Sms::template('otp', ['code' => '1234', 'minutes' => '5'])
    ->to('+254712345678')
    ->send();

// Check if a template exists
Sms::templateService()->exists('otp'); // true

// Get all template names
Sms::templateService()->getTemplateNames(); // ['otp', 'welcome', 'order_shipped']

use Moffhub\SmsHandler\Facades\Sms;

$estimate = Sms::estimateCost('Hello world', 100, 'advanta');
// Returns:
// [
//     'segments' => 1,
//     'per_segment_cost' => 1.50,
//     'total_cost' => 150.0,
//     'recipient_count' => 100,
//     'is_unicode' => false,
// ]

'providers' => [
    'advanta' => [
        // ...credentials...
        'per_segment_cost' => 1.50,
    ],
],

use Moffhub\SmsHandler\Facades\Sms;

// Overall summary
$summary = Sms::analytics()->summary();
// ['total_sent' => 1000, 'total_delivered' => 950, 'total_failed' => 50, 'success_rate' => 95.0, ...]

// Filter by provider
$summary = Sms::analytics()->forProvider('twilio')->summary();

// Filter by date range
$summary = Sms::analytics()->last30Days()->summary();
$summary = Sms::analytics()->last7Days()->summary();
$summary = Sms::analytics()->between($from, $to)->summary();

// Combine filters
$summary = Sms::analytics()->forProvider('advanta')->last30Days()->summary();

// Daily breakdown
$breakdown = Sms::analytics()->last30Days()->dailyBreakdown();
// Collection of ['date' => '2024-01-15', 'sent' => 100, 'delivered' => 95, 'failed' => 5]

// Per-provider summary
$providers = Sms::analytics()->perProviderSummary();
// Collection of ['provider' => 'advanta', 'sent' => 500, 'delivered' => 490, 'failed' => 10, 'success_rate' => 98.0]

use Moffhub\SmsHandler\Exceptions\ProviderException;
use Moffhub\SmsHandler\Exceptions\InvalidPhoneNumberException;
use Moffhub\SmsHandler\Exceptions\InvalidMessageException;

try {
    Sms::sendSms($phone, $message);
} catch (InvalidPhoneNumberException $e) {
    // Phone number validation failed
    // e.g., "Invalid phone number '123': Phone number must have at least 9 digits"
} catch (InvalidMessageException $e) {
    // Message validation failed
    // e.g., "SMS message cannot be empty"
    // e.g., "Message exceeds maximum of 918 characters"
} catch (ProviderException $e) {
    // Provider API error — fallback was already attempted if configured
    // e.g., "SMS provider 'advanta' failed to send: Connection timeout"
}

use Moffhub\SmsHandler\Events\SmsSent;
use Moffhub\SmsHandler\Events\SmsFailed;
use Moffhub\SmsHandler\Events\DeliveryReportReceived;

// In EventServiceProvider
protected $listen = [
    SmsSent::class => [SmsSuccessListener::class],
    SmsFailed::class => [SmsFailureListener::class],
    DeliveryReportReceived::class => [DeliveryReportListener::class],
];

// SmsSent carries: provider, to, message, messageId, response
// SmsFailed carries: provider, to, message, exception
// DeliveryReportReceived carries: provider, messageId, status, phoneNumber, payload

use Moffhub\SmsHandler\Providers\CustomProvider;
use Illuminate\Support\Collection;

class MySmsProvider extends CustomProvider
{
    protected function getApiUrl(): string
    {
        return 'https://api.custom.com/send';
    }

    protected function buildPayload(string $to, string $message): array
    {
        return [
            'to' => $to,
            'text' => $message,
            'api_key' => $this->config['key'],
        ];
    }

    protected function handleResponse(mixed $response): ?Collection
    {
        return collect([
            'status' => $response['status'] ?? 'unknown',
        ]);
    }
}

// In a service provider
use Moffhub\SmsHandler\SmsManager;

$this->app->make(SmsManager::class)->extend('custom', function ($app) {
    return new MySmsProvider([
        'key' => config('sms.providers.custom.key'),
    ]);
});

// config/sms.php
'providers' => [
    'custom' => [
        'key' => env('MY_CUSTOM_API_KEY'),
    ],
],

use Moffhub\SmsHandler\Notifications\SmsChannel;

class OrderShipped extends Notification
{
    public function via($notifiable): array
    {
        return [SmsChannel::class];
    }

    public function toSms($notifiable): string
    {
        return 'Your order has been shipped!';
    }
}

public function routeNotificationForSms(): string
{
    return $this->phone;
}

use Illuminate\Support\Facades\Http;
use Moffhub\SmsHandler\Facades\Sms;

Http::fake([
    '*' => Http::response([
        'responses' => [
            [
                'response-code' => 200,
                'response-description' => 'Success',
                'mobile' => '254712345678',
                'messageid' => 'msg123',
            ],
        ],
    ]),
]);

Sms::sendSms('+254712345678', 'Test message');

Http::assertSentCount(1);

use Illuminate\Support\Facades\Event;
use Moffhub\SmsHandler\Events\SmsSent;
use Moffhub\SmsHandler\Events\SmsFailed;

Event::fake([SmsSent::class, SmsFailed::class]);

Sms::sendSms('+254712345678', 'Test');

Event::assertDispatched(SmsSent::class, function ($event) {
    return $event->to === '+254712345678';
});

use Moffhub\SmsHandler\Services\TemplateService;

$service = new TemplateService();
$rendered = $service->render('otp', ['code' => '1234']);
$this->assertEquals('Your code is 1234.', $rendered);

use Moffhub\SmsHandler\Facades\Sms;

$estimate = Sms::estimateCost('Short message', 1, 'advanta');
$this->assertEquals(1, $estimate['segments']);
$this->assertEquals(1.50, $estimate['total_cost']);

// config/logging.php
'channels' => [
    'sms' => [
        'driver' => 'daily',
        'path' => storage_path('logs/sms.log'),
        'level' => 'debug',
    ],
],
bash
php artisan vendor:publish --provider="Moffhub\SmsHandler\SmsHandlerServiceProvider" --tag=sms-config
php artisan vendor:publish --tag=sms-migrations
php artisan migrate
bash
# Last 30 days (default)
php artisan sms:stats

# Last 7 days
php artisan sms:stats --days=7

# Filter by provider
php artisan sms:stats --provider=advanta

# Combined
php artisan sms:stats --provider=twilio --days=14
bash
SMS_STRUCTURED_LOG_CHANNEL=sms