lindemannrock / craft-sms-manager
SMS gateway and management for Craft CMS with multi-provider support
Installs: 5
Dependents: 2
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Language:Twig
Type:craft-plugin
pkg:composer/lindemannrock/craft-sms-manager
Requires
- php: ^8.2
- craftcms/cms: ^5.0.0
- lindemannrock/craft-logging-library: ^5.0
- lindemannrock/craft-plugin-base: ^5.0
Requires (Dev)
- craftcms/ecs: dev-main
- craftcms/phpstan: dev-main
README
SMS gateway and management plugin for Craft CMS 5.x with multi-provider support, analytics, and delivery tracking.
Beta Notice
This plugin is currently in active development and provided under the MIT License for testing purposes.
Licensing is subject to change. We are finalizing our licensing structure and some or all features may require a paid license when officially released on the Craft Plugin Store. Some plugins may remain free, others may offer free and Pro editions, or be fully commercial.
If you are using this plugin, please be aware that future versions may have different licensing terms.
Features
- Multi-Provider Support: Extensible provider system for different SMS gateways
- MPP-SMS: Kuwait SMS provider with Arabic and English support
- Extensible architecture for adding custom providers
- Sender ID Management: Configure multiple sender IDs per provider
- Enable/disable sender IDs individually
- Set default sender IDs per provider
- Handle-based API access for templates
- Multi-Language Support: Native support for Arabic (UCS-2 encoding) and English messages
- Comprehensive Analytics:
- Daily SMS statistics (sent, failed, pending)
- Language breakdown (English, Arabic, other)
- Provider and sender ID performance tracking
- Source plugin tracking (know which plugin triggered each SMS)
- Configurable retention period
- Delivery Logs:
- Full message history with status tracking
- Provider response logging
- Error message capture
- Export to CSV
- Configurable retention and auto-cleanup
- Dashboard: Real-time overview of SMS activity and provider status
- User Permissions: Granular access control for providers, sender IDs, analytics, logs, and settings
- Utilities: Clear analytics and logs from Craft's utilities section
- Logging: Structured logging via Logging Library with configurable levels
Requirements
- Craft CMS 5.0 or greater
- PHP 8.2 or greater
- Logging Library 5.0 or greater (installed automatically as dependency)
Installation
Via Composer
cd /path/to/project
composer require lindemannrock/craft-sms-manager
./craft plugin/install sms-manager
Using DDEV
cd /path/to/project
ddev composer require lindemannrock/craft-sms-manager
ddev craft plugin/install sms-manager
Via Control Panel
In the Control Panel, go to Settings → Plugins and click "Install" for SMS Manager.
Configuration
Settings
Navigate to SMS Manager → Settings in the control panel to configure:
General Settings:
- Plugin Name: Customize the display name in the control panel
Default Provider Settings:
- Default Provider: Provider to use when none specified
- Default Sender ID: Sender ID to use when none specified
Analytics Settings:
- Enable Analytics: Toggle analytics tracking
- Analytics Limit: Maximum records to retain
- Analytics Retention: Days to keep analytics (0 = forever)
- Auto-Trim Analytics: Automatically clean up old records
Logs Settings:
- Enable Logs: Toggle delivery logging
- Logs Limit: Maximum log records to retain
- Logs Retention: Days to keep logs (0 = forever)
- Auto-Trim Logs: Automatically clean up old records
Interface Settings:
- Items Per Page: Number of items in list views
- Dashboard Refresh: Auto-refresh interval in seconds
Logging Library Settings:
- Log Level: debug, info, warning, error
Config File
Create a config/sms-manager.php file to override default settings:
cp vendor/lindemannrock/craft-sms-manager/src/config.php config/sms-manager.php
<?php return [ // Plugin Settings 'pluginName' => 'SMS Manager', // Logging Settings 'logLevel' => 'error', // error, warning, info, or debug (debug requires devMode) // Analytics Settings 'enableAnalytics' => true, 'analyticsLimit' => 1000, 'analyticsRetention' => 30, // days (0 for unlimited) 'autoTrimAnalytics' => true, // Logs Settings 'enableLogs' => true, 'logsLimit' => 10000, 'logsRetention' => 30, // days (0 for unlimited) 'autoTrimLogs' => true, // Interface Settings 'itemsPerPage' => 100, 'refreshIntervalSecs' => 30, // Multi-environment support 'dev' => [ 'logLevel' => 'debug', // More verbose in dev 'analyticsRetention' => 7, 'logsRetention' => 7, ], 'production' => [ 'logLevel' => 'error', // Only errors in production 'analyticsRetention' => 90, 'logsRetention' => 90, ], ];
Usage
Setting Up a Provider
- Navigate to SMS Manager → Providers
- Click New Provider
- Select provider type (e.g., MPP-SMS)
- Enter provider settings:
- Name: Display name for the provider
- API Key: Your provider API key (supports environment variables:
$MPP_SMS_API_KEY) - API URL: Optional custom endpoint (defaults to provider's standard URL)
- Enable the provider and save
Setting Up Sender IDs
- Navigate to SMS Manager → Sender IDs
- Click New Sender ID
- Configure:
- Name: Display name (e.g., "My Brand")
- Handle: Unique identifier for templates (e.g.,
my-brand) - Sender ID: The actual sender ID registered with your provider
- Provider: Select which provider this sender ID belongs to
- Default: Set as default for this provider
- Enable and save
Sending SMS from PHP
use lindemannrock\smsmanager\SmsManager; // Basic send (uses default provider and sender ID) $success = SmsManager::$plugin->sms->send( '+96512345678', // Recipient 'Hello from Craft CMS!', // Message 'en' // Language: 'en' or 'ar' ); // Send with specific provider and sender ID $success = SmsManager::$plugin->sms->send( '+96512345678', 'مرحبا من كرافت!', // Arabic message 'ar', // Arabic language $providerId, // Provider ID $senderIdId, // Sender ID 'my-plugin', // Source plugin (for analytics) $elementId // Source element ID (optional) ); // Send using sender ID handle $success = SmsManager::$plugin->sms->sendWithHandle( '+96512345678', 'Hello!', 'my-brand', // Sender ID handle 'en', 'my-plugin' ); // Send with detailed response $result = SmsManager::$plugin->sms->sendWithDetails( '+96512345678', 'Hello!', 'en', $providerId, $senderIdId ); // Result includes: // - success: bool // - messageId: string|null // - response: string|null (raw provider response) // - error: string|null // - executionTime: int (milliseconds) // - providerName: string|null // - senderIdName: string|null // - senderIdValue: string|null // - recipient: string
Sending SMS from Twig
{# Send SMS using the Twig variable #} {% set result = craft.smsHelper.send('+96512345678', 'Hello!', 'en') %} {% if result %} <p>SMS sent successfully!</p> {% else %} <p>Failed to send SMS.</p> {% endif %} {# Send with specific sender ID handle #} {% set result = craft.smsHelper.sendWithHandle('+96512345678', 'Hello!', 'my-brand', 'en') %} {# Get all enabled sender IDs #} {% set senderIds = craft.smsHelper.getSenderIds() %} {% for senderId in senderIds %} <option value="{{ senderId.id }}">{{ senderId.name }}</option> {% endfor %} {# Get sender IDs for a specific provider #} {% set senderIds = craft.smsHelper.getSenderIds(providerId) %}
Integration with Other Plugins
SMS Manager tracks which plugin triggered each SMS for analytics:
// In your custom plugin SmsManager::$plugin->sms->send( $phoneNumber, $message, 'en', null, // Use default provider null, // Use default sender ID 'my-custom-plugin', // Your plugin handle $entry->id // Optional: related element ID );
This appears in analytics and logs, allowing you to see SMS usage by source plugin.
Providers
MPP-SMS
Kuwait SMS provider with support for Arabic and English messages.
Settings:
- API Key: Your MPP-SMS API key (required)
- API URL: Custom endpoint (optional, defaults to
https://api.mpp-sms.com/api/send.aspx)
Features:
- Automatic UCS-2 encoding for Arabic messages
- English URL encoding
- Message ID extraction from responses
- Full error logging
Environment Variables:
# .env
MPP_SMS_API_KEY=your-api-key-here
// In provider settings, use: $MPP_SMS_API_KEY
Creating Custom Providers
Extend BaseProvider to create custom SMS providers:
<?php namespace mymodule\providers; use lindemannrock\smsmanager\providers\BaseProvider; use lindemannrock\smsmanager\records\ProviderRecord; class MyProvider extends BaseProvider { public static function handle(): string { return 'my-provider'; } public static function displayName(): string { return 'My SMS Provider'; } public static function description(): string { return 'Description of my provider.'; } public static function supportsConnectionTest(): bool { return true; // If you implement testConnection() } public function getSettingsHtml(?ProviderRecord $provider = null): string { return $this->renderSettingsTemplate('my-module/provider-settings', [ 'provider' => $provider, ]); } public function validateSettings(array $settings): array { $errors = []; if (empty($settings['apiKey'])) { $errors['apiKey'] = 'API Key is required.'; } return $errors; } public function send(string $to, string $message, string $senderId, string $language, array $settings): array { // Implement your provider's API call return [ 'success' => true, 'messageId' => 'msg-123', 'response' => 'OK', 'error' => null, ]; } }
Register your provider in your module's init():
use lindemannrock\smsmanager\services\ProvidersService; use lindemannrock\smsmanager\events\RegisterProvidersEvent; use yii\base\Event; Event::on( ProvidersService::class, ProvidersService::EVENT_REGISTER_PROVIDERS, function(RegisterProvidersEvent $event) { $event->providers[] = MyProvider::class; } );
Analytics
Viewing Analytics
Navigate to SMS Manager → Analytics to see:
- Total messages sent vs failed
- Daily trends chart
- Language breakdown (English, Arabic, other)
- Provider performance comparison
- Source plugin breakdown
Analytics API
use lindemannrock\smsmanager\SmsManager; // Get analytics service $analytics = SmsManager::$plugin->analytics; // Get summary statistics $summary = $analytics->getSummary(); // Returns: totalSent, totalFailed, totalPending, successRate // Get daily statistics $daily = $analytics->getDailyStats($startDate, $endDate); // Get provider breakdown $byProvider = $analytics->getByProvider(); // Get language breakdown $byLanguage = $analytics->getByLanguage();
SMS Logs
Viewing Logs
Navigate to SMS Manager → SMS Logs to see:
- All sent messages with status (sent, failed, pending)
- Recipient, message content, language
- Provider and sender ID used
- Provider response and error messages
- Source plugin and element tracking
Log Statuses
- Pending: Message queued, not yet sent
- Sent: Successfully delivered to provider
- Failed: Provider returned an error
Exporting Logs
Click Export to download logs as CSV with columns:
- Date, Recipient, Message, Language
- Provider, Sender ID, Status
- Error Message, Provider Message ID
- Source Plugin, Source Element ID
Utilities
Access via Utilities → SMS Manager:
Analytics & Logs
- Clear All Analytics: Remove all analytics data
- Clear All SMS Logs: Remove all delivery logs
Both actions require confirmation and respect user permissions.
Permissions
Provider Permissions
- Manage providers
- View providers
- Create providers
- Edit providers
- Delete providers
Sender ID Permissions
- Manage sender IDs
- View sender IDs
- Create sender IDs
- Edit sender IDs
- Delete sender IDs
Analytics Permissions
- View analytics
- Export analytics
- Clear analytics
Log Permissions
- View logs
- Download logs
Settings Permissions
- Manage settings
Logging
SMS Manager uses the LindemannRock Logging Library for system logging.
Log Levels
- Error: Critical errors only (default)
- Warning: Errors and warnings
- Info: General information
- Debug: Detailed debugging (requires devMode)
Configuration
// config/sms-manager.php return [ 'logLevel' => 'error', // error, warning, info, or debug ];
Note: Debug level requires Craft's devMode to be enabled.
Log Files
- Location:
storage/logs/sms-manager-YYYY-MM-DD.log - Retention: 30 days (automatic cleanup)
- Web Interface: View logs at SMS Manager → System Logs
Events
use lindemannrock\smsmanager\services\SmsService; use lindemannrock\smsmanager\events\SendEvent; use yii\base\Event; // Before sending SMS Event::on( SmsService::class, SmsService::EVENT_BEFORE_SEND, function(SendEvent $event) { // Access: $event->to, $event->message, $event->language // Set $event->isValid = false to cancel } ); // After sending SMS Event::on( SmsService::class, SmsService::EVENT_AFTER_SEND, function(SendEvent $event) { // Access: $event->success, $event->messageId, $event->response } ); // Register custom providers use lindemannrock\smsmanager\services\ProvidersService; use lindemannrock\smsmanager\events\RegisterProvidersEvent; Event::on( ProvidersService::class, ProvidersService::EVENT_REGISTER_PROVIDERS, function(RegisterProvidersEvent $event) { $event->providers[] = MyCustomProvider::class; } );
Troubleshooting
SMS Not Sending
- Check provider is enabled: SMS Manager → Providers → ensure status is enabled
- Check sender ID is enabled: SMS Manager → Sender IDs → ensure status is enabled
- Verify API credentials: Check API key is correct in provider settings
- Check logs: SMS Manager → SMS Logs for error messages
- Check system logs: SMS Manager → System Logs for detailed errors
Arabic Messages Not Displaying Correctly
- Ensure language is set to
'ar'when sending - MPP-SMS automatically uses UCS-2 encoding for Arabic
- Check recipient device supports Arabic SMS
Analytics Not Tracking
- Verify analytics is enabled in settings
- Check
enableAnalyticssetting istrue - Analytics only tracks when messages are sent via the service
Provider Response Errors
Common MPP-SMS errors:
- Invalid API Key: Check your API key in provider settings
- Invalid Sender ID: Sender ID not registered with provider
- Invalid Mobile Number: Check phone number format
- Insufficient Balance: Top up your provider account
Support
- Documentation: https://github.com/LindemannRock/craft-sms-manager
- Issues: https://github.com/LindemannRock/craft-sms-manager/issues
- Email: support@lindemannrock.com
License
This plugin is licensed under the MIT License. See LICENSE for details.
Developed by LindemannRock