Construisez un chatbot WhatsApp avec Python, Flask et Twilio

November 20, 2019
Rédigé par

Construisez un chatbot WhatsApp avec Python, Flask et Twilio

Un chatbot est une application logicielle capable de mener une conversation avec un utilisateur humain par le biais d'un langage écrit ou parlé. Le niveau d'« intelligence » varie considérablement d'un chatbot à l'autre. Bien que certains chatbots aient une compréhension assez élémentaire du langage, d'autres utilisent des algorithmes d'Intelligence Artificielle (IA) et de Machine Learning (ML) sophistiqués afin d'atteindre un niveau de conversation presque humain.

Dans ce tutoriel, je vais vous montrer à quel point il est facile de construire un chatbot pour WhatsApp à l'aide de l'API Twilio pour WhatsApp et du framework Flask pour Python. Vous trouverez ci-dessous un exemple d'une interaction que j'aie eue avec ce chatbot :

Session de démonstration du chatbot WhatsApp

Configuration requise pour le tutoriel

Pour suivre ce tutoriel, vous avez besoin de ce qui suit :

  • Python 3.6 ou version ultérieure. Si votre système d'exploitation ne fournit pas d'interpréteur Python, vous pouvez vous rendre sur python.org pour le télécharger.
  • Flask. Nous allons créer une application web qui répond aux messages WhatsApp entrants.
  • ngrok. Nous utiliserons cet utilitaire pratique pour connecter l'application Flask exécutée sur votre système à une URL publique à laquelle Twilio peut se connecter. Cela est nécessaire pour la version de développement du chatbot, parce que votre ordinateur est probablement derrière un routeur ou un pare-feu, ce qui fait qu'il n'est pas directement accessible sur Internet. Si ngrok n'est pas installé, vous pouvez le télécharger pour Windows, MacOS ou Linux.
  • Un smartphone avec un numéro de téléphone actif sur lequel WhatsApp est installé.
  • Un compte Twilio. Si vous débutez sur Twilio, créez un compte gratuit maintenant. Vous pouvez consulter les fonctionnalités et limitations d'un compte Twilio gratuit.

Configurez la sandbox WhatsApp Twilio

Twilio fournit une sandbox WhatsApp dans laquelle vous pouvez facilement développer et tester votre application. Une fois votre application terminée, vous pouvez demander un accès de production pour votre numéro de téléphone Twilio, qui nécessite l'approbation de WhatsApp.

Connectez maintenant votre smartphone à la sandbox. Depuis votre Console Twilio, sélectionnez Programmable Messaging, puis cliquez sur « Try it Out » et enfin sur Try Whatsapp. La page de la sandbox WhatsApp affichera le numéro de sandbox attribué à votre compte, ainsi qu'un code joint.

Capture d'écran de l'installation de la sandbox WhatsApp

Pour activer la sandbox WhatsApp pour votre smartphone, envoyez un message WhatsApp avec le code indiqué au numéro attribué à votre compte. Le code commence par le mot join, suivi d'une expression de deux mots générée de façon aléatoire. Peu après avoir envoyé le message, vous devriez recevoir une réponse de Twilio indiquant que votre numéro de téléphone mobile est connecté à la sandbox et que vous pouvez commencer à envoyer et recevoir des messages.

Notez que cette étape doit être répétée pour tous les téléphones supplémentaires que vous souhaitez connecter à votre sandbox.

Création d'un environnement virtuel Python

Suivant les meilleures pratiques Python, nous allons créer un répertoire distinct pour notre projet de chatbot ; et à l'intérieur de celui-ci, un environnement virtuel. Nous allons ensuite installer les packages Python dont nous aurons besoin pour notre chatbot.

Si vous utilisez un système Unix ou Mac OS, ouvrez un terminal et saisissez les commandes suivantes pour effectuer les tâches décrites ci-dessus :

$ mkdir whatsapp-bot
$ cd whatsapp-bot
$ python3 -m venv whatsapp-bot-venv
$ source whatsapp-bot-venv/bin/activate
(whatsapp-bot-venv) $ pip install twilio flask requests

