Article original : How to Build a WhatsApp Dictionary Chatbot using Twilio, FastAPI, and MongoDB

Parfois, vous voulez vérifier la signification d'un mot tout en discutant avec quelqu'un sur WhatsApp. Mais vous ne voulez pas quitter ou minimiser l'application.

Et si vous construisiez un bot WhatsApp qui peut vous donner la signification des mots que vous voulez connaître ?

Dans ce tutoriel, vous apprendrez à créer un chatbot qui peut servir de dictionnaire. Il sera facilement accessible sur WhatsApp en utilisant l'API Twilio MessagingX WhatsApp pour envoyer et recevoir des messages. Nous utiliserons Fast API pour créer le serveur web et interagir avec la base de données, et MongoDB pour stocker les mots et leurs significations dans une base de données.

À la fin de ce tutoriel, vous aurez développé un chatbot fonctionnel qui peut définir des mots en temps réel pendant que vous conversez sur WhatsApp.

Prérequis

  • Python 3.9+ installé sur votre machine.

  • Compte MongoDB gratuit – si vous n'en avez pas, vous pouvez en créer un ici.

  • Compte Twilio gratuit – vous pouvez en créer un ici.

  • Compte développeur Merriam-Webster – vous pouvez en créer un ici.

  • Un IDE ou éditeur de texte, tel que VS code.

Configurer votre environnement de développement

Avant de commencer, vous devez configurer votre environnement de développement en créant le répertoire et les fichiers nécessaires. Voici les commandes pour cela :

mkdir whatsappDictionary
cd whatsappDictionary
touch requirements.txt models.py utils.py main.py .env
  • requirements.txt contient les bibliothèques nécessaires pour faire fonctionner le chatbot.

  • model.py contient le code connectant votre chatbot au serveur MongoDB.

  • utils.py inclut le code pour se connecter à l'API Twilio MessagingX WhatsApp.

  • main.py contient le code pour construire le serveur Fast API et se connecter à l'API Merriam-Webster.

  • whatsappDictionary est le répertoire pour tous les fichiers.

Ensuite, vous allez créer et activer un environnement virtuel et mettre à jour le gestionnaire de paquets Python pip vers la version la plus récente en utilisant la commande suivante :

python -m venv venv; ./venv/Scripts/Activate; pip --upgrade pip

Si vous êtes sur une machine Linux, utilisez cette commande :

pyton -m venv venv; venv\\Scripts\\activate.bat; pip --upgrade pip

Pour en savoir plus sur les environnements virtuels et leurs avantages, vous pouvez lire ce tutoriel.

Ensuite, vous devrez remplir le fichier requirements.txt avec les dépendances suivantes :

fastapi
uvicorn
twilio
pymongo
pyngrok
requests
dotenv
  • fastapi est un framework Python pour construire des API rapidement et facilement.

  • uvicorn est une implémentation de serveur ultra-rapide pour Python.

  • twilio vous permet d'interagir avec l'API Twilio MessagingX WhatsApp.

  • pymongo est le pilote que vous utiliserez pour vous connecter au serveur MongoDB.

  • pyngrok vous permet de tunneler un serveur local vers une URL publique.

  • requests permet d'envoyer des requêtes HTTP en utilisant Python.

  • dotenv charge les variables d'environnement à partir du fichier .env.

Installez ces dépendances en exécutant la commande suivante dans votre terminal :

pip install -r requirements.txt

Configurer la base de données

Vous souhaitez maintenant configurer une base de données pour stocker les mots et leurs définitions. Vous allez utiliser MongoDB, qui est un langage NoSQL et est facile à configurer.

