En continuant à naviguer sur mon site, vous consentez à ce que j'utilise des cookies pour collecter les statistiques de visites. En savoir plus

#Informatique Créer un système d'envoi de SMS par le Web

L'envoi de SMS ne se limite pas forcément à "Tu viens à la soirée samedi ?" Ça peut aussi s'avérer très pratique pour nous informer qu'un problème est arrivé sur un serveur, que la température de votre frigo est trop élevée ou que sais-je. Avec un Rasperry Pi, on peut mettre en place ce genre de système assez facilement…

J'ai récemment mis en place, pour un de mes projets et pour mes besoins personnels, un système d'envoi de SMS plus ou moins automatique, géré par un serveur. Je partage l'astuce pour les intéressés. Il peut y avoir plusieurs utilisations possibles comme être averti par SMS d'un problème sur votre serveur ou sur votre site (surcharge, sauvegarde échouée, …), ou des applications domotiques, notamment parce que ce système utilise un Rasperry Pi. Justement, voici la liste du matériel nécessaire :

  • Un Raspberry Pi fonctionnel
  • Une clef USB GSM (exemple : Huawei) à brancher sur le RasPi
  • Une carte Sim
  • Votre serveur (si vous voulez faire uniquement de la domotique il ne vous sera pas vraiment utile)

Ce tuto sera donc composé de deux parties : on mettra tout d'abord en place l'envoi de SMS sur le RasPi, puis on mettra en place un service web sur le serveur, afin de pouvoir planifier l'envoi de SMS.

Avant toute chose, sachez que ces instructions sont perfectibles, donc si vous avez des suggestions, des améliorations à proposer, n'hésitez pas !

Prise en main de la clef GSM

