Building a Dialogflow Chatbot with Webhook Integration for FastAPI and MongoDB

Hanish
6 min readJul 4, 2023

Introduction:
In order to provide automated support and enhance user experiences, chatbots have grown in popularity. We will examine how to use webhooks to create a Dialogflow chatbot that is integrated with the FastAPI in this lesson. We will concentrate on getting property information out of a MongoDB database and showing it in the chatbot interface. In the MongoDB database, we will also keep user data for later processing. You will have a fully functional chatbot capable of retrieving property information and obtaining user data at the end of this session.

Prerequisites: You need to have a basic understanding of Python, FastAPI, Dialogflow, and MongoDB to follow along with this lesson. Before continuing, ensure that you have these installed and configured.

Step 1: Setting up the Project
Let’s start by setting up our project environment. Open a terminal or command prompt and follow these steps

$ mkdir dialogflow-chatbot
$ cd dialogflow-chatbot
$ python3 -m venv venv
$ source venv/bin/activate # For Linux/Mac
$ .\venv\Scripts\activate # For Windows

Step 2: Installing Dependencies

Next, we need to install the required dependencies. Create a new file called requirements.txt in your project directory and add the following dependencies:

fastapi
pymongo
pydantic
uvicorn

Save the file and install the dependencies using pip:

$ pip install -r requirements.txt

Step 3: Setting up MongoDB Connection

To connect to our MongoDB database, open the main.py file in your favorite code editor and add the following code:

import logging
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from pymongo import MongoClient

# Connection URL and database name
client = MongoClient("mongodb_URL")
db = client["Database_name"]
property_collection = db["Collection_name"]
response_collection = db["Collection_name"]

# Define the request models
class PropertyRequest(BaseModel):
location: str

class ResponseRequest(BaseModel):
name: str
email: str
phone_number: str

# Create FastAPI application
app = FastAPI()

Step 4: Implementing the Dialogflow Webhook Integration

Let’s define the route and logic for handling Dialogflow’s webhook integration. Add the following code to main.py:

@app.post("/fulfillment")
async def fulfillment(request: Request):
# Get the JSON payload from the request
payload = await request.json()

# Extract the intent name
intent_name = payload["queryResult"]["intent"]["displayName"]

if intent_name == "Details":
# Retrieve user information from the payload
name = payload["queryResult"]["parameters"]["name"]
email = payload["queryResult"]["parameters"]["email"]
phone_number = payload["queryResult"]["parameters"]["phone_number"]

# Create a new response document
response_doc = {
"name": name,
"email": email,
"phone_number": phone_number
}

# Save the response document to the 'responses' collection
response_collection.insert_one(response_doc)

elif intent_name == "Yes":
# Retrieve location parameter from the payload
location = payload["queryResult"]["parameters"]["Location"]

# Create a query object to filter based on location
query = {"Location": location}

# Retrieve properties matching the location filter
result = property_collection.find(query)
properties_list = list(result)

# Prepare the response
fulfillment_messages = [
{
"payload": {
"richContent": [
[
{
"type": "image",
"rawUrl": property['Image'],
"accessibilityText": f"{property['Type_']} in {property['Location']}"
},
{
"type": "info",
"title": f"{property['Type_']} in {property['Location']}",
"subtitle": f"Price: {property['Price']}, Bedrooms: {property['Bed_Rooms']}, Bathrooms: {property['Bathrooms']}"
}
]
]
}
}
for property in properties_list
]

# Add a message before the properties
fulfillment_messages.insert(0, {
"text": {
"text": ["Here are your amazing properties✌️"]
}
})

response = {
"fulfillmentMessages": fulfillment_messages
}

return JSONResponse(content=response, headers={"Content-Type": "application/json"})

else:
logging.warning("Unsupported intent triggered")
return JSONResponse(content={"fulfillmentMessages": [{"text": {"text": ["This fulfillment is not triggered for the specified intent."]}}]}, headers={"Content-Type": "application/json"})

