Un système de notification par SMS

Publié le 2025-06-06 par DarkChyper

Ce week-end, j’ai découvert une option bien pratique grâce à un contact : Free Mobile propose un service gratuit de notifications par SMS inclus avec ses abonnements. Ce service vous permet de vous envoyer des SMS depuis vos scripts ou applications, idéal pour être alerté d’un événement système ou recevoir un rapport automatique.

Si vous êtes abonné Free Mobile, l’activation se fait via l’espace abonné (depuis un navigateur, pas l’application mobile) : Mon forfait Mobile > Mes options > Notifications par SMS.

Une fois activé, une clé d’API privée est générée.

⚠️ Ne la partagez avec personne, elle donne un accès direct à l’envoi de SMS vers votre ligne.

Activation de l'option sur le site de free

Sur le site, vous trouverez toutes les explications pour utiliser cette API de notifications, et cela m'a donné pas mal d'idées d'utilisation (eux parlent de NAS ou de systèmes d'alarme). Je vais intégrer ces notifications à mes différents scripts et notamment à GoKeep.

Live blog coding et amusement en golang


Fonctionnement de l'API de Free

Pour envoyer un SMS avec le système de notification, il suffit de faire une requete POST ou GET à cette adresse

https://smsapi.free-mobile.fr/sendmsg

Avec les paramètres suivants:

Enfin, je n'ai jamais réussi à utiliser POST, je ne sais pas si la documentation est à jour.

Par exemple : https://smsapi.free-mobile.fr/sendmsg?user=12345689&pass=KeyANePAsPArtager&msg=Hello%20World%20!

Dans tous les cas, on profite des codes retours HTTP pour comprendre ce qui s'est passé :


NotiFreeMe

Pour simplifier l’intégration dans mes projets, j’ai commencé à écrire NotiFreeMe, une petite bibliothèque en Go. Elle permet d’envoyer facilement des SMS via l’API Free sans avoir à réécrire tout à chaque fois.

Golang est particulièrement adapté à ce genre de projet : rapide, statique, déployable en un binaire. Et comme souvent : un besoin + une bonne excuse = un projet 😄

Commençons avec un code minimaliste.

 GO

package main import ( "fmt" "net/http" "net/url" ) func sendNotifree(user string, pass string, message string) error { apiURL := "https://smsapi.free-mobile.fr/sendmsg" params := url.Values{} params.Add("user", user) params.Add("pass", pass) params.Add("msg", message) resp, err := http.Get(apiURL + "?" + params.Encode()) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != 200 { return fmt.Errorf("échec de l'envoi SMS: HTTP %d", resp.StatusCode) } return nil } func main() { user := "NUMERO_CLIENT" pass := "CLEF_API" message := "[NotiFreeMe] Hello, World !" err := sendNotifree(user, pass, message) if err != nil { fmt.Println("Erreur :", err) } else { fmt.Println("SMS envoyé avec succès !") } }

Ce code a le mérite de fonctionner, mais il est loin d’être réutilisable. Mon objectif est d’aller plus loin : je veux que NotiFreeMe puisse aussi bien être utilisé comme une dépendance dans d’autres outils en Go, que comme un exécutable indépendant, utilisable par n’importe quel script, quel que soit le langage. Encore une fois, la force de Go est de produire un exécutable autonome, sans dépendances.

J’ai avancé pas à pas vers cet objectif, en m’aidant de ChatGPT et du Chat de Mistral. Oui, j’utilise des LLM pour m’accompagner dans le développement de mes solutions et non, je n’en ai pas honte. J’en reparlerai un peu plus tard.

C'est ainsi que je suis arrivé à une première version stable et simple de NotiFreeMe, disponible sur Gitlab:

NotiFreeMe, une dépendance et un outil autonome pour envoyer des notifications SMS via Free Mobile.


Intégration dans GoKeep

Ce que j'aimerai améliorer dans GoKeep c'est l'ajout de notifications par SMS selon des événements :

Première étape, je code un truc simple : j'importe la dépendance NotiFreeMe, j'ajoute les champs user et pass à ma structure Settings, je crée le client et j'envoie les messages. Je teste en local avec succès, et je déploie rapidement en production.

 GO

import "gitlab.com/dark-open/notifreeme/notiFreeMe" type Settings struct { ApplicationKey string `json:"applicationKey"` ApplicationSecret string `json:"applicationSecret"` ConsumerKey string `json:"consumerKey"` Domains []Domain `json:"domains"` FreeUser string `json:freeUser` FreePass string `json:freePass` } func main() { [...] freeClient,errFree := notiFreeMe.NewClient(settings.FreeUser, settings.FreePass) if (nil == errFree) { err = freeClient.Send("[GoKeep] Nouvelle IP : " + currentIp) if nil != err { log.Println("Fail to send SMS") } } else { log.Println("Erreur lors de la création du client Free") } [...] }

C'est fonctionnel, mais ce code est loin d'être optimal :

Encore une fois, j'ai appliqué ces contraintes une à une à mon code en m'aidant des IA. Au final, j'ai un code plutôt lisible, qui utilise les goroutines et les channels pour paralléliser l’envoi des notifications.


Je connaissais ces concepts de Go de nom, mais je n’avais encore jamais eu l’occasion de les mettre en pratique. Et comme pour toutes les premières fois, cela fait un peu peur : on ne sait pas vraiment par où commencer. Avoir un coup de main (même d’une IA) pour appliquer ces notions sur un projet personnel me semble vraiment formateur. On n’a pas toujours la chance d’avoir un développeur senior sous la main pour nous aider.

Maintenant que je les ai abordés grâce à l’IA, est-ce que je maîtrise ces concepts ? Absolument pas. Mais j’ai désormais une base de code que je comprends parfaitement, et qui me permet de poursuivre leur apprentissage sereinement, en évitant de bloquer sur des "panic: deadlock" incompréhensibles dans la console.


Le système de notifications est désormais optionnel, en passant par un second fichier de configuration (.freecreds), et son initialisation est déclenchée très tôt dans l’exécution du programme. Cela rend le mécanisme totalement découplé : même si le fichier .freecreds est absent ou invalide, le reste du script continue de fonctionner normalement.

Enfin, ces améliorations m’ont permis d’initialiser la goroutine et le client SMS dès le démarrage, ce qui, combiné au caractère optionnel du système, permet à la fonction check() de tenter un envoi de SMS sans risque de crash.

Dépôt de GoKeep sur Gitlab

J’allais enchainer avec mon rapport aux IA (ou LLM… enfin vous voyez quoi). Mais en y réfléchissant, j’ai tellement de choses à dire sur le sujet, entre usage perso, pro, quotidien, et bidouilles en tout genre... impossible pour moi de résumer tout cela dans un seul pauvre petit paragraphe.

J'évite donc de faire une énorme digression du sujet principal et je vous invite à surveiller mon flux RSS pour ne pas rater la sortie de ce futur article. Stay tuned !