SMS API – SMS Class
The SMS class sends text messages through a fully modular driver system. Built‑in international providers (Twilio, Vonage, Plivo, etc.) and five top Nepali providers are included. A Generic HTTP driver allows any custom gateway, and users can create their own named providers from the SMS Settings UI without writing code.
Contents
- Architecture & Design
- Quick Start
- Built‑in Providers
- Nepali Providers
- Creating Custom Providers (UI)
- Generic HTTP Driver
- Sending SMS
- Extending with PHP Drivers
- Troubleshooting
Architecture & Design
The SMS system follows a driver pattern. Every provider is a single PHP class
implementing the SmsDriver interface, stored in plugins/SmsDrivers/.
The core SMS class scans this folder, reads each driver, and builds a registry
that the Misc module's SMS Settings tab uses to populate the provider dropdown.
- Zero hardcoding – drop a new PHP file into the folder and it appears instantly.
- UI‑driven custom providers – non‑developers can add their own gateways via a simple form (Generic HTTP driver under the hood).
- All configuration stored per project in
project.json.
Quick Start
use PpPhp\Core\SMS;
// 1. Configure (usually done via Misc → SMS Settings, or programmatically)
SMS::SetConfig([
'provider' => 'twilio',
'accountSid' => 'AC...',
'authToken' => 'abc...',
'from' => '+1234567890',
]);
// 2. Send
$result = SMS::Send('+9779812345678', 'Hello from pp-php!');
if ($result['success']) {
echo 'Sent!';
} else {
echo 'Error: ' . $result['error'];
}
Built‑in International Providers
| Provider | Required Fields | Notes |
|---|---|---|
| Twilio | accountSid, authToken, from | Trial accounts can only send to verified numbers. |
| Vonage (Nexmo) | apiKey, apiSecret, from | Supports alphanumeric sender IDs. |
| MessageBird | accessKey, from | Create access key in Developers section. |
| Plivo | authId, authToken, from | Tiered pricing; strong alternative to Twilio. |
| Sinch | servicePlanId, bearerToken, from | Choose region for base URL. |
| Infobip | apiKey, baseUrl, from | Base URL found in Infobip portal. |
| ClickSend | username, apiKey | From is optional; uses shared numbers if blank. |
| Generic HTTP | url, method, toParam, msgParam, fromParam | Works with any gateway accepting HTTP requests. |
Nepali Providers
| Provider | Required Fields | Endpoint |
|---|---|---|
| Sparrow SMS | token, identity, from | api.sparrowsms.com/v2/sms/ |
| Aakash SMS | token, from | aakashsms.com/admin/public/sms/v3/send |
More Nepali providers can be added by dropping a PHP driver into plugins/SmsDrivers/.
Creating Custom Providers (UI)
In the Misc → SMS Settings tab, click Add Custom Provider. Fill in:
- Provider Key – a unique ID (e.g.,
mygateway) - Display Label – shown in the dropdown
- API URL – the gateway's endpoint
- Method – POST or GET
- Parameter names for recipient, message, and sender
- Extra params – any additional key=value pairs required by the gateway (comma separated)
After saving, the new provider appears in the dropdown and works like any built‑in driver.
All settings are stored in project.json.
Example: Creating a Custom Provider for "BulkSMS"
- Click Add Custom Provider.
- Key:
bulksms - Label:
BulkSMS Gateway - API URL:
https://bulksms.example.com/api/v1/send - Method: POST
- to param:
recipient - message param:
content - from param:
sender - Extra params:
api_key=MY_API_KEY,type=text - Click Save.
Now select "BulkSMS Gateway" from the provider dropdown, fill in the required fields
(like from), and send a test SMS.
Generic HTTP Driver
The Generic HTTP driver allows any SMS gateway that accepts HTTP requests. Use it directly from the SMS Settings tab (select "Generic HTTP") or programmatically:
SMS::SetConfig([
'provider' => 'http',
'url' => 'https://sms.example.com/api/send',
'method' => 'POST',
'toParam' => 'phone',
'msgParam' => 'text',
'fromParam' => 'sender',
'extraParams' => 'api_key=abc123,priority=high',
'from' => 'MyApp',
]);
$result = SMS::Send('+9779812345678', 'Your OTP is 123456');
Sending SMS
The SMS::Send($to, $message) method returns an associative array:
// Success
['success' => true]
// Failure
['success' => false, 'error' => 'Description of the error']
Example: Sending with a custom provider configured via the UI
// The UI already saved this config. In your code, just load the project state.
$state = ProjectState::load('my-project');
$smsConfig = $state['misc']['sms'] ?? [];
SMS::SetConfig($smsConfig);
$result = SMS::Send('+9779812345678', 'Hello!');
if ($result['success']) {
echo 'OK';
} else {
echo $result['error'];
}
Extending with PHP Drivers
Create a new file in plugins/SmsDrivers/ (e.g., MyProvider.php) implementing the SmsDriver interface:
<?php
declare(strict_types=1);
namespace PpPhp\Plugins\SmsDrivers;
use PpPhp\Core\SmsDriver;
class MyProvider implements SmsDriver
{
public function label(): string { return 'My SMS Provider'; }
public function helpText(): string { return 'Enter your API credentials.'; }
public function requiredFields(): array {
return ['apiKey' => 'API Key', 'from' => 'Sender ID'];
}
public function send(string $to, string $message, array $config): array {
$apiKey = $config['apiKey'] ?? '';
$from = $config['from'] ?? '';
if (empty($apiKey) || empty($from)) {
return ['success' => false, 'error' => 'API Key and Sender ID are required.'];
}
$url = 'https://api.myprovider.com/send';
$data = http_build_query(['key' => $apiKey, 'to' => $to, 'from' => $from, 'msg' => $message]);
// cURL logic (copy from any existing driver)
$ch = curl_init(); /* ... */ curl_close($ch);
return ['success' => true];
}
}
Save the file, refresh the Misc → SMS Settings page, and your provider appears.
Troubleshooting
- "No SMS provider selected" – select a provider in the Misc module's SMS tab.
- "Driver not found for provider 'X'" – the PHP driver file is missing or has a syntax error. Check
plugins/SmsDrivers/. - "HTTP 401 / 403" – check your API key, token, or credentials.
- "cURL error" – ensure your server allows outbound HTTPS connections.
- Twilio trial accounts – only verified numbers can receive SMS.
- Custom provider not working – verify the API URL and parameter names match exactly what the gateway expects.