[feat] Add support for creating whatsapp bot using embedchain (#458)
This commit is contained in:
@@ -2,26 +2,45 @@
|
|||||||
title: '💬 WhatsApp Bot'
|
title: '💬 WhatsApp Bot'
|
||||||
---
|
---
|
||||||
|
|
||||||
### 🖼️ Template Setup
|
### 🚀 Getting started
|
||||||
|
|
||||||
- Fork [this](https://replit.com/@taranjeetio/EC-WhatsApp-Bot-Template?v=1#README.md) replit template.
|
1. Install embedchain python package:
|
||||||
- Set your `OPENAI_API_KEY` in Secrets.
|
|
||||||
- Register for a free account on [Twilio](https://www.twilio.com/try-twilio) and create a new Whatsapp Sandbox.
|
|
||||||
- You can find it in the left Sidebar under `Develop` by navigating to `Messaging>Try it out>Send a WhatsApp Message`.
|
|
||||||
- To connect a phone number and allow it to chat with the bot, follow the on screen instructions.
|
|
||||||
- Click on `Run` in the replit container and a URL will get generated for your bot.
|
|
||||||
- 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.
|
|
||||||
|
|
||||||
### 🚀 Usage Instructions
|
```bash
|
||||||
|
pip install embedchain
|
||||||
- To allow a new number or reconnect an old number with the Sandbox, follow the instructions in your Twilio account.
|
|
||||||
- To add data sources to the bot, use the command:
|
|
||||||
```text
|
|
||||||
add <data_type> <url_or_text>
|
|
||||||
```
|
|
||||||
- To ask queries from the bot, use the command:
|
|
||||||
```text
|
|
||||||
<question>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
🎉 Happy Chatting! 🎉
|
2. Launch your WhatsApp bot:
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m embedchain.bots.whatsapp --port 5000
|
||||||
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
3. Create a free account on [Twilio](https://www.twilio.com/try-twilio)
|
||||||
|
- Set up a WhatsApp Sandbox in your Twilio dashboard. Access it via the left sidebar: `Messaging > Try it out > Send a WhatsApp Message`.
|
||||||
|
- Follow on-screen instructions to link a phone number for chatting with your bot
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
### 💬 How to use
|
||||||
|
|
||||||
|
- To connect a new number or reconnect an old one in the Sandbox, follow Twilio's instructions.
|
||||||
|
- To include data sources, use this command:
|
||||||
|
```text
|
||||||
|
add <url_or_text>
|
||||||
|
```
|
||||||
|
|
||||||
|
- To ask the bot questions, just type your query:
|
||||||
|
```text
|
||||||
|
<your-question-here>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
Here is an example of Elon Musk WhatsApp Bot that we created:
|
||||||
|
|
||||||
|
<img src="/images/whatsapp.jpg"/>
|
||||||
|
|||||||
BIN
docs/images/whatsapp.jpg
Normal file
BIN
docs/images/whatsapp.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
0
embedchain/bots/__init__.py
Normal file
0
embedchain/bots/__init__.py
Normal file
25
embedchain/bots/base.py
Normal file
25
embedchain/bots/base.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
from embedchain import CustomApp
|
||||||
|
from embedchain.config import AddConfig, CustomAppConfig, QueryConfig
|
||||||
|
from embedchain.models import EmbeddingFunctions, Providers
|
||||||
|
|
||||||
|
|
||||||
|
class BaseBot:
|
||||||
|
def __init__(self, app_config=None):
|
||||||
|
if app_config is None:
|
||||||
|
app_config = CustomAppConfig(embedding_fn=EmbeddingFunctions.OPENAI, provider=Providers.OPENAI)
|
||||||
|
self.app_config = app_config
|
||||||
|
self.app = CustomApp(config=self.app_config)
|
||||||
|
|
||||||
|
def add(self, data, config: AddConfig = None):
|
||||||
|
"""Add data to the bot"""
|
||||||
|
config = config if config else AddConfig()
|
||||||
|
self.app.add(data, config=config)
|
||||||
|
|
||||||
|
def query(self, query, config: QueryConfig = None):
|
||||||
|
"""Query bot"""
|
||||||
|
config = config if config else QueryConfig()
|
||||||
|
return self.app.query(query, config=config)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""Start the bot's functionality."""
|
||||||
|
raise NotImplementedError("Subclasses must implement the start method.")
|
||||||
72
embedchain/bots/whatsapp.py
Normal file
72
embedchain/bots/whatsapp.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from flask import Flask, request
|
||||||
|
from twilio.twiml.messaging_response import MessagingResponse
|
||||||
|
|
||||||
|
from .base import BaseBot
|
||||||
|
|
||||||
|
|
||||||
|
class WhatsAppBot(BaseBot):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def handle_message(self, message):
|
||||||
|
if message.startswith("add "):
|
||||||
|
response = self.add_data(message)
|
||||||
|
else:
|
||||||
|
response = self.ask_bot(message)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def add_data(self, message):
|
||||||
|
data = message.split(" ")[-1]
|
||||||
|
try:
|
||||||
|
self.add(data)
|
||||||
|
response = f"Added data from: {data}"
|
||||||
|
except Exception:
|
||||||
|
logging.exception(f"Failed to add data {data}.")
|
||||||
|
response = "Some error occurred while adding data."
|
||||||
|
return response
|
||||||
|
|
||||||
|
def ask_bot(self, message):
|
||||||
|
try:
|
||||||
|
response = self.query(message)
|
||||||
|
except Exception:
|
||||||
|
logging.exception(f"Failed to query {message}.")
|
||||||
|
response = "An error occurred. Please try again!"
|
||||||
|
return response
|
||||||
|
|
||||||
|
def start(self, host="0.0.0.0", port=5000, debug=True):
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
def signal_handler(sig, frame):
|
||||||
|
logging.info("\nGracefully shutting down the WhatsAppBot...")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
|
||||||
|
@app.route("/chat", methods=["POST"])
|
||||||
|
def chat():
|
||||||
|
incoming_message = request.values.get("Body", "").lower()
|
||||||
|
response = self.handle_message(incoming_message)
|
||||||
|
twilio_response = MessagingResponse()
|
||||||
|
twilio_response.message(response)
|
||||||
|
return str(twilio_response)
|
||||||
|
|
||||||
|
app.run(host=host, port=port, debug=debug)
|
||||||
|
|
||||||
|
|
||||||
|
def start_command():
|
||||||
|
parser = argparse.ArgumentParser(description="EmbedChain WhatsAppBot command line interface")
|
||||||
|
parser.add_argument("--host", default="0.0.0.0", help="Host IP to bind")
|
||||||
|
parser.add_argument("--port", default=5000, type=int, help="Port to bind")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
whatsapp_bot = WhatsAppBot()
|
||||||
|
whatsapp_bot.start(host=args.host, port=args.port)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
start_command()
|
||||||
10
examples/whatsapp_bot/run.py
Normal file
10
examples/whatsapp_bot/run.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
from embedchain.bots.whatsapp import WhatsAppBot
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
whatsapp_bot = WhatsAppBot()
|
||||||
|
whatsapp_bot.start()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
1
setup.py
1
setup.py
@@ -41,5 +41,6 @@ setuptools.setup(
|
|||||||
"dev": ["black", "ruff", "isort", "pytest"],
|
"dev": ["black", "ruff", "isort", "pytest"],
|
||||||
"community": ["llama-index==0.7.21"],
|
"community": ["llama-index==0.7.21"],
|
||||||
"elasticsearch": ["elasticsearch>=8.9.0"],
|
"elasticsearch": ["elasticsearch>=8.9.0"],
|
||||||
|
"whatsapp": ["twilio==8.5.0", "flask==1.1.2"],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user