doganddev
Accueil Blog Boutique

Laravel SMPP : envoi et réception de SMS avec kstmostofa/laravel-smpp

DOG&DEV · 25/01/2025

Technique FAQ Technique
Laravel SMPP : envoi et réception de SMS avec kstmostofa/laravel-smpp

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:receive sous 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.

Commentaires (0)

Laisser un commentaire