Laravel SMPP : envoi et réception de SMS avec kstmostofa/laravel-smpp
DOG&DEV · 25/01/2025
Laravel SMPP : envoi et réception de SMS avec kstmostofa/laravel-smpp
Le package kstmostofa/laravel-smpp fournit une interface Laravel pour le protocole SMPP v3.4 : envoi de SMS (courts ou longs, GSM 03.38 / UCS-2), Demande de reçu de livraison (DLR), réception de MO (messages entrants), modes Transmitter / Receiver / Transceiver, et gestion des connexions. Un Artisan peut être utilisé pour écouter DLR et MO en continu. Ce guide décrit l’installation, la config, l’envoi et la création d’un listener personnalisé.
Prérequis
- Laravel 10+ (ou 11/12)
- Accès à un serveur SMPP (host, port, identifiants)
- PHP avec extensions sockets (généralement présentes)
1. Installation
composer require kstmostofa/laravel-smpp
Publication de la config :
php artisan vendor:publish --provider="Kstmostofa\LaravelSmpp\LaravelSmppServiceProvider" --tag="smpp-config"
2. Configuration
Fichier config/smpp.php (les valeurs par défaut peuvent être surchargées par .env) :
return [
'host' => env('SMPP_HOST', '127.0.0.1'),
'port' => env('SMPP_PORT', 2775),
'username' => env('SMPP_USERNAME', 'smppuser'),
'password' => env('SMPP_PASSWORD', 'smpppass'),
'timeout' => env('SMPP_TIMEOUT', 10000),
'debug' => env('SMPP_DEBUG', false),
];
.env :
SMPP_HOST=smpp.fournisseur.com
SMPP_PORT=2775
SMPP_USERNAME=votre_user
SMPP_PASSWORD=votre_mot_de_passe
SMPP_TIMEOUT=10000
SMPP_DEBUG=false
3. Envoi rapide
use Kstmostofa\LaravelSmpp\Facades\LaravelSmpp;
use Kstmostofa\LaravelSmpp\SMPP;
LaravelSmpp::getTransport()->open();
LaravelSmpp::bindTransceiver();
$id = LaravelSmpp::setSender('MONALIAS', SMPP::TON_ALPHANUMERIC)
->setRecipient('33612345678', SMPP::TON_INTERNATIONAL)
->requestDLR()
->sendSMS('Hello world');
LaravelSmpp::close();
requestDLR() demande les reçus de livraison ; le fournisseur SMPP renverra des DLR que vous pouvez traiter dans un listener (voir ci‑dessous).
4. Listener DLR / MO (commande Artisan)
Les DLR et MO sont asynchrones : il faut une connexion persistante (bind Receiver ou Transceiver) et une boucle qui lit les PDU. On réalise ça avec une commande Artisan longue, à lancer via Supervisor ou systemd en production.
Création :
php artisan make:command SmppReceive --command=smpp:receive
Exemple d’implémentation (app/Console/Commands/SmppReceive.php) :
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Kstmostofa\LaravelSmpp\Facades\LaravelSmpp;
use Kstmostofa\LaravelSmpp\DeliveryReceipt;
use Kstmostofa\LaravelSmpp\Sms;
class SmppReceive extends Command
{
protected $signature = 'smpp:receive {--host=} {--port=} {--username=} {--password=} {--timeout=} {--debug}';
public function handle()
{
$cfg = config('smpp');
foreach (['host','port','username','password','timeout'] as $k) {
if ($this->option($k) !== null) $cfg[$k] = $this->option($k);
}
if ($this->option('debug')) $cfg['debug'] = true;
LaravelSmpp::setConfig($cfg);
LaravelSmpp::getTransport()->open();
LaravelSmpp::bindTransceiver();
$this->info('Connecté et bind OK.');
while (true) {
try {
$pdu = LaravelSmpp::readSMS();
if ($pdu instanceof DeliveryReceipt) {
$this->info("[DLR] id={$pdu->messageId} status={$pdu->status}");
// Mettre à jour le statut en BDD, notifier, etc.
} elseif ($pdu instanceof Sms) {
$this->info("[MO] from={$pdu->source->value} text={$pdu->message}");
// Stocker le MO, déclencher un job, etc.
}
LaravelSmpp::enquireLink();
usleep(100_000); // 100 ms
} catch (\Throwable $e) {
$this->error('Erreur: ' . $e->getMessage());
sleep(1);
try { LaravelSmpp::reconnect(); } catch (\Throwable $r) { $this->error('Reconnect: ' . $r->getMessage()); }
}
}
}
}
Lancement :
php artisan smpp:receive --host=smpp.example.com --username=user --password=pass --debug
5. Override de config à la volée
LaravelSmpp::setConfig([
'host' => 'alt.host', 'port' => 2776, 'username' => 'alt',
'password' => 'secret', 'timeout' => 15000, 'debug' => true,
]);
6. Forcer IPv4 / IPv6
Si le réseau pose problème (résolution, firewall) :
use Kstmostofa\LaravelSmpp\Transport\Socket;
Socket::$forceIpv4 = true; // ou Socket::$forceIpv6 = true;
Dépannage
| Symptôme | Cause possible | Correctif |
|---|---|---|
| Erreur de connexion | Mauvais host/port, firewall, identifiants | Vérifier SMPP_HOST, SMPP_PORT, credentials ; SMPP_DEBUG=true pour les logs |
| DLR / MO non reçus | Bind en Transmitter au lieu de Transceiver/Receiver | Utiliser bindTransceiver (ou bind Receiver) pour recevoir ; le fournisseur doit envoyer les DLR |
| Listener qui s’arrête | Exception non gérée, déconnexion | try/catch dans la boucle ; reconnect ; Supervisor pour redémarrer la commande |
Bonnes pratiques
- Lancer
smpp:receivesous Supervisor ou systemd avec restart automatique. - Persister les DLR (statut des envois) et les MO (messages entrants) en BDD ou via jobs pour un traitement asynchrone.
- Ne pas logger les corps des SMS si des données personnelles ou sensibles sont présentes.
Ressources
Cet article s’inscrit dans notre série de guides technique et développement web. Pour un serveur ou une application sur-mesure, contact.