Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Whatsapp integration #2335

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
54 changes: 54 additions & 0 deletions cookbook/examples/apps/whatsapp_chat_agent/agents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import logging
import os

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.storage.agent.sqlite import SqliteAgentStorage
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.tools.whatsapp import WhatsAppTools
from dotenv import load_dotenv

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Load environment variables
load_dotenv()

# Configure constants
VERIFY_TOKEN = os.getenv("WHATSAPP_VERIFY_TOKEN")
if not VERIFY_TOKEN:
raise ValueError("WHATSAPP_VERIFY_TOKEN must be set in .envrc")

WEBHOOK_URL = os.getenv("WHATSAPP_WEBHOOK_URL")
if not WEBHOOK_URL:
raise ValueError("WHATSAPP_WEBHOOK_URL must be set in .envrc")

AGENT_STORAGE_FILE = "tmp/whatsapp_agents.db"


def get_whatsapp_agent() -> Agent:
"""Returns an instance of the WhatsApp Agent.

Returns:
Agent: The configured WhatsApp agent instance.
"""
# Initialize WhatsApp tools
whatsapp = WhatsAppTools()

# Create and return the agent
return Agent(
name="WhatsApp Assistant",
model=OpenAIChat(id="gpt-4o"),
tools=[
whatsapp,
DuckDuckGoTools(),
],
storage=SqliteAgentStorage(
table_name="whatsapp_agent", db_file=AGENT_STORAGE_FILE
),
add_history_to_messages=True,
num_history_responses=3,
markdown=True,
description="You are a whatsapp chat agent. You will respond like how people talk to each other on whatsapp, with short sentences and simple language. If user asks you something which requires a web search, use the DuckDuckGoTools to search the web.",
)
81 changes: 81 additions & 0 deletions cookbook/examples/apps/whatsapp_chat_agent/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import logging

from agents import VERIFY_TOKEN, get_whatsapp_agent
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import PlainTextResponse

# Configure logging
logger = logging.getLogger(__name__)

# Initialize agent
agent = get_whatsapp_agent()

# Create FastAPI app
app = FastAPI()


@app.get("/webhook")
async def verify_webhook(request: Request):
"""Handle WhatsApp webhook verification"""
mode = request.query_params.get("hub.mode")
token = request.query_params.get("hub.verify_token")
challenge = request.query_params.get("hub.challenge")

if mode == "subscribe" and token == VERIFY_TOKEN:
if not challenge:
raise HTTPException(status_code=400, detail="No challenge received")
return PlainTextResponse(content=challenge)

raise HTTPException(status_code=403, detail="Invalid verify token or mode")


@app.post("/webhook")
async def handle_message(request: Request):
"""Handle incoming WhatsApp messages"""
try:
body = await request.json()

# Validate webhook data
if body.get("object") != "whatsapp_business_account":
logger.warning(
f"Received non-WhatsApp webhook object: {body.get('object')}"
)
return {"status": "ignored"}

# Process messages
for entry in body.get("entry", []):
for change in entry.get("changes", []):
messages = change.get("value", {}).get("messages", [])

if not messages:
continue

message = messages[0]
if message.get("type") != "text":
continue

# Extract message details
phone_number = message["from"]
message_text = message["text"]["body"]

logger.info(f"Processing message from {phone_number}: {message_text}")

# Generate and send response
response = agent.run(message_text)
agent.tools[0].send_text_message_sync(
recipient=phone_number, text=response.content
)
logger.info(f"Response sent to {phone_number}")

return {"status": "ok"}