Comme j'ai galéré pendant plusieurs heures à envoyer des SMS vainement, je vous le dis tout de suite : cherchez le numéro du centre de messagerie de votre opérateur. Si vous ne l'avez pas, en France, l'envoi de SMS ne s'effectuera pas (ce n'est peut-être pas le cas pour tous les pays). Pour Free, par exemple c'est le +33 (0)6 95 00 06 95. Par ailleurs, faites attention, lisez bien le contrat de votre opérateur mobile qui peut imposer une limite de nombre de SMS par jour, par mois ou une limite de destinataires distincts. De plus, certains opérateurs n'aiment pas tellement qu'on utilise leurs cartes SIM dans des clefs 3G ou pour envoyer des SMS de manière plus ou moins automatique, ce que je trouve un peu abhérent, mais c'est comme ça. Je ne serai donc pas tenu responsable des utilisations abusive et tout le tralala. En bref, informez-vous sur les limites de votre contrat pour ne pas avoir de mauvaises surprises et n'en profitez pas pour spammer les gens !

Revenons-en à la théorie. Tout d'abord, vous devez savoir que les dispositifs GSM communiquent avec des commandes "AT". Par exemple :

AT+CLIR=1 OK

Ici, AT+CLIR=1 est la commande que vous avez envoyée. Elle a pour effet de rendre vos prochains appels masqués. Le OK est la réponse du dispositif. Voici toute une liste de commandes qui pourront vous être utiles durant vos essais :

  • AT : renvoie OK. Ça vous permet d'être sûr que vous vous trouvez bien sur une interface de communication AT.
  • ATI : vous permet d'obtenir des informations sur votre dispositif.
  • AT+CPIN=xxxx : Remplacez xxxx par le code PIN de votre carte SIM
  • AT+CMGF=1 : Permet de définir le format d'envoi des SMS au format texte. Si vous mettez =0, le format sera un format encodé, mais je ne le traîterai pas ici
  • AT+CMGW="+33xxxxxxxxx" : Permet d'enregistrer le SMS à envoyer. Remplacez +33xxxxxxxxx par le numéro de téléphone souhaité. Quand vous utilisez cette commande, vous entrez ensuite dans un mode de saisie interactif. Vous pouvez donc écrire votre SMS à votre guise, jusqu'à ce que vous appuyez sur Ctrl+Z. Si tout s'est bien passé, le dispositif vous renverra l'identifiant du SMS que vous venez de saisir. Le SMS est désormais enregistré dans la carte SIM.
  • AT+CMSS=xx : Permet d'envoyer le SMS dont l'identifiant (retourné par la commande AT+CMGW) est xx.
  • AT+CSQ : Permet de connaître la qualité du signal réseau. Un nombre du style 8,99 pourra vous être retourné. Ce qui compte, c'est le chiffre avant la virgule. Plus il est élevé, meilleure la qualité du signal réseau est.

Il est possible de court-circuiter l'enregistrement du SMS en mémoire en utilisant la commande AT+CMGS, mais dans un premier temps, faisons les choses étape par étape. D'autres commandes comme AT+COPS vous permettent d'obtenir des informations sur le réseau, notamment pour obtenir le nom du réseau (Orange, SFR, Bouygues, …) mais aussi d'autres informations pour savoir si vous êtes en mode itinérance, etc. Je ne détaille pas ces commandes ici, mais sachez qu'elles existent et qu'il existe des documents comme celui-ci qui vous permettront d'exploiter pleinement votre dispositif GSM.

Pour pouvoir communiquer directement avec l'interface du dispositif GSM, je vous recommande d'installer la commande cu sur votre RasPi qui s'utilise comme suit :

cu -l ttyUSB0

Bien sûr, si votre clef GSM (qui prend 2 ports USB virtuels à elle toute seule !) n'est pas sur ttyUSB0 (/dev/ttyUSB0), remplacez par ce qui convient. Pour quitter cette interface semblable à un telnet, vous devrez saisir les caractères suivant et patienter 2 secondes :

~.

Dans un premier temps, je vous laisse faire vos essais.

Envoi du premier SMS en utilisant un script shell

Pour s'affranchir de l'interface de cu, et donc pour pouvoir faciliter l'utilisation dans un script shell, une commande nous sauve la vie : il s'agit de gammu (à installer également). Je vous donne la commande à utiliser de but en blanc :

gammu sendsms TEXT 06XXXXXXXX -smscnumber 0695000695 -text "Servez ces vieux whisky aux juges blonds qui fument."

Détaillons la commande :

  • sendsms : l'action à effectuer, on envoie un SMS
  • TEXT : le format d'écriture du SMS (correspond à un AT+CMGF=1)
  • 06XXXXXXXX : le numéro du destinataire
  • -smscnumber 0695000695 : on retrouve le numéro du service de l'opérateur
  • -text "…" : Le texte du message. Gammu permet aussi de lire l'entrée standard.

À partir de là, les possibilités deviennent infinies ! Vous pouvez donc exploiter cette commande dans un script shell, que vous appelerez dans un cron, etc.

Interaction avec un serveur distant

Dans mon cas, mon serveur a besoin de cette interface d'envoi de SMS. Or, mon RasPi se trouve chez moi, derrière ma box. Il n'est donc pas accessible par défaut depuis l'extérieur, et je n'avais pas envie d'ouvrir mon pare-feu, mettre un DynDNS en place, un VPN ou je ne sais quoi. J'ai donc mis en place un cron sur le RasPi qui consulte, toutes les minutes, la liste des SMS à envoyer que mon serveur a enregistrée, et qui les envoie en conséquence.

Côté serveur, un petit service a été mis en place qui peut-être appelé de deux manières :

  • Enregistrer un SMS à envoyer
  • Récupérer la liste des SMS

Histoire d'augmenter un peu la sécurité, non seulement on mettra en place un certificat SSL pour chiffrer la connexion, mais en plus, j'ai codé un petit système d'authentification inspiré des systèmes comme OAuth. Ainsi, pour appeler le service, il faudra d'abord passer le portail d'authentification, en fournissant un identifiant d'application et le mot de passe qui va avec. Le serveur renverra un jeton d'authentification. Quand on appellera l'URL du service, il sera donc nécessaire de fournir l'identifiant de l'application et le jeton (valable une seule fois et 10 minutes maximum dans mon cas). Voici un exemple d'appel pour lire les SMS à envoyer. Attention ! Cette action récupère les SMS puis les supprime de la file d'attente pour ne pas encombrer la mémoire, et éviter de renvoyer des SMS en boucle :

https://sms.monsite.fr/auth.php?app_key=xxxxxxxxx&app_secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx → Si ça a fonctionné, le jeton est renvoyé (dans une sérialisation JSON)

https://sms.monsite.fr/read.php?app_key=xxxxxxxxx&token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx → Si l'authentification est valide, la liste de tous les SMS sont renvoyés

Voici un autre exemple, cette fois-ci pour enregistrer l'envoi d'un SMS dans la file d'attente :

https://sms.monsite.fr/auth.php?app_key=xxxxxxxxx&app_secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx → Si ça a fonctionné, le jeton est renvoyé (dans une sérialisation JSON)

https://sms.monsite.fr/sms.php?app_key=xxxxxxxxx&token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&smsdata=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx → Si l'authentification est valide, on enregistre le SMS. Note : smsdata correspond au SMS sérialisé en JSON et encodé en base64. Du côté du RasPi, il vous faudra donc le décoder et le désérialiser pour le traîter.

L'utilisation de l'API n'est pas plus compliquée que ça. Pour pouvoir vous en servir directement je vous ai mis les sources sur Github. Il y a, en plus, un petit script shell qui vous permettra d'enregistrer votre application auprès du serveur (afin de pouvoir obtenir les jetons par la suite, ce script vous renverra votre identifiant et votre mot de passe).

Quelques mots à propos des sources serveur. Voici ce que vous trouverez dans le dépôt GitHub :

  • index.php : Petit script PHP que vous appellerez depuis votre navigateur pour tester les SMS, et uniquement pour les tests (je vous conseille de le supprimer ensuite). Il fonctionne en appelant l'URL https://sms.monsite.fr/index.php?action=queue pour envoyer un SMS. Il est possible de remplacer queue par unqueue pour récupérer la liste des SMS qui sont à envoyer. Attention ! si vous appelez l'action unqueue, les SMS seront effacés de la liste des SMS à envoyer. À vous de remplacer les bonnes variables, je vous laisse un peu de déchiffrage de PHP pour ce script-là :)
  • auth.php : Script d'authentification à appeler avant tout appel aux autres scripts (à l'exception d'index.php)
  • read.php : Script pour récupérer la liste complète des SMS
  • sms.php : Script pour enregistrer un SMS dans la file d'attente
  • sh/create_app.php : En appelant ce script depuis la ligne de commande de votre serveur (php create_app.php), une application avec les identifiants sera créée. Ce sont ces identifiants que vous utiliserez pour récupérer le jeton. Il vous sera possible de créer plusieurs applications avec ça. Note : le répertoire sh est protégé par un .htaccess qui interdit toute requête depuis l'extérieur.
  • data/ : Un peu à la manière de SQLite, j'enregistre mes données dans ce répertoire, protégé lui aussi par un .htaccess. Il contient les identifiants d'applications, les jetons d'authentification en cours de validité et les SMS à envoyer. Ces fichiers sont formatés en JSON, et il est déconseillé d'y toucher à la main.
  • inc/ : Le répertoire inc contient toutes les classes utilisées dans l'application. La classe Curl a été trouvée sur Github.