Pour ceux qui suivent le tutoriel sous Windows, entrez les commandes suivantes dans une fenêtre d'invite de commande :

$ mkdir whatsapp-bot
$ cd whatsapp-bot
$ python3 -m venv whatsapp-bot-venv
$ whatsapp-bot-venvScripts\activate
(whatsapp-bot-venv) $ pip install twilio flask requests

La dernière commande utilise ‘pip’, le programme d'installation du package Python, pour installer les trois packages que nous allons utiliser dans ce projet, qui sont :

À titre de référence, au moment de la publication de ce post, les versions des packages ci-dessus, et leurs dépendances testées, étaient les suivantes :

certifi==2019.9.11
chardet==3.0.4
Click==7.0
Flask==1.1.1
idna==2.8
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
PyJWT==1.7.1
pytz==2019.3
requests==2.22.0
six==1.13.0
twilio==6.33.1
urllib3==1.25.7
Werkzeug==0.16.0

Créer un service de chatbot Flask

C'est là qu'on va pouvoir commencer à s'amuser. Construisons un chatbot !

Le type de chatbot qui fonctionnera le mieux pour vous dépendra en grande partie de vos besoins spécifiques. Pour ce didacticiel, je vais construire un chatbot extrêmement simple qui reconnaît deux mots clés dans les messages envoyés par l'utilisateur et réagit à eux. Si l'utilisateur écrit un message contenant le mot « quote », alors le chatbot renverra une citation connue sélectionnée aléatoirement. Si, au lieu de cela, le message contient le mot « cat », alors une image de chat aléatoire sera renvoyée. Si « quote » et « cat » sont tous deux présents dans le message, alors le bot répondra avec une citation et une image de chat ensemble.

Le Webhook

L'API Twilio pour WhatsApp utilise un Webhook pour notifier une application lorsqu'il y a un message entrant. Notre application de chatbot doit définir un point de terminaison qui sera configuré comme ce Webhook afin que Twilio puisse communiquer avec lui.

Avec le framework Flask, il est extrêmement facile de définir un Webhook. Vous trouverez ci-dessous une application squelette définissant un Webhook. Ne vous souciez pas de copier ce code, je vais d'abord vous montrer toutes les différentes parties de l'implémentation, puis une fois que vous les aurez comprises, nous verrons comment toutes les combiner en une application qui fonctionne.

from flask import Flask

app = Flask(__name__)


@app.route('/bot', methods=['POST'])
def bot():
    # add webhook logic here and return a response


if __name__ == '__main__':
    app.run()

Si vous ne connaissez pas le framework Flask, sa documentation comporte une section de démarrage rapide qui devrait vous permettre d'être rapidement à l'aise. Pour une ressource d'apprentissage plus approfondie, je vous recommande de suivre mon Méga-Tutoriel Flask.

Ce qu'il faut garder à l'esprit à propos du code ci-dessus, c'est que l'application définit un point de terminaison /bot qui écoute les requêtes POST. Chaque fois qu'un message entrant provenant d'un utilisateur est reçu par Twilio, il appelle à son tour ce point de terminaison. Le corps de la fonction bot() va analyser le message envoyé par l'utilisateur et fournir la réponse appropriée.

Messages et réponses

La première chose que nous devons faire dans notre chatbot, c'est obtenir le message saisi par l'utilisateur. Ce message apparaît dans la charge utile de la requête POST avec une clé 'Body'. Nous pouvons y accéder via l'objet request de Flask :

from flask import request
incoming_msg = request.values.get('Body', '').lower()

Puisque nous allons effectuer une analyse de langage de base sur ce texte, j'ai également converti le texte en minuscules, de sorte que nous n'ayons pas à nous soucier de toutes les formes différentes sous lesquelles un mot peut apparaître lorsqu'on introduit des variations de casse.