Step 5: Running the FastAPI App :

To run the FastAPI application, add the following code at the end of main.py:

if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)

Step 6: Deploying FastAPI App

Deploy the FastAPI app by running the following command in the terminal:

$ uvicorn main:app --reload

The application will start running at http://localhost:8000.

Step 7: Integrating with Dialogflow

  1. Open the Dialogflow console and navigate to your agent.
  2. Go to the “Fulfillment” section.
  3. Enable the “Webhook” option and enter the URL of your FastAPI application
  4. Save your changes

Step 8: Testing the Chatbot

  1. In the Dialogflow console, go to the “Test” section.
  2. Start a conversation with your chatbot and ask questions related to property details.
  3. The chatbot will retrieve property information from the MongoDB database and display it in the chat interface.
  4. If the user provides personal information, it will be stored in the MongoDB database for further processing.

Let’s go through the code step by step to understand its functionality:

  1. First, the necessary libraries and modules are imported:
  • logging is imported for logging purposes.
  • FastAPI is imported to create the FastAPI application.
  • Request is imported from fastapi to handle incoming requests.
  • JSONResponse is imported from fastapi.responses to create JSON responses.
  • BaseModel is imported from pydantic to define request models.
  • MongoClient is imported from pymongo to connect to MongoDB.

2. The MongoDB connection details are defined using MongoClient. Update this section with your own MongoDB connection URL and database details.

3. Two collections are defined:

  • The First collection represents the collection in the MongoDB database that stores property information.
  • The Second collection represents the collection in the MongoDB database that stores user responses.

4. Two request models are defined using BaseModel:

  • PropertyRequest represents the request model for retrieving property details based on location.
  • ResponseRequest represents the request model for storing user response information.

5. The FastAPI application is created using FastAPI().

6. The /fulfillment route is defined as a POST route that handles the fulfillment logic for Dialogflow webhook integration. It expects a Request object as input.

7. Inside the fulfillment route function:

  • The JSON payload from the request is extracted using await request.json().
  • The intent name is extracted from the payload to determine the appropriate fulfillment logic.

8. If the intent name is “Details”:

  • The user information (name, email, phone number) is retrieved from the payload.
  • A new response document is created with the user information.
  • The response document is inserted into the responses collection in the MongoDB database.

9. If the intent name is “Yes”:

  • The location parameter is retrieved from the payload.
  • A query object is created to filter properties based on the location.
  • Properties matching the location filter are retrieved from the properties collection in the MongoDB database.
  • The property details are prepared in the format expected by Dialogflow’s rich content response.
  • A fulfillment response is created with the property details and a message.
  • The fulfillment response is returned as a JSON response

10. If the intent name does not match any supported intents:

  • A warning message is logged.
  • A response is returned indicating that the fulfillment is not triggered for the specified intent.

11.Finally, the code checks if the main.py file is being run directly (not imported as a module):

  • The logging level is set to INFO.
  • The FastAPI application is run using uvicorn on host="0.0.0.0" and port=8000.

To summarize, the code sets up a FastAPI application that handles the fulfillment logic for a Dialogflow chatbot. It retrieves property details from a MongoDB database based on user queries and displays them in the chatbot using rich content responses. User information provided during the conversation is stored in the MongoDB database for further processing.

Remember to customize the code according to your specific requirements, such as adding more intents, modifying the response format, and implementing error handling and authentication as needed.

Conclusion:

In this tutorial, we created a Dialogflow chatbot and used webhooks to interface it with FastAPI. We learned how to extract and show property details from a MongoDB database in the chatbot. We also saved user information in the MongoDB database. This chatbot can be improved further by adding new intents, enabling natural language comprehension, and interacting with other services.

Remember to adapt the code to your needs and to guarantee correct error handling, security, and authentication in a production environment. Have fun coding!

--

--