CTRLK

Integrate Generative AI into a WhatsApp chatbot with LangGraph AI agent

|

View as Markdown

Add GenAI functionality to your chatbot to enhance the chatbot's intelligence. The chatbot uses GenAI to get additional, current information to generate responses.

This tutorial shows how to integrate Generative AI (GenAI) into a WhatsApp chatbot by using the LangGraph AI agent. Customize the example to meet your use case and requirements.

Products and channels [#products-channels]

WhatsApp

Prerequisites [#prerequisites]

  • Infobip account. Select WhatsApp as the channel on the welcome screen.

  • Python 3.11 or higher. Make sure that your environment is set up.

  • WhatsApp is connected to the selected device (phone or PC through the web app).

  • Do one of the following.

    • Create a secure connection to your device by using tools such as Pinggy or Ngrok.
    • Use a public website link to make the service accessible.
  • An understanding of LLM functions and tool calling.

Implementation steps [#implementation-steps]

Configure the Infobip web interface

Get data from the Infobip web interface

  1. Log on to the Infobip web interface.
  2. Copy the API Key and API Base URL. Copy the API key
  3. Go to Channels and Numbers > Channels > WhatsApp > Senders tab.
  4. Copy the default Infobip test sender number 447860099299. Copy the test sender

Configure the test sender

  1. Select the three dots next to the Infobip test sender and select Edit configuration.

    Edit configuration
  2. In the Inbound configuration > Keywords section, select the three dots next to the keyword that matches your username and select Edit.

    Edit keyword
  3. Configure the forwarding action for inbound messages.

    1. In the Forwarding action section, select Forward to HTTP.

    2. Enter the URL of your endpoint. Example: Tunnel URL to localhost using pinggy.

      ssh -p 443 -L4300:localhost:4300 -o StrictHostKeyChecking=no -o ServerAliveInterval=30 -R0:localhost:8000 a.pinggy.ios
    3. In the Renderer field, select MO_OTT_CONTACT.

      Edit keyword
  4. If your Infobip account is in the trial period, send a keyword to the registered number. Example: Send the keyword WA123.

Set up the Python environment

Set up the environment
  1. Create a new Python virtual environment.

  2. Add the following code to requirements.txt.

    1fastapi==0.115.9
    2uvicorn==0.34
    3langgraph==0.3.1
    4python-dotenv==1.0.1
    5langchain\_openai==0.3.7
    6langchain\_community==0.3.18
    7duckduckgo\_search==7.5.0
  3. Use the following code to install the required libraries.

    pip install -r requirements.txt

Set up secrets

Create a .env file to store API keys and sensitive configuration. Use either Azure credentials or OPENAI_API_KEY.

1 
2# Infobip Platform
3OUTBOUND_ENDPOINT = #enter your endpoint URL here. Example: kwqlz1.api.infobip.com - find this on the homepage of the Infobip web interface
4ENDPOINT_API_KEY = #endpoint API key - find this on the homepage of the Infobip web interface
5WHATSAPP_SENDER = #whatsapp sender number. Example: 447860099299
6# GenAI credentials, Azure
7OPENAI_API_VERSION = "2024-06-01"
8AZURE_OPENAI_ENDPOINT = #enter your Azure OpenAI endpoint URL
9AZURE_OPENAI_API_KEY = #enter your Azure OpenAI API Key
10DEPLOYMENT_NAME = #enter the name of the Azure OpenAI deployment. Example: The name of your model

Configure the code

The code structure contains the following.

  • Main: API endpoint.
  • Message sender: Sends messages to WhatsApp through Infobip.
  • Core agent: Manages GenAI processing.

Configure the API endpoint: main.py

Use FastAPI library to make the service available online.

  1. Import the required modules and create a function to extract inbound messages.

    python
    1from fastapi import FastAPI, Request
    2from send_message import message_sender
    3from core_agent import InboundMessage, message_handler
    4import uvicorn
    5 
    6app = FastAPI()
    7 
    8def extract_response_data(response: dict) -> InboundMessage:
    9 try:
    10 text_field = response['results'][0]['message']['text']
    11 contact_name = response['results'][0]['contact']['name']
    12 sender_number = response['results'][0]['from']
    13 constructed_message = InboundMessage(message_text=text_field, contact=contact_name, from_number=sender_number)
    14 return constructed_message
    15 except KeyError as e:
    16 return {"KeyError": str(e)}
  2. Configure the FastAPI endpoint to manage incoming messages.

    python
    1@app.post("/incoming")
    2async def receive_event(request: Request):
    3 try:
    4 response = await request.json()
    5 inbound_data = extract_response_data(response)
    6 outbound_message = message_handler(inbound_data)
    7 return(message_sender(inbound_data.from_number, outbound_message))
    8 except Exception as e:
    9 return {"error": str(e)}
  3. Run the server.

    python
    1if __name__ == "__main__":
    2 uvicorn.run(app, host="0.0.0.0", port=8000)

Configure the message sender: send_message.py

The message sender sends outbound messages by using the WhatsApp sender number and Infobip credentials.

python
1import http.client
2import json
3from dotenv import load_dotenv
4import os
5 
6load_dotenv()
7whatsapp_sender = os.getenv("WHATSAPP_SENDER")
8outbound_endpoint = os.getenv("OUTBOUND_ENDPOINT")
9api_key = os.getenv("ENDPOINT_API_KEY")
10 
11authorization = f"App {api_key}"
12 
13def message_sender(destination: int, message: str):
14 conn = http.client.HTTPSConnection(outbound_endpoint)
15 payload = json.dumps({
16 "from": whatsapp_sender,
17 "to": destination,
18 "content": {
19 "text": message
20 }
21 })
22 headers = {
23 'Authorization': authorization,
24 'Content-Type': 'application/json',
25 'Accept': 'application/json'
26 }
27 conn.request("POST", "/whatsapp/1/message/text", payload, headers)
28 res = conn.getresponse()
29 data = res.read()
30 return print(data.decode("utf-8"))

Integrate LangGraph: core_agent.py

This section shows how to integrate LangGraph logic into your chatbot.

LangGraph is a framework for building GenAI agent solutions. It does the following.

  • Controls the integration process.
  • Helps get an overview of the process.
  • Enables integration of advanced concepts such as human-in-the loop and tool calling.

In this tutorial, the GenAI agent uses DuckDuckGo Search tool to search the web to support its responses. The GenAI agent uses the GPT-4o model from OpenAI.

  1. Manage imports for LangGraph and LangChain. These are used to call the Search tool function and Azure OpenAI. Instead of Azure OpenAI, you can use either direct calls to OpenAI or one of the chat model providers.

    python
    1from dotenv import load_dotenv
    2import os
    3from langchain_core.messages import BaseMessage
    4from langchain_openai import AzureChatOpenAI
    5from typing import Annotated
    6from typing_extensions import TypedDict
    7from langgraph.checkpoint.memory import MemorySaver
    8from langgraph.graph import StateGraph, START
    9from langgraph.graph.message import add_messages
    10from langgraph.prebuilt import ToolNode, tools_condition
    11from langchain_community.tools import DuckDuckGoSearchResults
    12from pydantic import BaseModel
    13 
    14load_dotenv()
  2. Define the message class with Pydantic validation.

    python
    1class InboundMessage(BaseModel):
    2 message_text: str
    3 contact: str
    4 from_number: str
  3. Define the state of the graph.

    python
    1class State(TypedDict):
    2 messages: Annotated[list, add_messages]
  4. Define the LLM and memory store for the conversation and tool bindings. Instead of DuckDuckGoSearchResults, you can write custom functions.

    python
    1llm = AzureChatOpenAI(azure_deployment=os.getenv("DEPLOYMENT_NAME"), streaming=False,
    2 max_tokens=700)
    3 
    4memory = MemorySaver()
    5 
    6search_tool = DuckDuckGoSearchResults(output_format="json")
    7tools = [search_tool]
    8llm_with_tools = llm.bind_tools(tools)
    9 
    10def chatbot(state: State):
    11 return {"messages": [llm_with_tools.invoke(state["messages"])]}
  5. Define the function to build the graph and manage messages.

The following image shows the graph that is built by the Message handler function.

Generated graph

The message handler function listens for events in the graph stream and looks for the messages. It builds a graph and calls it when end users send messages to the chatbot. This triggers a request to a GenAI model that generates the output.

python
1def message_handler(InboundMessage):
2 graph_builder = StateGraph(State)
3 graph_builder.add_node("chatbot", chatbot)
4 graph_builder.add_node("tools", ToolNode(tools))
5 graph_builder.add_edge(START, "chatbot")
6 graph_builder.add_conditional_edges("chatbot", tools_condition,)
7
8 graph_builder.add_edge("tools", "chatbot")
9
10 graph = graph_builder.compile(checkpointer=memory)
11
12 config = {"configurable": {"thread_id": InboundMessage.from_number}}
13 all_messages = []
14
15 for event in graph.stream({"messages": [("system", "imitate C3PO"), ("user", InboundMessage.message_text)]}, config):
16 for value in event.values():
17 messages = value["messages"]
18 if messages:
19 last_message = messages[-1]
20 if isinstance(last_message, BaseMessage):
21 #...and append them to a list
22 all_messages.append(last_message.content)
23
24 if all_messages:
25 return (all_messages[-1])

The system prompt "imitate C3PO" shows the impact of system prompts. Modify this part according to your use case by using prompt engineering techniques.

Launch

Launch main.py and start a conversation with your sender over WhatsApp. If you develop the system locally, start a tunnel for localhost access.

The following example shows a Pinggy tunnel that receives messages from the Infobip platform and sends them to the LangGraph AI agent.

Pinggy tunnel

Using GPT-4o enhances the chatbot's intelligence. Also, the ability to search the web makes sure that the chatbot has additional, current information.

The example in the following image shows that the GenAI chatbot knows about the latest Infobip news. This shows its ability to search the web to support its responses.

GenAI result