La réponse que Twilio attend du Webhook doit être donnée en TwistML ou Twilio Markup Language, qui est un langage basé sur le XML. La Bibliothèque d'aide de Twilio pour Python est fournie avec des classes qui facilitent la création de cette réponse sans avoir « directement » à créer du XML. Vous trouverez ci-dessous comment créer une réponse qui inclut des composants texte et multimédia :

from twilio.twiml.messaging_response import MessagingResponse

resp = MessagingResponse()
msg = resp.message()
msg.body('this is the response text')
msg.media('https://example.com/path/image.jpg')

Voyez comment Twilio, pour renvoyer une image, attend une URL pointant directement vers elle plutôt que les données réelles de l'image.

Logique du chatbot

Pour la logique du chatbot elle-même, je vais utiliser une approche très simple, mais étonnamment efficace. Je vais en fait explorer les messages entrants à la recherche des mots-clés 'quote' et'cat'. Voici la structure de base du chatbot :

    responded = False
    if 'quote' in incoming_msg:
        # add a quote to the response here
        responded = True
    if 'cat' in incoming_msg:
        # add a cat picture to the response here
        responded = True
    if not responded:
        # return a generic response here

Grâce à cette structure simple, nous pouvons détecter les références aux citations et/ou aux chats et configurer l'objet de réponse de Twilio en conséquence. Le booléen responded est utile pour suivre les cas où le message n'inclut aucun des mots clés que nous recherchons, et offrir alors une réponse générique.

API tierces

Pour fournir au chatbot des citations originales et des images de chats, je vais utiliser deux API accessibles au grand public. Pour les citations célèbres, j'ai choisi l'API Quotable de Luke Peavey. Une requête GET vers https://api.quotable.io/random renvoie une citation aléatoire à partir d'un pool de 1 500 au format JSON.

Pour les images de chats, je vais utiliser l'API Cat as a Service de Kevin Balicot. Il s'agit d'une API extrêmement simple, l'URL https://cataas.com/cat renvoie à chaque fois une image de chat différente (vous pouvez la tester en collant cette URL dans la barre d'adresse du navigateur, puis en appuyant sur Actualiser pour obtenir une nouvelle image de chat). C'est en fait très pratique, car comme je l'ai mentionné ci-dessus, Twilio veut que l'image soit donnée sous la forme d'une URL lors de la préparation de la réponse TwilML.

Réunissons le tout

Maintenant que vous avez vu tous les aspects de la mise en œuvre du chatbot, nous sommes prêts à intégrer toutes les pièces afin d'obtenir le service de chatbot complet. Vous pouvez copier le code ci-dessous dans un fichier bot.py :

from flask import Flask, request
import requests
from twilio.twiml.messaging_response import MessagingResponse

app = Flask(__name__)


@app.route('/bot', methods=['POST'])
def bot():
    incoming_msg = request.values.get('Body', '').lower()
    resp = MessagingResponse()
    msg = resp.message()
    responded = False
    if 'quote' in incoming_msg:
        # return a quote
        r = requests.get('https://api.quotable.io/random')
        if r.status_code == 200:
            data = r.json()
            quote = f'{data["content"]} ({data["author"]})'
        else:
            quote = 'I could not retrieve a quote at this time, sorry.'
        msg.body(quote)
        responded = True
    if 'cat' in incoming_msg:
        # return a cat pic
        msg.media('https://cataas.com/cat')
        responded = True
    if not responded:
        msg.body('I only know about famous quotes and cats, sorry!')
    return str(resp)


if __name__ == '__main__':
    app.run()

Test du chatbot

Prêt à tester le chatbot ? Après avoir copié le code ci-dessus dans le fichier bot.py, démarrez le chatbot en exécutant python bot.py, et en vous assurant à ce moment-là que l'environnement virtuel Python est activé. La sortie devrait être similaire à celle-ci :

(whatsapp-bot-venv) $ python bot.py
 * Serving Flask app "bot" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Le service s'exécute maintenant en tant que service privé sur le port 5000 dans votre ordinateur, et restera là à attendre les connexions entrantes. Pour rendre ce service accessible depuis Internet, nous devons utiliser ngrok.

