Envoyer des SMS depuis un projet Django

Letter Carrier Delivering Mail

Dans la plupart des projets Web, contacter les utilisateurs par email est largement suffisant. Mais il arrive que l'on souhaite utiliser d'autres modes d'interaction, tels que le sms. Comparé au mail, le sms présente certains avantages :

  • il est plus facile de créer un compte email bidon qu'un faux numéro de mobile ;
  • le sms est instantané ;
  • le sms est quasi-impossible à manquer.

Évidemment, tout le monde est bien conscient que c'est un média de communication qui présente également des inconvéniants :

  • l'envoi de sms est plus intrusif, et donc potentiellement plus dérangeant ;
  • f**k you! I won't give you my phone number.

Dans ce rapide tutoriel, nous allons voir quels sont les moyens à notre disposition pour envoyer des sms depuis un projet Django.

Choisir le bon fournisseur

Pour des projets de moindre envergure, on pourrait sans doute imaginer bricoler une petite application qui envoie des sms depuis son propre mobile. Mais si l'on veut vraiment quelque chose de fiable et propre, alors il va falloir passer par un provider dédié qui mettra à notre disposition une chouette API.

Même si la première méthode permettrait sans doute d'économiser quelques euros, elle n'est pas fiable sur le long terme. Le gros problèmes des sms, c'est qu'en France, ça douille sévère. Nos chers opérateurs facturent encore à prix d'or la transition de ces quelques octets par leurs réseaux, et les prix s'en ressentent.

Alors qu'aujourd'hui la plupart des forfaits mobiles personnels proposent l'envoi de sms illimités, les tarifs pratiqués pour un usage pro sont plutôt… décourageants. Tenez, prenons l'exemple du pack sms proposé par OVH. 8cts HT le sms, soit presque 10 centimes TTC. 10 p**ain de centimes ! C'est une blague ? Heureusement, la commande en gros volume permet d'avoir des réductions jusqu'à 20%, mais pour atteindre ce niveau, il faut en commander… 1 million, soit 64000€ HT, et ça laisse le sms à plus de 6 centimes. Gloups !

Après avoir cherché et testé quelques passerelles Web / Sms, je suis tombé sur Nexmo, qui fait du sms son cœur de métier, et qui pratique les tarifs les moins exhorbitants.

Outre le fait que ce sont les tarifs les moins inintéressants que j'ai pu trouver, leur service est plutôt simple et agréable à utiliser. Pas besoin de remplir des formulaires à n'en plus finir pour commencer à envoyer des sms ; il suffit de créer un compte, de récupérer votre clé d'identification pour l'API, et vous êtes paré. Nexmo vous offre même quelques crédits pour commencer à tester l'envoi de sms sans avoir à sortir tout de suite votre carte-bleue. Enfin, le service fonctionne par compte pré-payé, et aucun volume d'achat n'est imposé.

L'API proposée est trés simple à utiliser, et des librairies sont disponibles dans la plupart des langages courants.

Une alternative est Twilio, qui propose une palette de services plus étendue, mais des tarifs moins intéressants vers les mobiles français.

Intégrer Nexmo dans Django

Une intégration basique dans Django est relativement simple, puisqu'il ne s'agit que d'appels à une API rest.

Il existe déjà une librairie Python qui permet de communiquer directement avec l'API Nexmo. Votre serviteur, quand à lui, vient de publier django-nexmo, une petite appli Django qui ne fait rien d'autre qu'intégrer la lib susmentionnée et faciliter son installation.

Ainsi, après l'installation et avoir ajouté quelques paramètres dans les settings, l'envoi de SMS depuis un projet Django se fera de manière simplissime :

from nexmo import send_message
send_message('+33612345678', 'My sms message body')

Vous vous attendiez à plus complexe ? Désolé de vous décevoir !

Gérer les accusés de réception

L'appel à l'API retourne un résultat immédiatement. Toutefois, Nexmo peut avoir besoin de communiquer après coup avec votre application, par exemple pour vous retourner un accusé de réception, ou indiquer un échec après plusieurs tentatives d'envois.

Cet échange passe par la mise en place d'une url de callback côté Django. Tout ce que vous avez à faire, c'est créer une nouvelle vue qui récupère (ou pas) les différents paramètres passés par Nexmo, et à retourner une réponse vide. Voici l'exemple de django-nexmo :

import logging

from django.http import HttpResponse

from .error_messages import (NEXMO_STATUSES, UNKNOWN_STATUS,
                             NEXMO_MESSAGES, UNKNOWN_MESSAGE)


logger = logging.getLogger(__name__)


def callback(request):
    """Callback URL for Nexmo."""
    message_id = request.GET.get('messageId')
    status_id = request.GET.get('status')
    status_msg = NEXMO_STATUSES.get(status_id, UNKNOWN_STATUS)
    error_id = int(request.GET.get('err-code'))
    error_msg = NEXMO_MESSAGES.get(error_id, UNKNOWN_MESSAGE)

    logger.info(u'Nexmo callback: Sms = %s, Status = %s, message = %s' % (
        message_id,
        status_msg,
        error_msg
    ))

    # Nexmo expects a 200 response code
    return HttpResponse('')

Il vous suffit de déclarer cette url dans les paramètres de votre compte Nexmo, et voilà.

Pour conclure

Tout ça pour dire qu'envoyer des sms vers des mobiles français est relativement simple, à condition d'avoir des ronds. Sur cette sage conclusion, je vous laisse à vos oignons.