except Exception as e:
logger.error(f"Error processing webhook: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))


if __name__ == "__main__":
import uvicorn

logger.info("Starting WhatsApp Bot Server")
uvicorn.run(app, host="0.0.0.0", port=8000)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

############################################################################
# Generate requirements.txt from requirements.in
############################################################################

echo "Generating requirements.txt"

CURR_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

UV_CUSTOM_COMPILE_COMMAND="./generate_requirements.sh" \
uv pip compile ${CURR_DIR}/requirements.in --no-cache --upgrade -o ${CURR_DIR}/requirements.txt
158 changes: 158 additions & 0 deletions cookbook/examples/apps/whatsapp_chat_agent/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# WhatsApp Business API Integration with AI Agent

This is a WhatsApp chatbot that automatically responds to incoming messages using an AI agent. The bot runs on FastAPI and uses the WhatsApp Business API to handle message interactions.

## Features

- Automatically responds to any incoming WhatsApp messages
- Uses AI to generate contextual responses
- Handles webhook verification for WhatsApp Business API
- Supports secure HTTPS communication
- Logs all interactions for monitoring

## Prerequisites

- Python 3.7+
- ngrok account (for development/testing)
- WhatsApp Business API access
- Meta Developer account
- OpenAI API key

## Getting WhatsApp Credentials

1. **Create Meta Developer Account**:

- Go to [Meta Developer Portal](https://developers.facebook.com/) and create an account
- Create a new app at [Meta Apps Dashboard](https://developers.facebook.com/apps/)
- Enable WhatsApp integration for your app

2. **Set Up WhatsApp Business API**:

- Go to your app's WhatsApp Setup page
- Find your WhatsApp Business Account ID in Business Settings
- Get your Phone Number ID from the WhatsApp > Getting Started page
- Generate a permanent access token in App Dashboard > WhatsApp > API Setup

3. **Test Environment Setup**:
- Note: Initially, you can only send messages to numbers registered in your test environment
- For production, you'll need to submit your app for review

## Environment Setup

Create a `.envrc` file in the project root with these variables:

```bash
# From Meta Developer Portal
export WHATSAPP_ACCESS_TOKEN=your_whatsapp_access_token # From App Dashboard > WhatsApp > API Setup
export WHATSAPP_PHONE_NUMBER_ID=your_phone_number_id # From WhatsApp > Getting Started
export WHATSAPP_WEBHOOK_URL=your_webhook_url # Your ngrok URL + /webhook
export WHATSAPP_VERIFY_TOKEN=your_verify_token # Any secure string you choose

# For OpenAI integration
export OPENAI_API_KEY=your_openai_api_key
```

## Installation

1. Install dependencies:

```bash
pip install -r requirements.txt
```

2. Set up your environment variables in `.envrc`:

```bash
source .envrc
```

## Running the Application

You need to run two components:

1. **The ngrok tunnel** (in one terminal):

```bash
ngrok http --domain=your-domain.ngrok-free.app 8000
```

2. **The FastAPI server** (in another terminal):

```bash
python app.py
```

## WhatsApp Business Setup

1. Go to Meta Developer Portal
2. Set up your WhatsApp Business account
3. Configure the webhook:
- URL: Your ngrok URL + "/webhook" (e.g., https://your-domain.ngrok-free.app/webhook)
- Verify Token: Same as WHATSAPP_VERIFY_TOKEN in your .envrc
- Subscribe to the 'messages' webhook field

## How It Works

1. When someone sends a message to your WhatsApp Business number:

- The message is received via webhook
- The AI agent processes the message
- A response is automatically generated and sent back

2. The agent can:
- Process incoming text messages
- Generate contextual responses
- Log all interactions

## Monitoring

The application logs important events:

- Server start/stop
- Incoming messages
- Response generation
- Message delivery status

Check the console output for logs.

## Error Handling

The application includes error handling for:

- Invalid webhook verification
- Message processing errors
- API communication issues

## Security Notes

- Keep your environment variables secure
- Don't commit `.envrc` to version control
- Use HTTPS for all communications
- Regularly rotate your access tokens

## Troubleshooting

Common issues:

1. Webhook verification failing:

- Check your VERIFY_TOKEN matches
- Ensure ngrok is running
- Verify webhook URL is correct

2. Messages not being received:

- Check webhook subscription status
- Verify WhatsApp Business API access

3. No responses being sent:
- Verify OpenAI API key
- Check WhatsApp access token

## Support

For issues and questions:

1. Check the logs for error messages
2. Review Meta's WhatsApp Business API documentation
3. Verify your API credentials and tokens
10 changes: 10 additions & 0 deletions cookbook/examples/apps/whatsapp_chat_agent/requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fastapi
uvicorn
python-dotenv
requests
duckduckgo-search
openai
agno
python-multipart
aiohttp
SQLAlchemy
Loading