Vous devrez créer un compte gratuit sur le site MongoDB (si vous n'en avez pas déjà un). Une fois que vous avez un compte, connectez-vous pour créer un nouveau cluster Shared et une base de données.

Cette image montre comment créer un cluster partagé sur MongoDB

Image montrant comment créer un cluster partagé sur Mongo DB

Ensuite, allez dans Security_,_, puis ADD NEW DATABASE USER pour ajouter un nouvel utilisateur avec un accès en lecture/écriture à la base de données.

Cette image montre l'onglet où vous pouvez ajouter une nouvelle base de données

Cette image montre l'onglet où vous pouvez ajouter une nouvelle base de données

Cette image montre la fenêtre d'ajout d'un nouvel utilisateur de base de données

Cette image montre la fenêtre d'ajout d'un nouvel utilisateur de base de données

Retournez au tableau de bord du cluster, cliquez sur Connect puis sur Drivers.

Cette image montre le processus final lors de la tentative de connexion au cluster

Cette image montre le processus final lors de la tentative de connexion au cluster

Copiez le code affiché et collez-le dans model.py :

Cette image montre le code sur la façon de se connecter au serveur MongoDB en utilisant le pilote pymongo.

Cette image montre le code sur la façon de se connecter au serveur MongoDB en utilisant le pilote pymongo.

from pymongo.mongo_client import MongoClient
from pymongo.server_api import ServerApi

uri = f"mongodb+srv://adejumoridwan:<password>@cluster0.d9jr4ev.mongodb.net/?retryWrites=true&w=majority"

# Envoyer un ping pour confirmer une connexion réussie
try:
    client.admin.command('ping')
    print("Pinged your deployment. You successfully connected to MongoDB!")
except Exception as e:
    print(e)

Donnez votre mot de passe pour exécuter le code et vous connecter au serveur MongoDB. Vous ne voulez pas que quelqu'un voie cela. Allez dans le fichier .env que vous avez créé et stockez votre mot de passe là-bas.

MONGO_SECRET=<password>

Ensuite, mettez à jour model.py pour accéder au fichier .env.

from pymongo.mongo_client import MongoClient
from pymongo.server_api import ServerApi
from dotenv import load_dotenv
import os

load_dotenv()
password = os.environ.get('MONGO_SECRET')

uri = f"mongodb+srv://adejumoridwan:{password}@cluster0.d9jr4ev.mongodb.net/?retryWrites=true&w=majority"

# Envoyer un ping pour confirmer une connexion réussie
try:
    client.admin.command('ping')
    print("Pinged your deployment. You successfully connected to MongoDB!")
except Exception as e:
    print(e)
  • load_dotenv() charge les variables dans .env

  • os.environ.get('MONGO_SECRET') reçoit le mot de passe de .env, qui stocke la variable mot de passe

Exécutez le script pour vous connecter au serveur MongoDB. Vous pouvez créer une collection en cliquant sur le nom de votre cluster et en allant dans Collections. Les collections sont des versions NoSQL des tables SQL.

Cliquez sur Create Database pour créer votre base de données :

Cela montre des informations et des onglets concernant les clusters créés tels que Overview, Collections et ainsi de suite

Cela montre des informations et des onglets concernant les clusters créés tels que Overview, Collections et ainsi de suite

Donnez les noms de la base de données et de la collection. Les noms de la base de données et de la collection pour ce tutoriel sont MY_DB et dictionary, respectivement.

La fenêtre montre les options à remplir lorsque vous voulez créer une base de données, comme un nom de base de données, un nom de collection et des préférences supplémentaires.

La fenêtre montre les options à remplir lorsque vous voulez créer une base de données, comme un nom de base de données, un nom de collection et des préférences supplémentaires.

Allez dans models.py et mettez à jour le code pour créer un nouveau client et vous connecter au serveur.

from pymongo.mongo_client import MongoClient
from pymongo.server_api import ServerApi
from dotenv import load_dotenv
import os

load_dotenv()
password = os.environ.get('MONGO_SECRET')

uri = f"mongodb+srv://adejumoridwan:{password}@cluster0.d9jr4ev.mongodb.net/?retryWrites=true&w=majority"

# Créer un nouveau client et se connecter au serveur
client = MongoClient(uri, server_api=ServerApi('1'))

dictionary_collection = client["MY_DB"]["dictionary"]

# Envoyer un ping pour confirmer une connexion réussie
try:
    client.admin.command('ping')
    print("Pinged your deployment. You successfully connected to MongoDB!")
except Exception as e:
    print(e)

dictionary_collection est ce que vous utiliserez pour mettre à jour les entrées dans le serveur plus tard.

Comment configurer Twilio Sandbox pour WhatsApp

Pour configurer le bac à sable Twilio pour WhatsApp, allez dans la console Twilio. Sous Develop, cliquez sur Messaging, puis sur Try it out. Sous Try it out, cliquez sur Send a WhatsApp Message.

Ce bac à sable vous permet d'envoyer des messages WhatsApp à votre numéro

Ce bac à sable vous permet d'envoyer des messages WhatsApp à votre numéro

Pour vous connecter au bac à sable WhatsApp, enregistrez le numéro fourni sur le bac à sable sur votre appareil et envoyez le message join manner-free au numéro, ou vous pouvez scanner le code QR sur votre appareil.

Ici, vous voyez le bac à sable pour connecter le bac à sable WhatsApp à votre numéro

Ici, vous voyez le bac à sable pour connecter le bac à sable WhatsApp à votre numéro

Une fois la connexion réussie, copiez le code et collez-le dans le fichier utils.py :

Ici, vous pouvez voir comment vous connecter à l'API WhatsApp dans divers langages. Actuellement, l'image montre comment se connecter à l'API WhatsApp afin que vous puissiez envoyer des messages depuis Twilio.

Ici, vous pouvez voir comment vous connecter à l'API WhatsApp dans divers langages. Actuellement, l'image montre comment se connecter à l'API WhatsApp afin que vous puissiez envoyer des messages depuis Twilio.

from twilio.rest import Client

account_sid = '<account_sid>'
auth_token = '[AuthToken]'
client = Client(account_sid, auth_token)

message = client.messages.create(
  from_='whatsapp:+14155238886',
  body='Your appointment is coming up on July 21 at 3PM',
  to='whatsapp:<to_number>
)

print(message.sid)

La fonction client.messages.create() vous permet d'envoyer des messages à votre WhatsApp depuis le bac à sable WhatsApp. Elle prend trois paramètres :

  • from_ est l'endroit d'où provient le message, c'est-à-dire depuis le bac à sable WhatsApp

  • body prend le corps de votre message

  • to est le numéro WhatsApp auquel vous envoyez le message

Comment se connecter à l'API Twilio

Allez dans le fichier .env pour stocker votre jeton d'authentification Twilio, l'ID de compte, le numéro de bac à sable Twilio et le numéro WhatsApp.

MONGO_SECRET="<password>"
TWILIO_ACCOUNT_SID="<account_sid>"
TWILIO_AUTH_TOKEN="<auth_token>"
TWILIO_NUMBER="<twilio_number>"
TO_NUMBER="<to_number>"

Mettez à jour le fichier utils.py pour accéder à ces variables :

from twilio.rest import Client
from dotenv import load_dotenv
import os

load_dotenv()

account_sid = os.getenv("TWILIO_ACCOUNT_SID")
auth_token = os.getenv("TWILIO_AUTH_TOKEN")
client = Client(account_sid, auth_token)
twilio_number = os.getenv('TWILIO_NUMBER')
to_number = os.getenv("TO_NUMBER")

message = client.messages.create(
  from_=f'whatsapp:{twilio_number}',
  body='Your appointment is coming up on July 21 at 3PM',
  to=f'whatsapp:{to_number}
)

load_dotenv() charge les variables d'environnement, et os.getenv obtient ces variables à partir de l'environnement.

Ensuite, définissez une fonction send_message. Cette fonction aura deux arguments : to_number et text. La fonction enverra un message défini dans text à to_number.

from twilio.rest import Client
from dotenv import load_dotenv
import os

load_dotenv()

account_sid = os.getenv("TWILIO_ACCOUNT_SID")
auth_token = os.getenv("TWILIO_AUTH_TOKEN")
client = Client(account_sid, auth_token)
twilio_number = os.getenv('TWILIO_NUMBER')

def send_message(to_number, text):
      message = client.messages.create(
          from_=f"whatsapp:{twilio_number}",
          body=text,
          to=f"whatsapp:{to_number}"
          )

Mettez à jour la fonction send_message pour configurer la journalisation en cas d'erreurs rencontrées lors de l'envoi de messages.

import logging
from dotenv import load_dotenv
import os
from twilio.rest import Client

load_dotenv()

account_sid = os.getenv("TWILIO_ACCOUNT_SID")
auth_token = os.getenv("TWILIO_AUTH_TOKEN")
client = Client(account_sid, auth_token)
twilio_number = os.getenv('TWILIO_NUMBER')

# Configurer la journalisation
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Logique d'envoi de message via l'API de messagerie Twilio
def send_message(to_number, text):
    try:
        message = client.messages.create(
            from_=f"whatsapp:{twilio_number}",
            body=text,
            to=f"whatsapp:{to_number}"
            )
        logger.info(f"Message envoyé à {to_number}: {message.body}")
    except Exception as e:
        logger.error(f"Erreur lors de l'envoi du message à {to_number}: {e}")

Comment construire le backend FastAPI

Dans le fichier main.py, configurez une application FastAPI basique.

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def index():
    return {"message": "I love FreeCodeCamp"}

Le code ci-dessous configure un backend FastAPI basique, créant une nouvelle instance de la classe FastAPI et l'assignant à la variable app.

Le décorateur @app.get crée un nouveau point de terminaison que vous pouvez accéder avec une requête HTTP GET. Le point de terminaison est à l'URL racine / et retourne une réponse JSON avec une seule paire clé-valeur : "message": "I love FreeCodeCamp".

Pour exécuter l'application, exécutez la commande suivante dans votre terminal :

uvicorn main:app --reload

Sur votre navigateur, ouvrez l'hôte http://127.0.0.1:8000. Vous verrez une réponse JSON de {"message": "I love FreeCodeCamp"}. Vous pouvez également accéder à une documentation API interactive fournie par swagger sur l'hôte http://127.0.0.1:8000/doc qui vous permet d'interagir avec votre API et de voir si vous avez des erreurs.

Cette documentation interactive fournie par swagger montre comment interagir avec votre API pour vérifier les erreurs.

Cette documentation interactive fournie par swagger montre comment interagir avec votre API pour vérifier les erreurs.

Comment configurer ngrok

Pour recevoir des messages Twilio sur le backend, vous utiliserez ngrok pour héberger l'hôte local sur un serveur public. Lisez cet article pour apprendre comment configurer ngrok sur votre machine.

Sur l'administrateur ngrok, exécutez la commande ngrok http 8000. Cela rend votre hôte public, et vous pouvez recevoir des messages sur votre backend.

Ici, vous pouvez voir ngrok en cours d'exécution sur votre machine locale

Ici, vous pouvez voir ngrok en cours d'exécution sur votre machine locale

Allez dans votre bac à sable WhatsApp, sous les paramètres du bac à sable, et collez l'URL de transfert https://b5a6-105-112-120-51.ngrok-free.app en y ajoutant /message sous When a message comes in et cliquez sur Save.

Cette image montre comment configurer votre bac à sable et le lier à l'URL ngrok

Cette image montre comment configurer votre bac à sable et le lier à l'URL ngrok

Comment se connecter à l'API Merriam-Webster

Pour configurer un compte de dictionnaire Merriam-Webster, allez ici et remplissez vos informations d'identification :

Image montrant la page pour s'inscrire au Merriam Webster Developer Center

Image montrant la page pour s'inscrire au Merriam Webster Developer Center

Vous pouvez vous inscrire pour deux clés : Collegiate Dictionary et Collegiate Thesaurus, bien que ce tutoriel utilise uniquement Collegiate Dictionary.

Cela montre les différentes clés que l'on peut demander sur Merriam-Webster

Cela montre les différentes clés que l'on peut demander sur Merriam-Webster

Après avoir rempli tous vos détails, cliquez sur Register et Login.

Dans l'onglet home, allez dans Keys pour obtenir vos clés API.

Cet onglet de clé montre les clés que vous avez enregistrées

Cet onglet de clé montre les clés que vous avez enregistrées

Mettez à jour le fichier .env, en enregistrant la clé comme DICTIONARY_KEY.

MONGO_SECRET="<password>"
TWILIO_ACCOUNT_SID="<account_sid>"
TWILIO_AUTH_TOKEN="<auth_token>"
TWILIO_NUMBER="<twilio_number>"
TO_NUMBER="<to_number>"
DICTIONARY_API_KEY="<dictionary_key>"

Mettez à jour le fichier main.py comme suit :

from fastapi import FastAPI, Form
import requests
from utils import send_message
from dotenv import load_dotenv
import os
from typing import List

load_dotenv()

app = FastAPI()
whatsapp_number = os.getenv("TO_NUMBER")
api_key = os.getenv("DICTIONARY_API_KEY")

@app.post("/message")
async def reply(Body: str = Form()):
    url = f"<https://www.dictionaryapi.com/api/v3/references/collegiate/json/{Body}?key={api_key}>"
    response = requests.get(url)
    # Extraire les données JSON de la réponse
    data = response.json()

    definition = data[0]["shortdef"][0]

    send_message(whatsapp_number, definition)

@app.post("/message") est un décorateur dans le framework fastAPI qui définit une route de requête POST vers l'URL /message. La fonction reply définie ci-dessus est appelée lorsqu'une requête POST est envoyée à cette URL.

La fonction reply prend un paramètre Body dans le corps de la requête, qui est le message envoyé au chatbot (le mot dont vous voulez obtenir la définition). Elle envoie ensuite une requête HTTP à l'API Merriam-Webster pour récupérer la signification du mot.

La variable url stocke le lien vers l'API Merriam-Webster, qui prend le Body et la api_key pour obtenir des détails concernant le mot fourni.

Vous pouvez faire des requêtes à partir de url en utilisant requests de la bibliothèque request et stocker request.get(url) dans la variable response.

Vous extrayez ensuite les données JSON de la réponse en utilisant response.json() et les stockez dans la variable data.

data[0]["shortdef"][0] vous permet d'accéder à la définition courte d'un mot stockée dans la variable definition.

send_message() prend la définition et l'envoie à whatsapp_number.

Ensuite, vous devrez gérer les situations où quelqu'un envoie une phrase au lieu d'un mot, ou un mot contenant des ponctuations ou des caractères. Mettez donc à jour main.py comme suit :

from fastapi import FastAPI, Form
import requests
from utils import send_message
from dotenv import load_dotenv
import os
from typing import List
from models import dictionary_collection

load_dotenv()

app = FastAPI()
whatsapp_number = os.getenv("TO_NUMBER")
api_key = os.getenv("DICTIONARY_API_KEY")

@app.post("/message")
async def reply(Body: str = Form()):
    url = f"<https://www.dictionaryapi.com/api/v3/references/collegiate/json/{Body}?key={api_key}>"
    flag="Please give a valid word"

    if Body.isalpha():
        response = requests.get(url)
        # Extraire les données JSON de la réponse
        data = response.json()

        definition = data[0]["shortdef"][0]

        send_message(whatsapp_number, definition)
    else:
        return send_message(whatsapp_number, flag)

    return ""

flag est une variable stockant le message à donner si vous fournissez une phrase ou un mot avec des caractères.

La condition if vérifie si un message est un mot via Body.isaplha(), si vrai, il obtient la définition de l'API Merriam-Webster, si faux, il retourne la fonction send_message() disant à l'utilisateur de Please give a valid word.

Pour stocker les mots et leurs significations dans la base de données MongoDB, mettez à jour main.py comme suit :

from fastapi import FastAPI, Form
import requests
from utils import send_message
from dotenv import load_dotenv
import os
from typing import List
from models import dictionary_collection

load_dotenv()

app = FastAPI()
whatsapp_number = os.getenv("TO_NUMBER")
api_key = os.getenv("DICTIONARY_API_KEY")

@app.post("/message")
async def reply(Body: str = Form()):
    url = f"<https://www.dictionaryapi.com/api/v3/references/collegiate/json/{Body}?key={api_key}>"
    flag="Please give a valid word"

    if Body.isalpha():
        response = requests.get(url)
        # Extraire les données JSON de la réponse
        data = response.json()

        definition = data[0]["shortdef"][0]

        send_message(whatsapp_number, definition)

        dictionary_db = {"word":Body, "definition":definition}
        dictionary_collection.insert_one(dictionary_db)

    else:
        return send_message(whatsapp_number, flag)

    return ""

dictionary_db = {"word": Body, "definition": definition} crée un dictionnaire avec deux clés, word et definition, et les valeurs Body et definition, respectivement.

dictionary_collection.insert_one(dictionary_db) insère le dictionnaire dans la collection MongoDB, nommée dictionary_collection.

Vous pouvez aller sur votre tableau de bord et voir les éléments ajoutés à la collection.

Cela contient les éléments qui ont été envoyés et reçus sur votre application

Cela contient les éléments qui ont été envoyés et reçus sur votre application

Tester le ChatBot

Maintenant, vous pouvez discuter avec le chatbot et demander des définitions de mots :

Image montrant une discussion avec le chatbot dictionnaire

Image montrant une discussion avec le chatbot dictionnaire

Conclusion

Dans ce tutoriel, vous avez appris à créer un chatbot dictionnaire WhatsApp. Vous avez appris à utiliser FastAPI pour alimenter le backend de votre application, à interagir avec l'API Twilio MessagingX WhatsApp, et à utiliser une base de données NoSQL comme MongoDB pour stocker vos données.

Vous pouvez étendre le chatbot pour obtenir des synonymes et des définitions de mots avec plus d'une explication en accédant à plus de métadonnées de l'API Merriam-Webster.

Vous pouvez consulter la documentation de l'API Merriam-Webster pour les différentes réponses que vous pouvez obtenir. Assurez-vous de lire la documentation de l'API Twilio WhatsApp pour des fonctionnalités plus avancées comme l'obtention de réponses multimédias et la prononciation des mots.