From e3ae84b80d3ac5ca506e733d02e411b3cb5dcb5f Mon Sep 17 00:00:00 2001 From: Sahil Kumar Yadav Date: Tue, 15 Aug 2023 03:10:25 +0530 Subject: [PATCH] add: WhatsApp, Slack and Telegram bots (#438) --- docs/examples/api_server.mdx | 51 ++++++++++++++++++-- docs/examples/slack_bot.mdx | 39 +++++++++++++++ docs/examples/telegram_bot.mdx | 26 ++++++++++ docs/examples/whatsapp_bot.mdx | 27 +++++++++++ docs/mint.json | 2 +- examples/api_server/README.md | 3 ++ examples/api_server/api_server.py | 13 +++++ examples/discord_bot/README.md | 3 ++ examples/slack_bot/.gitignore | 7 +++ examples/slack_bot/README.md | 3 ++ examples/slack_bot/requirements.txt | 5 ++ examples/slack_bot/slack_bot.py | 58 ++++++++++++++++++++++ examples/slack_bot/variables.env | 3 ++ examples/telegram_bot/.gitignore | 7 +++ examples/telegram_bot/README.md | 3 ++ examples/telegram_bot/requirements.txt | 4 ++ examples/telegram_bot/telegram_bot.py | 66 ++++++++++++++++++++++++++ examples/telegram_bot/variables.env | 2 + examples/whatsapp_bot/.gitignore | 8 ++++ examples/whatsapp_bot/README.md | 3 ++ examples/whatsapp_bot/requirements.txt | 3 ++ examples/whatsapp_bot/variables.env | 1 + examples/whatsapp_bot/whatsapp_bot.py | 51 ++++++++++++++++++++ 23 files changed, 384 insertions(+), 4 deletions(-) create mode 100644 docs/examples/slack_bot.mdx create mode 100644 docs/examples/telegram_bot.mdx create mode 100644 docs/examples/whatsapp_bot.mdx create mode 100644 examples/api_server/README.md create mode 100644 examples/discord_bot/README.md create mode 100644 examples/slack_bot/.gitignore create mode 100644 examples/slack_bot/README.md create mode 100644 examples/slack_bot/requirements.txt create mode 100644 examples/slack_bot/slack_bot.py create mode 100644 examples/slack_bot/variables.env create mode 100644 examples/telegram_bot/.gitignore create mode 100644 examples/telegram_bot/README.md create mode 100644 examples/telegram_bot/requirements.txt create mode 100644 examples/telegram_bot/telegram_bot.py create mode 100644 examples/telegram_bot/variables.env create mode 100644 examples/whatsapp_bot/.gitignore create mode 100644 examples/whatsapp_bot/README.md create mode 100644 examples/whatsapp_bot/requirements.txt create mode 100644 examples/whatsapp_bot/variables.env create mode 100644 examples/whatsapp_bot/whatsapp_bot.py diff --git a/docs/examples/api_server.mdx b/docs/examples/api_server.mdx index 2d077114..0a62faeb 100644 --- a/docs/examples/api_server.mdx +++ b/docs/examples/api_server.mdx @@ -2,6 +2,8 @@ title: '🌍 API Server' --- +The API Server based on Flask integrates the `embedchain` package, offering endpoints to add, query, and chat to engage in conversations with a chatbot using JSON requests. + ### 🐳 Docker Setup - Open variables.env, and edit it to add your 🔑 `OPENAI_API_KEY`. @@ -16,8 +18,8 @@ docker-compose up --build ### 🚀 Usage Instructions - Your api server is running on [http://localhost:5000/](http://localhost:5000/) -- To use the api server, make an api call to the endpoints `/add` and `/query` using the json formats discussed below. -- To add data sources to the bot: +- To use the api server, make an api call to the endpoints `/add`, `/query` and `/chat` using the json formats discussed below. +- To add data sources to the bot (/add): ```json // Request { @@ -30,7 +32,19 @@ docker-compose up --build "data": "Added data_type: url_or_text" } ``` -- To ask questions from the bot: +- To ask queries from the bot (/query): +```json +// Request +{ + "question": "your_question_here" +} + +// Response +{ + "data": "your_answer_here" +} +``` +- To chat with the bot (/chat): ```json // Request { @@ -43,4 +57,35 @@ docker-compose up --build } ``` +### 📡 Curl Call Formats + +- To add data sources to the bot (/add): +```bash +curl -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "data_type": "your_data_type_here", + "url_or_text": "your_url_or_text_here" + }' \ + http://localhost:5000/add +``` +- To ask queries from the bot (/query): +```bash +curl -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "question": "your_question_here" + }' \ + http://localhost:5000/query +``` +- To chat with the bot (/chat): +```bash +curl -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "question": "your_question_here" + }' \ + http://localhost:5000/chat +``` + 🎉 Happy Chatting! 🎉 diff --git a/docs/examples/slack_bot.mdx b/docs/examples/slack_bot.mdx new file mode 100644 index 00000000..e4fa8f89 --- /dev/null +++ b/docs/examples/slack_bot.mdx @@ -0,0 +1,39 @@ +--- +title: '💼 Slack Bot' +--- + +### 🖼️ Template Setup + +- Fork [this](https://replit.com/@taranjeetio/EC-Slack-Bot-Template?v=1#README.md) replit template. +- Set your `OPENAI_API_KEY` in Secrets. +- Create a workspace on Slack if you don't have one already by clicking [here](https://slack.com/intl/en-in/). +- Create a new App on your Slack account by going [here](https://api.slack.com/apps). +- Select `From Scratch`, then enter the Bot Name and select your workspace. +- On the `Basic Information` page copy the `Signing Secret` and set it in your secrets as `SLACK_SIGNING_SECRET`. +- On the left Sidebar, go to `OAuth and Permissions` and add the following scopes under `Bot Token Scopes`: +```text +app_mentions:read +channels:history +channels:read +chat:write +``` +- Now select the option `Install to Workspace` and after it's done, copy the `Bot User OAuth Token` and set it in your secrets as `SLACK_BOT_TOKEN`. +- Start your replit container now by clicking on `Run`. +- On the Slack API website go to `Event Subscriptions` on the left Sidebar and turn on `Enable Events`. +- Copy the generated server URL in replit, append `/chat` at its end and paste it in `Request URL` box. +- After it gets verified, click on `Subscribe to bot events`, add `message.channels` Bot User Event and click on `Save Changes`. +- Now go to your workspace, click on the bot name in the Sidebar and then add the bot to any channel you want. + +### 🚀 Usage Instructions + +- Go to the channel where you have added your bot. +- To add data sources to the bot, use the command: +```text +add +``` +- To ask queries from the bot, use the command: +```text +query +``` + +🎉 Happy Chatting! 🎉 diff --git a/docs/examples/telegram_bot.mdx b/docs/examples/telegram_bot.mdx new file mode 100644 index 00000000..be5dbf05 --- /dev/null +++ b/docs/examples/telegram_bot.mdx @@ -0,0 +1,26 @@ +--- +title: '📱 Telegram Bot' +--- + +### 🖼️ Template Setup + +- Fork [this](https://replit.com/@taranjeetio/EC-Telegram-Bot-Template?v=1#README.md) replit template. +- Set your `OPENAI_API_KEY` in Secrets. +- Open the Telegram app and search for the `BotFather` user. +- Start a chat with BotFather and use the `/newbot` command to create a new bot. +- Follow the instructions to choose a name and username for your bot. +- Once the bot is created, BotFather will provide you with a unique token for your bot. +- Set this token as `TELEGRAM_BOT_TOKEN` in Secrets. +- Click on `Run` in the replit container and a URL will get generated for your bot. +- Now set your webhook by running the following link in your browser: +```url +https://api.telegram.org/bot/setWebhook?url= +``` +- When you get a successful response in your browser, your bot is ready to be used. + +### 🚀 Usage Instructions + +- Open your bot by searching for it using the bot name or bot username. +- Click on `Start` or type `/start` and follow the on screen instructions. + +🎉 Happy Chatting! 🎉 diff --git a/docs/examples/whatsapp_bot.mdx b/docs/examples/whatsapp_bot.mdx new file mode 100644 index 00000000..c4773361 --- /dev/null +++ b/docs/examples/whatsapp_bot.mdx @@ -0,0 +1,27 @@ +--- +title: '💬 WhatsApp Bot' +--- + +### 🖼️ Template Setup + +- Fork [this](https://replit.com/@taranjeetio/EC-WhatsApp-Bot-Template?v=1#README.md) replit template. +- 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 + +- 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 +``` +- To ask queries from the bot, use the command: +```text + +``` + +🎉 Happy Chatting! 🎉 diff --git a/docs/mint.json b/docs/mint.json index 98ccf745..1b974b1b 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -36,7 +36,7 @@ }, { "group": "Examples", - "pages": ["examples/full_stack", "examples/api_server", "examples/discord_bot"] + "pages": ["examples/full_stack", "examples/api_server", "examples/discord_bot", "examples/slack_bot", "examples/telegram_bot", "examples/whatsapp_bot"] }, { "group": "Contribution Guidelines", diff --git a/examples/api_server/README.md b/examples/api_server/README.md new file mode 100644 index 00000000..1d9fa612 --- /dev/null +++ b/examples/api_server/README.md @@ -0,0 +1,3 @@ +# API Server + +This is a docker template to create your own API Server using the embedchain package. To know more about the API Server and how to use it, go [here](https://docs.embedchain.ai/examples/api_server). \ No newline at end of file diff --git a/examples/api_server/api_server.py b/examples/api_server/api_server.py index 224dd7a0..a49465e0 100644 --- a/examples/api_server/api_server.py +++ b/examples/api_server/api_server.py @@ -26,6 +26,19 @@ def add(): @app.route("/query", methods=["POST"]) def query(): + data = request.get_json() + question = data.get("question") + if question: + try: + response = chat_bot.query(question) + return jsonify({"data": response}), 200 + except Exception: + return jsonify({"error": "An error occurred. Please try again!"}), 500 + return jsonify({"error": "Invalid request. Please provide 'question' in JSON format."}), 400 + + +@app.route("/chat", methods=["POST"]) +def chat(): data = request.get_json() question = data.get("question") if question: diff --git a/examples/discord_bot/README.md b/examples/discord_bot/README.md new file mode 100644 index 00000000..7e3f7e66 --- /dev/null +++ b/examples/discord_bot/README.md @@ -0,0 +1,3 @@ +# Discord Bot + +This is a docker template to create your own Discord bot using the embedchain package. To know more about the bot and how to use it, go [here](https://docs.embedchain.ai/examples/discord_bot). \ No newline at end of file diff --git a/examples/slack_bot/.gitignore b/examples/slack_bot/.gitignore new file mode 100644 index 00000000..ba288ed3 --- /dev/null +++ b/examples/slack_bot/.gitignore @@ -0,0 +1,7 @@ +__pycache__ +db +database +pyenv +venv +.env +trash_files/ diff --git a/examples/slack_bot/README.md b/examples/slack_bot/README.md new file mode 100644 index 00000000..beb86341 --- /dev/null +++ b/examples/slack_bot/README.md @@ -0,0 +1,3 @@ +# Slack Bot + +This is a replit template to create your own Slack bot using the embedchain package. To know more about the bot and how to use it, go [here](https://docs.embedchain.ai/examples/slack_bot). \ No newline at end of file diff --git a/examples/slack_bot/requirements.txt b/examples/slack_bot/requirements.txt new file mode 100644 index 00000000..d604507f --- /dev/null +++ b/examples/slack_bot/requirements.txt @@ -0,0 +1,5 @@ +flask==2.3.2 +slackeventsapi==3.0.1 +slacksdk==3.21.3 +python-dotenv==1.0.0 +embedchain \ No newline at end of file diff --git a/examples/slack_bot/slack_bot.py b/examples/slack_bot/slack_bot.py new file mode 100644 index 00000000..302a2167 --- /dev/null +++ b/examples/slack_bot/slack_bot.py @@ -0,0 +1,58 @@ +import os + +from dotenv import load_dotenv +from flask import Flask +from slack_sdk import WebClient +from slackeventsapi import SlackEventAdapter + +from embedchain import App + +load_dotenv() +app = Flask(__name__) + +slack_signing_secret = os.environ.get("SLACK_SIGNING_SECRET") +slack_events_adapter = SlackEventAdapter(slack_signing_secret, "/chat", app) + +slack_bot_token = os.environ.get("SLACK_BOT_TOKEN") +client = WebClient(token=slack_bot_token) + +chat_bot = App() +recent_message = {"ts": 0, "channel": ""} + + +@slack_events_adapter.on("message") +def handle_message(event_data): + message = event_data["event"] + if "text" in message and message.get("subtype") != "bot_message": + text = message["text"] + if float(message.get("ts")) > float(recent_message["ts"]): + recent_message["ts"] = message["ts"] + recent_message["channel"] = message["channel"] + if text.startswith("query"): + _, question = text.split(" ", 1) + try: + response = chat_bot.chat(question) + send_slack_message(message["channel"], response) + print("Query answered successfully!") + except Exception as e: + send_slack_message(message["channel"], "An error occurred. Please try again!") + print("Error occurred during 'query' command:", e) + elif text.startswith("add"): + _, data_type, url_or_text = text.split(" ", 2) + if url_or_text.startswith("<") and url_or_text.endswith(">"): + url_or_text = url_or_text[1:-1] + try: + chat_bot.add(data_type, url_or_text) + send_slack_message(message["channel"], f"Added {data_type} : {url_or_text}") + except Exception as e: + send_slack_message(message["channel"], f"Failed to add {data_type} : {url_or_text}") + print("Error occurred during 'add' command:", e) + + +def send_slack_message(channel, message): + response = client.chat_postMessage(channel=channel, text=message) + return response + + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000, debug=False) diff --git a/examples/slack_bot/variables.env b/examples/slack_bot/variables.env new file mode 100644 index 00000000..1b00ead5 --- /dev/null +++ b/examples/slack_bot/variables.env @@ -0,0 +1,3 @@ +SLACK_SIGNING_SECRET="" +SLACK_BOT_TOKEN="" +OPENAI_API_KEY="" \ No newline at end of file diff --git a/examples/telegram_bot/.gitignore b/examples/telegram_bot/.gitignore new file mode 100644 index 00000000..ba288ed3 --- /dev/null +++ b/examples/telegram_bot/.gitignore @@ -0,0 +1,7 @@ +__pycache__ +db +database +pyenv +venv +.env +trash_files/ diff --git a/examples/telegram_bot/README.md b/examples/telegram_bot/README.md new file mode 100644 index 00000000..21fc2df5 --- /dev/null +++ b/examples/telegram_bot/README.md @@ -0,0 +1,3 @@ +# Telegram Bot + +This is a replit template to create your own Telegram bot using the embedchain package. To know more about the bot and how to use it, go [here](https://docs.embedchain.ai/examples/telegram_bot). \ No newline at end of file diff --git a/examples/telegram_bot/requirements.txt b/examples/telegram_bot/requirements.txt new file mode 100644 index 00000000..3f661463 --- /dev/null +++ b/examples/telegram_bot/requirements.txt @@ -0,0 +1,4 @@ +flask==2.3.2 +requests==2.31.0 +python-dotenv==1.0.0 +embedchain \ No newline at end of file diff --git a/examples/telegram_bot/telegram_bot.py b/examples/telegram_bot/telegram_bot.py new file mode 100644 index 00000000..d81824dd --- /dev/null +++ b/examples/telegram_bot/telegram_bot.py @@ -0,0 +1,66 @@ +import os + +import requests +from dotenv import load_dotenv +from flask import Flask, request + +from embedchain import App + +app = Flask(__name__) +load_dotenv() +bot_token = os.environ["TELEGRAM_BOT_TOKEN"] +chat_bot = App() + + +@app.route("/", methods=["POST"]) +def telegram_webhook(): + data = request.json + message = data["message"] + chat_id = message["chat"]["id"] + text = message["text"] + if text.startswith("/start"): + response_text = ( + "Welcome to Embedchain Bot! Try the following commands to use the bot:\n" + "For adding data sources:\n /add \n" + "For asking queries:\n /query " + ) + elif text.startswith("/add"): + _, data_type, url_or_text = text.split(maxsplit=2) + response_text = add_to_chat_bot(data_type, url_or_text) + elif text.startswith("/query"): + _, question = text.split(maxsplit=1) + response_text = query_chat_bot(question) + else: + response_text = "Invalid command. Please refer to the documentation for correct syntax." + send_message(chat_id, response_text) + return "OK" + + +def add_to_chat_bot(data_type, url_or_text): + try: + chat_bot.add(data_type, url_or_text) + response_text = f"Added {data_type} : {url_or_text}" + except Exception as e: + response_text = f"Failed to add {data_type} : {url_or_text}" + print("Error occurred during 'add' command:", e) + return response_text + + +def query_chat_bot(question): + try: + response = chat_bot.chat(question) + response_text = response + except Exception as e: + response_text = "An error occurred. Please try again!" + print("Error occurred during 'query' command:", e) + return response_text + + +def send_message(chat_id, text): + url = f"https://api.telegram.org/bot{bot_token}/sendMessage" + data = {"chat_id": chat_id, "text": text} + requests.post(url, json=data) + + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000, debug=False) diff --git a/examples/telegram_bot/variables.env b/examples/telegram_bot/variables.env new file mode 100644 index 00000000..b4880368 --- /dev/null +++ b/examples/telegram_bot/variables.env @@ -0,0 +1,2 @@ +TELEGRAM_BOT_TOKEN="" +OPENAI_API_KEY="" \ No newline at end of file diff --git a/examples/whatsapp_bot/.gitignore b/examples/whatsapp_bot/.gitignore new file mode 100644 index 00000000..2227fe3e --- /dev/null +++ b/examples/whatsapp_bot/.gitignore @@ -0,0 +1,8 @@ +__pycache__ +db +database +pyenv +venv +.env +trash_files/ +.ideas.md \ No newline at end of file diff --git a/examples/whatsapp_bot/README.md b/examples/whatsapp_bot/README.md new file mode 100644 index 00000000..54cbf5c2 --- /dev/null +++ b/examples/whatsapp_bot/README.md @@ -0,0 +1,3 @@ +# WhatsApp Bot + +This is a replit template to create your own WhatsApp bot using the embedchain package. To know more about the bot and how to use it, go [here](https://docs.embedchain.ai/examples/whatsapp_bot). \ No newline at end of file diff --git a/examples/whatsapp_bot/requirements.txt b/examples/whatsapp_bot/requirements.txt new file mode 100644 index 00000000..ea251740 --- /dev/null +++ b/examples/whatsapp_bot/requirements.txt @@ -0,0 +1,3 @@ +Flask==2.3.2 +twilio==8.5.0 +embedchain \ No newline at end of file diff --git a/examples/whatsapp_bot/variables.env b/examples/whatsapp_bot/variables.env new file mode 100644 index 00000000..da672599 --- /dev/null +++ b/examples/whatsapp_bot/variables.env @@ -0,0 +1 @@ +OPENAI_API_KEY="" \ No newline at end of file diff --git a/examples/whatsapp_bot/whatsapp_bot.py b/examples/whatsapp_bot/whatsapp_bot.py new file mode 100644 index 00000000..d4d13a40 --- /dev/null +++ b/examples/whatsapp_bot/whatsapp_bot.py @@ -0,0 +1,51 @@ +from flask import Flask, request +from twilio.twiml.messaging_response import MessagingResponse + +from embedchain import App + +app = Flask(__name__) +chat_bot = App() + + +@app.route("/chat", methods=["POST"]) +def chat(): + incoming_message = request.values.get("Body", "").lower() + response = handle_message(incoming_message) + twilio_response = MessagingResponse() + twilio_response.message(response) + return str(twilio_response) + + +def handle_message(message): + if message.startswith("add "): + response = add_sources(message) + else: + response = query(message) + return response + + +def add_sources(message): + message_parts = message.split(" ", 2) + if len(message_parts) == 3: + data_type = message_parts[1] + url_or_text = message_parts[2] + try: + chat_bot.add(data_type, url_or_text) + response = f"Added {data_type}: {url_or_text}" + except Exception as e: + response = f"Failed to add {data_type}: {url_or_text}.\nError: {str(e)}" + else: + response = "Invalid 'add' command format.\nUse: add " + return response + + +def query(message): + try: + response = chat_bot.chat(message) + except Exception: + response = "An error occurred. Please try again!" + return response + + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000, debug=False)