Skip to content

Commit

Permalink
feat: Slack bot (mem0ai#469)
Browse files Browse the repository at this point in the history
Co-authored-by: Taranjeet Singh <[email protected]>
  • Loading branch information
cachho and taranjeet committed Sep 5, 2023
1 parent bd595f8 commit 3059e96
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 90 deletions.
26 changes: 12 additions & 14 deletions docs/examples/slack_bot.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,25 @@
title: '💼 Slack Bot'
---

### 🖼️ Template Setup
### 🖼️ 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`:
1. Create a workspace on Slack if you don't have one already by clicking [here](https://slack.com/intl/en-in/).
2. Create a new App on your Slack account by going [here](https://api.slack.com/apps).
3. Select `From Scratch`, then enter the Bot Name and select your workspace.
4. 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.
5. 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`.
6. Run your bot now with `python3 -m embedchain.bots.slack`
7. Expose your bot to the internet. Default port is `5000`, which can be changed by adding `port --8080` to the startup command. You can use your machine's public IP or DNS. Otherwise, employ a proxy server like [ngrok](https://ngrok.com/) to make your local bot accessible.
8. On the Slack API website go to `Event Subscriptions` on the left Sidebar and turn on `Enable Events`.
9. In `Request URL`, enter your server or ngrok address.
10. After it gets verified, click on `Subscribe to bot events`, add `message.channels` Bot User Event and click on `Save Changes`.
11. Now go to your workspace, right click on the bot name in the sidebar, click `view app details`, then `add this app to a channel`.

### 🚀 Usage Instructions

Expand Down
98 changes: 98 additions & 0 deletions embedchain/bots/slack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import argparse
import logging
import os
import signal
import sys

from embedchain import App
from embedchain.helper_classes.json_serializable import register_deserializable

from .base import BaseBot

try:
from flask import Flask, request
from slack_sdk import WebClient
except ModuleNotFoundError:
raise ModuleNotFoundError(
"The required dependencies for Slack are not installed." 'Please install with `pip install "embedchain[slack]"`'
) from None


SLACK_BOT_TOKEN = os.environ.get("SLACK_BOT_TOKEN")


@register_deserializable
class SlackBot(BaseBot):
def __init__(self):
self.client = WebClient(token=SLACK_BOT_TOKEN)
self.chat_bot = App()
self.recent_message = {"ts": 0, "channel": ""}
super().__init__()

def handle_message(self, event_data):
message = event_data.get("event")
if message and "text" in message and message.get("subtype") != "bot_message":
text: str = message["text"]
if float(message.get("ts")) > float(self.recent_message["ts"]):
self.recent_message["ts"] = message["ts"]
self.recent_message["channel"] = message["channel"]
if text.startswith("query"):
_, question = text.split(" ", 1)
try:
response = self.chat_bot.chat(question)
self.send_slack_message(message["channel"], response)
logging.info("Query answered successfully!")
except Exception as e:
self.send_slack_message(message["channel"], "An error occurred. Please try again!")
logging.error("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:
self.chat_bot.add(url_or_text, data_type)
self.send_slack_message(message["channel"], f"Added {data_type} : {url_or_text}")
except ValueError as e:
self.send_slack_message(message["channel"], f"Error: {str(e)}")
logging.error("Error occurred during 'add' command:", e)
except Exception as e:
self.send_slack_message(message["channel"], f"Failed to add {data_type} : {url_or_text}")
logging.error("Error occurred during 'add' command:", e)

def send_slack_message(self, channel, message):
response = self.client.chat_postMessage(channel=channel, text=message)
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 SlackBot...")
sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

@app.route("/", methods=["POST"])
def chat():
# Check if the request is a verification request
if request.json.get("challenge"):
return str(request.json.get("challenge"))

response = self.handle_message(request.json)
return str(response)

app.run(host=host, port=port, debug=debug)


def start_command():
parser = argparse.ArgumentParser(description="EmbedChain SlackBot 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()

slack_bot = SlackBot()
slack_bot.start(host=args.host, port=args.port)


if __name__ == "__main__":
start_command()
7 changes: 0 additions & 7 deletions examples/slack_bot/.gitignore

This file was deleted.

3 changes: 0 additions & 3 deletions examples/slack_bot/README.md

This file was deleted.

5 changes: 0 additions & 5 deletions examples/slack_bot/requirements.txt

This file was deleted.

58 changes: 0 additions & 58 deletions examples/slack_bot/slack_bot.py

This file was deleted.

3 changes: 0 additions & 3 deletions examples/slack_bot/variables.env

This file was deleted.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ flask = "^2.3.3"
twilio = "^8.5.0"
fastapi-poe = { version = "0.0.16", optional = true }
discord = { version = "^2.3.2", optional = true }
slack-sdk = { version = "3.21.3", optional = true }



Expand All @@ -121,6 +122,7 @@ opensource = ["sentence-transformers", "torch", "gpt4all"]
elasticsearch = ["elasticsearch"]
poe = ["fastapi-poe"]
discord = ["discord"]
slack = ["slack-sdk", "flask"]

[tool.poetry.group.docs.dependencies]

Expand Down

0 comments on commit 3059e96

Please sign in to comment.