Ce tuto est terminé ! Et à l'heure où je l'écris, un article NextINpact vient tout juste de parraître à propos de Free. Cette fonctionnalité m'aurait bien facilité la vie ! Cependant, dans mon cas, je souhaitais pouvoir envoyer les SMS vers mon téléphone personnel, et non vers la ligne Free. À vous de voir selon vos besoins.

J'ai évoqué rapidement la domotique. Je n'ai pas encore trop approché ce domaine avec un RasPi, mais de nombreux tutos existent sur le web vous montrant comment contrôler l'état de votre maison avec un RasPi. En combinant avec l'envoi de SMS, on pourrait imaginer un système de détection d'ouverture de porte, par exemple. Je vous ai également dit que la clef GSM utilise deux ports USB (dont un virtuel) à elle toute seule. Le deuxième port USB ne peut pas communiquer avec des commandes AT. Il est simplement là pour informer de l'arrivée de différents événements, tel que l'arrivée d'un SMS, un appel entrant, etc. En exploitant cette partie, vous pouvez tout aussi bien envoyer un SMS à votre RasPi demandant l'état de votre maison à un instant T, il vous répondra par un autre SMS que vous avez laissé la lumière allumée… vous pourriez aussi bien contrôler vos radiateurs, vos volets roulants, et bien d'autres choses ! Quand je vous disais que les possibilités sont infinies !

Rédigé le .

Commentaires

comments powered by Disqus