Repository navigation
adding a driver
You can plug in any SMS gateway (or messenger) without forking the package by registering a driver.
There are two registration styles:
| Method | When to use |
|---|---|
Sms::registerDriver($type, $class) |
Class is constructed as new $class($config) from DriverRegistry
|
Sms::extend($type, $closure) |
You need a custom factory (DI, mocked client, named connections) |
| Base class | Implements | Use for |
|---|---|---|
AbstractDriver |
SmsDriver |
Iranian / HTTP SMS panels (recommended) |
AbstractMessengerDriver |
MessengerDriver |
Telegram, Bale, WhatsApp-style bots |
AbstractHttpDriver |
MessageDriver |
Shared HTTP helpers only |
For SMS you almost always extend AbstractDriver:
- Override
getName(),send(), and usuallysendTemplate(). - Everything else (
getCredit, inbox, reports, …) throwsUnsupportedDriverMethodExceptionuntil you implement it. - Helpers like
request(),toResponse(),normalizeMobiles()are inherited.
<?php
namespace App\Sms;
use Alizeinodin\SmsApi\Drivers\AbstractDriver;
use Alizeinodin\SmsApi\DTOs\SendResult;
class MyPanelDriver extends AbstractDriver
{
public function getName(): string
{
return (string) ($this->config['name'] ?? 'mypanel');
}
public function send(string|array $mobiles, string $message, array $options = []): SendResult
{
$payload = [
'to' => $this->normalizeMobiles($mobiles),
'text' => $message,
'from' => $options['lineNumber'] ?? $this->lineNumber,
];
$decoded = $this->request('POST', 'send', $payload);
return $this->toResponse($decoded, driver: $this->getName());
}
public function sendTemplate(
string $mobile,
int|string $templateId,
array $parameters = [],
array $options = [],
): SendResult {
$decoded = $this->request('POST', 'verify', [
'mobile' => $this->normalizeMobile($mobile),
'template' => $templateId,
'tokens' => $parameters,
]);
return $this->toResponse($decoded, driver: $this->getName());
}
protected function buildClient(array $headers = []): \GuzzleHttp\Client
{
return parent::buildClient(array_merge([
'Authorization' => 'Bearer ' . ($this->config['api_key'] ?? ''),
], $headers));
}
}Set base_url (and credentials) in config so buildClient() / request() work.
In AppServiceProvider::boot():
use Alizeinodin\SmsApi\Facades\Sms;
use App\Sms\MyPanelDriver;
Sms::registerDriver('mypanel', MyPanelDriver::class);Then configure:
// config/smsapi.php
'drivers' => [
'mypanel' => [
'driver' => 'mypanel',
'api_key' => env('MYPANEL_API_KEY'),
'base_url' => env('MYPANEL_BASE_URL', 'https://api.mypanel.example/v1'),
'line_number' => env('MYPANEL_LINE'),
'timeout' => 30,
],
],SMSAPI_DRIVER=mypanel
MYPANEL_API_KEY=...Sms::driver('mypanel')->send('09121234567', 'Hello');Useful when the constructor needs more than $config, or you want named connections:
use Alizeinodin\SmsApi\Facades\Sms;
use App\Sms\MyPanelDriver;
Sms::extend('mypanel', function ($app, $name) {
$config = $app->make(\Alizeinodin\SmsApi\SmsManager::class)->configuration($name);
return new MyPanelDriver($config);
});extend receives ($app, $connectionName). One-argument closures fn ($app) => … still work for BC.
// config/smsapi.php
'connections' => [
'mypanel-otp' => [
'driver' => 'mypanel',
'api_key' => env('MYPANEL_OTP_KEY'),
'line_number' => env('MYPANEL_OTP_LINE'),
'base_url' => env('MYPANEL_BASE_URL'),
],
'mypanel-marketing' => [
'driver' => 'mypanel',
'api_key' => env('MYPANEL_MARKETING_KEY'),
'line_number' => env('MYPANEL_MARKETING_LINE'),
'base_url' => env('MYPANEL_BASE_URL'),
],
],Sms::connection('mypanel-otp')->sendTemplate(...);
Sms::driver('mypanel-marketing')->send(...);getName() → connection name (mypanel-otp)
getProvider() → transport / driver type (mypanel)
Extend AbstractMessengerDriver and implement send() (recipients are chat/user ids). Register the same way:
Sms::registerDriver('mybot', \App\Sms\MyBotDriver::class);Sms::driver('mybot')->send($chatId, 'Hello', ['chat_id' => $chatId]);Do not type-hint SmsDriver for messengers — use MessageDriver / MessengerDriver.
Sms::smsDriver() rejects non-SMS channels.
Once registered, the type key works everywhere else:
'templates' => [
'otp-login' => [
'mypanel' => 1001,
'smsir' => 100000,
],
],SMSAPI_FAILOVER_DRIVERS=mypanel,smsir,kavenegarSms::failover(['mypanel', 'kavenegar'])->send(...);
Sms::template('otp-login')->to($user)->send(['CODE' => '1234']);- Extend
AbstractDriver(SMS) orAbstractMessengerDriver(chat). - Implement at least
getName()+send()(+sendTemplate()for OTP patterns). - Return
SendResultviatoResponse()/new SendResult(...). - Register with
registerDriverorextend. - Add
drivers.*orconnections.*inconfig/smsapi.php. - Optionally map templates and include the type in failover lists.
See also: Drivers · Configuration · Templates