Skip to content

Commit f29443a

Browse files
authored
[feat] Add support for creating whatsapp bot using embedchain (#458)
1 parent 35b022d commit f29443a

File tree

7 files changed

+142
-15
lines changed

7 files changed

+142
-15
lines changed

docs/examples/whatsapp_bot.mdx

+34-15
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,45 @@
22
title: '💬 WhatsApp Bot'
33
---
44

5-
### 🖼️ Template Setup
5+
### 🚀 Getting started
66

7-
- Fork [this](https://replit.com/@taranjeetio/EC-WhatsApp-Bot-Template?v=1#README.md) replit template.
8-
- Set your `OPENAI_API_KEY` in Secrets.
9-
- Register for a free account on [Twilio](https://www.twilio.com/try-twilio) and create a new Whatsapp Sandbox.
10-
- You can find it in the left Sidebar under `Develop` by navigating to `Messaging>Try it out>Send a WhatsApp Message`.
11-
- To connect a phone number and allow it to chat with the bot, follow the on screen instructions.
12-
- Click on `Run` in the replit container and a URL will get generated for your bot.
13-
- Copy the URL, append `/chat` at the end and paste it under `When a message comes in` under the `Sandbox settings` for Whatsapp in Twilio. Save your settings.
7+
1. Install embedchain python package:
148

15-
### 🚀 Usage Instructions
9+
```bash
10+
pip install embedchain
11+
```
12+
13+
2. Launch your WhatsApp bot:
14+
15+
16+
```bash
17+
python -m embedchain.bots.whatsapp --port 5000
18+
```
19+
20+
If your bot needs to be accessible online, use your machine's public IP or DNS. Otherwise, employ a proxy server like [ngrok](https://ngrok.com/) to make your local bot accessible.
1621

17-
- To allow a new number or reconnect an old number with the Sandbox, follow the instructions in your Twilio account.
18-
- To add data sources to the bot, use the command:
22+
3. Create a free account on [Twilio](https://www.twilio.com/try-twilio)
23+
- Set up a WhatsApp Sandbox in your Twilio dashboard. Access it via the left sidebar: `Messaging > Try it out > Send a WhatsApp Message`.
24+
- Follow on-screen instructions to link a phone number for chatting with your bot
25+
- Copy your bot's public URL, add /chat at the end, and paste it in Twilio's WhatsApp Sandbox settings under "When a message comes in". Save the settings.
26+
27+
- Copy your bot's public url, append `/chat` at the end and paste it under `When a message comes in` under the `Sandbox settings` for Whatsapp in Twilio. Save your settings.
28+
29+
### 💬 How to use
30+
31+
- To connect a new number or reconnect an old one in the Sandbox, follow Twilio's instructions.
32+
- To include data sources, use this command:
1933
```text
20-
add <data_type> <url_or_text>
34+
add <url_or_text>
2135
```
22-
- To ask queries from the bot, use the command:
36+
37+
- To ask the bot questions, just type your query:
2338
```text
24-
<question>
39+
<your-question-here>
2540
```
2641

27-
🎉 Happy Chatting! 🎉
42+
### Example
43+
44+
Here is an example of Elon Musk WhatsApp Bot that we created:
45+
46+
<img src="/images/whatsapp.jpg"/>

docs/images/whatsapp.jpg

59.1 KB
Loading

embedchain/bots/__init__.py

Whitespace-only changes.

embedchain/bots/base.py

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from embedchain import CustomApp
2+
from embedchain.config import AddConfig, CustomAppConfig, QueryConfig
3+
from embedchain.models import EmbeddingFunctions, Providers
4+
5+
6+
class BaseBot:
7+
def __init__(self, app_config=None):
8+
if app_config is None:
9+
app_config = CustomAppConfig(embedding_fn=EmbeddingFunctions.OPENAI, provider=Providers.OPENAI)
10+
self.app_config = app_config
11+
self.app = CustomApp(config=self.app_config)
12+
13+
def add(self, data, config: AddConfig = None):
14+
"""Add data to the bot"""
15+
config = config if config else AddConfig()
16+
self.app.add(data, config=config)
17+
18+
def query(self, query, config: QueryConfig = None):
19+
"""Query bot"""
20+
config = config if config else QueryConfig()
21+
return self.app.query(query, config=config)
22+
23+
def start(self):
24+
"""Start the bot's functionality."""
25+
raise NotImplementedError("Subclasses must implement the start method.")

embedchain/bots/whatsapp.py

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import argparse
2+
import logging
3+
import signal
4+
import sys
5+
6+
from flask import Flask, request
7+
from twilio.twiml.messaging_response import MessagingResponse
8+
9+
from .base import BaseBot
10+
11+
12+
class WhatsAppBot(BaseBot):
13+
def __init__(self):
14+
super().__init__()
15+
16+
def handle_message(self, message):
17+
if message.startswith("add "):
18+
response = self.add_data(message)
19+
else:
20+
response = self.ask_bot(message)
21+
return response
22+
23+
def add_data(self, message):
24+
data = message.split(" ")[-1]
25+
try:
26+
self.add(data)
27+
response = f"Added data from: {data}"
28+
except Exception:
29+
logging.exception(f"Failed to add data {data}.")
30+
response = "Some error occurred while adding data."
31+
return response
32+
33+
def ask_bot(self, message):
34+
try:
35+
response = self.query(message)
36+
except Exception:
37+
logging.exception(f"Failed to query {message}.")
38+
response = "An error occurred. Please try again!"
39+
return response
40+
41+
def start(self, host="0.0.0.0", port=5000, debug=True):
42+
app = Flask(__name__)
43+
44+
def signal_handler(sig, frame):
45+
logging.info("\nGracefully shutting down the WhatsAppBot...")
46+
sys.exit(0)
47+
48+
signal.signal(signal.SIGINT, signal_handler)
49+
50+
@app.route("/chat", methods=["POST"])
51+
def chat():
52+
incoming_message = request.values.get("Body", "").lower()
53+
response = self.handle_message(incoming_message)
54+
twilio_response = MessagingResponse()
55+
twilio_response.message(response)
56+
return str(twilio_response)
57+
58+
app.run(host=host, port=port, debug=debug)
59+
60+
61+
def start_command():
62+
parser = argparse.ArgumentParser(description="EmbedChain WhatsAppBot command line interface")
63+
parser.add_argument("--host", default="0.0.0.0", help="Host IP to bind")
64+
parser.add_argument("--port", default=5000, type=int, help="Port to bind")
65+
args = parser.parse_args()
66+
67+
whatsapp_bot = WhatsAppBot()
68+
whatsapp_bot.start(host=args.host, port=args.port)
69+
70+
71+
if __name__ == "__main__":
72+
start_command()

examples/whatsapp_bot/run.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from embedchain.bots.whatsapp import WhatsAppBot
2+
3+
4+
def main():
5+
whatsapp_bot = WhatsAppBot()
6+
whatsapp_bot.start()
7+
8+
9+
if __name__ == "__main__":
10+
main()

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,6 @@
4141
"dev": ["black", "ruff", "isort", "pytest"],
4242
"community": ["llama-index==0.7.21"],
4343
"elasticsearch": ["elasticsearch>=8.9.0"],
44+
"whatsapp": ["twilio==8.5.0", "flask==1.1.2"],
4445
},
4546
)

0 commit comments

Comments
 (0)