Ouvrez une seconde fenêtre de terminal et exécutez ngrok http 5000 pour allouer un domaine public temporaire redirigeant les requêtes HTTP vers notre port local 5000. Sur un ordinateur Unix ou Mac OS, vous devrez peut-être utiliser ./ngrok http 5000 si vous avez l'exécutable ngrok dans votre répertoire actuel. La sortie de ngrok devrait ressembler à peu près à :

capture d'écran ngrok

Notez les lignes commençant par « Forwarding ». Elles montrent l'URL publique que ngrok utilise pour rediriger les requêtes vers notre service. Ce que nous devons faire maintenant, c'est dire à Twilio d'utiliser cette URL pour envoyer des notifications de message entrant.

Revenez à la Console Twilio, cliquez sur Programmable Messaging, puis sur Settings, et enfin sur WhatsApp Sandbox Settings. Copiez l'URL https:// à partir de la sortie ngrok, puis collez-la dans le champ « When a message comes in ». Puisque notre chatbot est exposé sous l'URL /bot, ajoutez-la à la fin de l'URL ngrok racine. Assurez-vous que la méthode de requête est définie sur HTTP Post. N'oubliez pas de cliquer sur le bouton rouge « Save » au bas de la page pour enregistrer ces modifications.

Capture d'écran de configuration de la sandbox Twilio pour WhatsApp

Vous pouvez maintenant commencer à envoyer des messages au chatbot depuis le smartphone que vous avez connecté à la sandbox. Vous pouvez saisir toute phrase de votre choix, et à chaque fois que les mots « quote » et « cat » apparaîtront dans les messages, le chatbot appellera les API tierces et renverra un nouveau contenu. Au cas où vous l'auriez manqué en haut de l'article, voici un exemple de session que j'ai eue avec le chatbot :

Session de démonstration du chatbot WhatsApp

Gardez à l'esprit qu'utiliser ngrok gratuitement entraîne quelques limitations. Notamment, vous ne pouvez maintenir une URL ngrok pendant plus de 8 heures, et le nom de domaine qui vous est attribué sera différent chaque fois que vous lancerez la commande ngrok. Vous devrez mettre à jour l'URL dans la Console Twilio à chaque fois que vous relancerez ngrok.

Remarques sur le déploiement en production

J'ai pensé qu'il serait utile de terminer ce tutoriel par une liste de choses que vous devrez prendre en compte si vous décidez de déployer un chatbot WhatsApp pour une utilisation en production.

Tout d'abord, vous avez vu que lorsque vous démarrez l'application Flask, un message assez effrayant vous avertit de ne pas utiliser de serveur de développement dans le cadre d'une production. Le serveur web fourni avec Flask est très pratique lorsqu'on développe et teste une application, mais n'est pas assez robuste pour répondre aux exigences d'une utilisation en production. Les deux serveurs web prêts pour la production les plus courants pour les applications web Python sont gunicorn et uWSGI, tous deux installables sur votre environnement virtuel avec pip. Voici par exemple comment exécuter le chatbot avec gunicorn :

(whatsapp-bot-venv) $ gunicorn -b :5000 bot:app

Gardez également à l'esprit que pour un déploiement en production, vous exécuterez le service sur un serveur cloud et non sur votre propre ordinateur. Vous n'aurez donc pas à utiliser ngrok.

Conclusion

Les entreprises se tournent de plus en plus vers les chatbots pour offrir à leurs clients un accès immédiat à l'assistance, aux ventes ou au marketing. Un chatbot peut être utile pour recueillir des informations sur les clients avant qu'un agent humain ne soit impliqué, et un chatbot bien conçu devrait également pouvoir gérer des flux de travail courants relatifs aux clients, sans aucune assistance humaine.

J'espère que ce tutoriel vous aura été utile et que vous avez maintenant une meilleure idée de comment construire votre chatbot WhatsApp. Ci-dessous figurent des ressources supplémentaires sur la création de chatbots avec Python, au cas où vous souhaiteriez voir d'autres implémentations :

J'adorerais voir le chatbot que vous construisez !