From 94a0238152a98f1f2e75eff492d2920b6e99cc69 Mon Sep 17 00:00:00 2001 From: Pratya Thanwatthanakit <43605404+l0ginp@users.noreply.github.com> Date: Sun, 12 Mar 2023 19:10:28 +0700 Subject: [PATCH 01/14] fix docker-compose build error fix build.context --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3e44b54..e1ba864 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.9" services: chatgptslackbot: build: - context: ./ + context: . image: chatgptslackbot restart: always container_name: chatgptslackbot From afc72565e36d7c8fa1a1d8001bf6360422e19d32 Mon Sep 17 00:00:00 2001 From: Gonzalo Sanchez <gonchi.sanchez@gmail.com> Date: Fri, 17 Mar 2023 15:11:08 -0300 Subject: [PATCH 02/14] Make it less verbose --- app.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app.py b/app.py index 1cf6fd7..8d50add 100644 --- a/app.py +++ b/app.py @@ -7,26 +7,23 @@ from slack_bolt import App ChatGPTConfig = { - "api_key": os.getenv("OPENAI_API_KEY"), - } + "api_key": os.getenv("OPENAI_API_KEY"), +} + if os.getenv("OPENAI_ENGINE"): ChatGPTConfig["engine"] = os.getenv("OPENAI_ENGINE") app = App() chatbot = Chatbot(**ChatGPTConfig) -# Listen for an event from the Events API + @app.event("app_mention") def event_test(event, say): prompt = re.sub('(?:\s)<@[^, ]*|(?:^)<@[^, ]*', '', event['text']) try: response = chatbot.ask(prompt) user = event['user'] - user = f"<@{user}> you asked:" - asked = ['>',prompt] - asked = "".join(asked) - send = [user,asked,response] - send = "\n".join(send) + send = f"@{user}: {response}" except Exception as e: print(e) send = "We're experiencing exceptionally high demand. Please, try again." @@ -37,10 +34,12 @@ def event_test(event, say): # Use the `app.event` method to send a reply to the message thread say(send, thread_ts=original_message_ts) + def chatgpt_refresh(): while True: time.sleep(60) + if __name__ == "__main__": thread = Thread(target=chatgpt_refresh) thread.start() From e7e689be180b0597f2548e026f409728b2a2b9fe Mon Sep 17 00:00:00 2001 From: Brian Marks <brian.marks@taxbit.com> Date: Tue, 21 Mar 2023 17:20:49 -0400 Subject: [PATCH 03/14] Minor improvements for Slack app --- .gitignore | 3 +++ Dockerfile | 3 ++- app.py | 4 ++-- docker-compose.yml | 2 +- requirements.txt | 2 +- variables.env | 3 +-- 6 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e943ff7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# JetBrains IDE +.idea/ +*.iml diff --git a/Dockerfile b/Dockerfile index 077645b..7fef936 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,10 +3,11 @@ FROM python WORKDIR /app RUN curl https://sh.rustup.rs -sSf | bash -s -- -y ENV PATH="/root/.cargo/bin:${PATH}" -COPY app.py /app COPY requirements.txt /app RUN pip install -r requirements.txt +COPY app.py /app + ENTRYPOINT ["python"] CMD ["app.py"] diff --git a/app.py b/app.py index 8d50add..5fc691d 100644 --- a/app.py +++ b/app.py @@ -19,11 +19,11 @@ @app.event("app_mention") def event_test(event, say): - prompt = re.sub('(?:\s)<@[^, ]*|(?:^)<@[^, ]*', '', event['text']) + prompt = re.sub('\\s<@[^, ]*|^<@[^, ]*', '', event['text']) try: response = chatbot.ask(prompt) user = event['user'] - send = f"@{user}: {response}" + send = f"<@{user}> {response}" except Exception as e: print(e) send = "We're experiencing exceptionally high demand. Please, try again." diff --git a/docker-compose.yml b/docker-compose.yml index e1ba864..1c5acd3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,4 +9,4 @@ services: env_file: - ./variables.env ports: - - 4000:4000 + - "4000:4000" diff --git a/requirements.txt b/requirements.txt index e02db2f..0ac2b46 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -slack_bolt +slack_bolt>=1.0.0 revChatGPT>=3.0.0 diff --git a/variables.env b/variables.env index 9b6e442..5d2f2e1 100644 --- a/variables.env +++ b/variables.env @@ -1,4 +1,3 @@ SLACK_SIGNING_SECRET= SLACK_BOT_TOKEN= -CHATGPT_EMAIL= -CHATGPT_PASSWORD= +OPENAI_API_KEY= From 70c14c6f643e46ae4121165b250b6141e01085bb Mon Sep 17 00:00:00 2001 From: Big <Big@Coralines-MacBook-Air.local> Date: Wed, 29 Mar 2023 16:00:53 +0700 Subject: [PATCH 04/14] add support dirrect message --- app.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app.py b/app.py index 5fc691d..26ee95c 100644 --- a/app.py +++ b/app.py @@ -34,6 +34,19 @@ def event_test(event, say): # Use the `app.event` method to send a reply to the message thread say(send, thread_ts=original_message_ts) +@app.event("message") +def event_test(event, say): + prompt = re.sub('\\s<@[^, ]*|^<@[^, ]*', '', event['text']) + try: + response = chatbot.ask(prompt) + user = event['user'] + send = response + except Exception as e: + print(e) + send = "We're experiencing exceptionally high demand. Please, try again." + + # reply message to new message + say(send) def chatgpt_refresh(): while True: From 3a79e3d61bf04809c47344eb6842c833dad2f1de Mon Sep 17 00:00:00 2001 From: Big <Big@Coralines-MacBook-Air.local> Date: Wed, 29 Mar 2023 16:10:58 +0700 Subject: [PATCH 05/14] add direct messages config --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index e4fe2ac..e7fb48e 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,10 @@ For this bot, the required Scopes in `OAuth & Permissions` are: * chat:write * im:write +For direct message required & config : +* `Enable bot direct messages` go to : Features -> App Home -> (Enable) Messages Tab +* `OAuth & Permissions` im:history + In the `Event Subscriptions`, you need to subscribe to the `app_mention` event. ## Limitations From 9698ff952e2ded05b7ddffeb942354a1b4f3c0e9 Mon Sep 17 00:00:00 2001 From: Raymond Chen <rchen@sonatype.com> Date: Sat, 15 Apr 2023 17:31:23 -0400 Subject: [PATCH 06/14] Add missing permission message:im --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e7fb48e..5918011 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ For this bot, the required Scopes in `OAuth & Permissions` are: For direct message required & config : * `Enable bot direct messages` go to : Features -> App Home -> (Enable) Messages Tab -* `OAuth & Permissions` im:history +* `OAuth & Permissions` im:history and message:im In the `Event Subscriptions`, you need to subscribe to the `app_mention` event. From ce6c0a4fbb04e10de0dde942ca1fa6be1d195e5e Mon Sep 17 00:00:00 2001 From: Pedro Rito <pedrorito@me.com> Date: Mon, 17 Apr 2023 20:32:24 +0100 Subject: [PATCH 07/14] Update README.md --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5918011..041f1b5 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The `revChatGPT` package is used to handle authentication and communication with ## Usage -To use the bot, you will need to install the dependencies and set the `CHATGPT_EMAIL` and `CHATGPT_PASSWORD` environment variables with your OpenAI credentials. You also need to set `SLACK_SIGNING_SECRET` and `SLACK_BOT_TOKEN` environment variables after creating the Slack App. You can then run the `app.py` script to start the bot. +To use the bot, you will need to install the dependencies and set the `OPENAI_API_KEY` environment variable that you can get from https://platform.openai.com/account/api-keys. You also need to set `SLACK_SIGNING_SECRET` and `SLACK_BOT_TOKEN` environment variables after creating the Slack App. You can then run the `app.py` script to start the bot. ```python pip install -r requirements.txt @@ -30,7 +30,7 @@ Once the bot is running, you can mention it in a Slack channel to send it a mess ## ChatGPT Configuration -The `ChatGPTConfig` dictionary at the top of the `app.py` script contains the configuration for the `revChatGPT` package. It specifies the email and password for the OpenAI account that the bot will use to authenticate with the GPT-3 API. These values are read from the `CHATGPT_EMAIL` and `CHATGPT_PASSWORD` environment variables. +The `ChatGPTConfig` dictionary at the top of the `app.py` script contains the configuration for the `revChatGPT` package. It specifies the API token for for the OpenAI account that the bot will use to authenticate with the GPT-3 API. The value is read from the `OPENAI_API_KEY` environment variable. The `conversation_id` parameter in the `Chatbot` constructor is used to specify the ID of the conversation that the bot should use. If this parameter is not provided, the `revChatGPT` package will generate a new conversation ID for each message that the bot receives. @@ -55,8 +55,6 @@ In the `Event Subscriptions`, you need to subscribe to the `app_mention` event. The bot uses a pre-trained GPT-3 model, which means that its responses are limited to the information that is contained in the model. It may not be able to respond accurately to messages that are outside of the scope of the pre-trained model. -Additionally, the bot is only designed to handle `app_mention` events, so it will not respond to other types of messages. This can be easily extended by adding more event handlers to the `app.py` script. - ## Notes The `tls-client` python library that is used by the `revChatGPT` package does not currently support ARM architectures. As a result, the bot may not be able to run on devices with ARM processors. This limitation will be addressed in a future update. From a5b0f1992331bc9983004cad82095767a9f76952 Mon Sep 17 00:00:00 2001 From: Brian Marks <brian.marks@taxbit.com> Date: Fri, 5 May 2023 14:48:03 -0400 Subject: [PATCH 08/14] Add health check endpoint at base for easy verification --- app.py | 8 ++++++++ requirements.txt | 1 + 2 files changed, 9 insertions(+) diff --git a/app.py b/app.py index 26ee95c..f41f804 100644 --- a/app.py +++ b/app.py @@ -2,6 +2,7 @@ import re import time from threading import Thread +from flask import Flask from revChatGPT.V3 import Chatbot from slack_bolt import App @@ -15,6 +16,7 @@ app = App() chatbot = Chatbot(**ChatGPTConfig) +flask_app = Flask(__name__) @app.event("app_mention") @@ -48,6 +50,12 @@ def event_test(event, say): # reply message to new message say(send) + +@flask_app.route("/", methods=["GET"]) +def health(): + return "" + + def chatgpt_refresh(): while True: time.sleep(60) diff --git a/requirements.txt b/requirements.txt index 0ac2b46..cf8a699 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ slack_bolt>=1.0.0 revChatGPT>=3.0.0 +flask>=2.0.0 From 8c025a2c72604c8b0488198c8ecf5f7cc8f3fbe2 Mon Sep 17 00:00:00 2001 From: Brian Marks <brian.marks@taxbit.com> Date: Fri, 5 May 2023 15:18:50 -0400 Subject: [PATCH 09/14] Clean up duplicate code --- app.py | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/app.py b/app.py index f41f804..0da408f 100644 --- a/app.py +++ b/app.py @@ -19,36 +19,38 @@ flask_app = Flask(__name__) -@app.event("app_mention") -def event_test(event, say): +def handle_event(event, say, is_mention): prompt = re.sub('\\s<@[^, ]*|^<@[^, ]*', '', event['text']) try: response = chatbot.ask(prompt) user = event['user'] - send = f"<@{user}> {response}" + + if is_mention: + send = f"<@{user}> {response}" + else: + send = response except Exception as e: print(e) send = "We're experiencing exceptionally high demand. Please, try again." - # Get the `ts` value of the original message - original_message_ts = event["ts"] + if is_mention: + # Get the `ts` value of the original message + original_message_ts = event["ts"] + else: + original_message_ts = None - # Use the `app.event` method to send a reply to the message thread + # Use the `app.event` method to send a message say(send, thread_ts=original_message_ts) -@app.event("message") -def event_test(event, say): - prompt = re.sub('\\s<@[^, ]*|^<@[^, ]*', '', event['text']) - try: - response = chatbot.ask(prompt) - user = event['user'] - send = response - except Exception as e: - print(e) - send = "We're experiencing exceptionally high demand. Please, try again." - # reply message to new message - say(send) +@app.event("app_mention") +def handle_mention(event, say): + handle_event(event, say, is_mention=True) + + +@app.event("message") +def handle_message(event, say): + handle_event(event, say, is_mention=False) @flask_app.route("/", methods=["GET"]) From bb47a9fb0cf93bc97085a66aa05034ff30ad13ab Mon Sep 17 00:00:00 2001 From: Brian Marks <brian.marks@taxbit.com> Date: Fri, 5 May 2023 15:19:48 -0400 Subject: [PATCH 10/14] Fix README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 041f1b5..49b6298 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The `revChatGPT` package is used to handle authentication and communication with To use the bot, you will need to install the dependencies and set the `OPENAI_API_KEY` environment variable that you can get from https://platform.openai.com/account/api-keys. You also need to set `SLACK_SIGNING_SECRET` and `SLACK_BOT_TOKEN` environment variables after creating the Slack App. You can then run the `app.py` script to start the bot. -```python +```bash pip install -r requirements.txt export SLACK_SIGNING_SECRET=slack_signing_secret export SLACK_BOT_TOKEN=slack_bot_token @@ -30,7 +30,7 @@ Once the bot is running, you can mention it in a Slack channel to send it a mess ## ChatGPT Configuration -The `ChatGPTConfig` dictionary at the top of the `app.py` script contains the configuration for the `revChatGPT` package. It specifies the API token for for the OpenAI account that the bot will use to authenticate with the GPT-3 API. The value is read from the `OPENAI_API_KEY` environment variable. +The `ChatGPTConfig` dictionary at the top of the `app.py` script contains the configuration for the `revChatGPT` package. It specifies the API token for the OpenAI account that the bot will use to authenticate with the GPT-3 API. The value is read from the `OPENAI_API_KEY` environment variable. The `conversation_id` parameter in the `Chatbot` constructor is used to specify the ID of the conversation that the bot should use. If this parameter is not provided, the `revChatGPT` package will generate a new conversation ID for each message that the bot receives. @@ -53,7 +53,7 @@ In the `Event Subscriptions`, you need to subscribe to the `app_mention` event. ## Limitations -The bot uses a pre-trained GPT-3 model, which means that its responses are limited to the information that is contained in the model. It may not be able to respond accurately to messages that are outside of the scope of the pre-trained model. +The bot uses a pre-trained GPT-3 model, which means that its responses are limited to the information that is contained in the model. It may not be able to respond accurately to messages that are outside the scope of the pre-trained model. ## Notes From a3672b9294a205afa0932f1011842cb1e372f4c5 Mon Sep 17 00:00:00 2001 From: Brian Marks <brian.marks@taxbit.com> Date: Tue, 9 May 2023 15:55:01 -0400 Subject: [PATCH 11/14] Separate conversations by threads --- app.py | 16 +++++++++++----- requirements.txt | 6 +++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/app.py b/app.py index 0da408f..6c8e9f4 100644 --- a/app.py +++ b/app.py @@ -1,5 +1,6 @@ import os import re +import sys import time from threading import Thread from flask import Flask @@ -20,18 +21,22 @@ def handle_event(event, say, is_mention): - prompt = re.sub('\\s<@[^, ]*|^<@[^, ]*', '', event['text']) + prompt = re.sub("\\s<@[^, ]*|^<@[^, ]*", "", event["text"]) + + # Each thread should be a separate conversation + convo_id = event.get("thread_ts") or event.get("ts") or "" + try: - response = chatbot.ask(prompt) - user = event['user'] + response = chatbot.ask(prompt, convo_id=convo_id) + user = event["user"] if is_mention: send = f"<@{user}> {response}" else: send = response except Exception as e: - print(e) - send = "We're experiencing exceptionally high demand. Please, try again." + print(e, file=sys.stderr) + send = "We are experiencing exceptionally high demand. Please, try again." if is_mention: # Get the `ts` value of the original message @@ -64,6 +69,7 @@ def chatgpt_refresh(): if __name__ == "__main__": + print("Bot Started!", file=sys.stderr) thread = Thread(target=chatgpt_refresh) thread.start() app.start(4000) # POST http://localhost:4000/slack/events diff --git a/requirements.txt b/requirements.txt index cf8a699..4bc810c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -slack_bolt>=1.0.0 -revChatGPT>=3.0.0 -flask>=2.0.0 +slack_bolt==1.18.0 +revChatGPT==5.0.0 +flask==2.3.2 From 559be952a66dd72e4ec5b7d9617d886c8748be36 Mon Sep 17 00:00:00 2001 From: Brian Marks <brian.marks@taxbit.com> Date: Tue, 9 May 2023 17:24:26 -0400 Subject: [PATCH 12/14] Remove health checks --- app.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app.py b/app.py index 6c8e9f4..2f91715 100644 --- a/app.py +++ b/app.py @@ -3,7 +3,6 @@ import sys import time from threading import Thread -from flask import Flask from revChatGPT.V3 import Chatbot from slack_bolt import App @@ -17,7 +16,6 @@ app = App() chatbot = Chatbot(**ChatGPTConfig) -flask_app = Flask(__name__) def handle_event(event, say, is_mention): @@ -58,11 +56,6 @@ def handle_message(event, say): handle_event(event, say, is_mention=False) -@flask_app.route("/", methods=["GET"]) -def health(): - return "" - - def chatgpt_refresh(): while True: time.sleep(60) From 0e7d3a569530c56771ffe878094c38a1437da7c4 Mon Sep 17 00:00:00 2001 From: Brian Marks <brian.marks@taxbit.com> Date: Tue, 9 May 2023 19:32:03 -0400 Subject: [PATCH 13/14] Add health check on another port --- app.py | 19 ++++++++++++------- docker-compose.yml | 1 + 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app.py b/app.py index 2f91715..49b9d31 100644 --- a/app.py +++ b/app.py @@ -1,9 +1,9 @@ import os import re import sys -import time from threading import Thread +from flask import Flask from revChatGPT.V3 import Chatbot from slack_bolt import App @@ -14,6 +14,7 @@ if os.getenv("OPENAI_ENGINE"): ChatGPTConfig["engine"] = os.getenv("OPENAI_ENGINE") +flask_app = Flask(__name__) app = App() chatbot = Chatbot(**ChatGPTConfig) @@ -56,13 +57,17 @@ def handle_message(event, say): handle_event(event, say, is_mention=False) -def chatgpt_refresh(): - while True: - time.sleep(60) +def start_flask_app(): + flask_app.run(host='0.0.0.0', port=3000) + + +# Define a health check route that returns a 200 HTTP response code +@flask_app.route('/health', methods=['GET']) +def health_check(): + return 'Bot is healthy' if __name__ == "__main__": print("Bot Started!", file=sys.stderr) - thread = Thread(target=chatgpt_refresh) - thread.start() - app.start(4000) # POST http://localhost:4000/slack/events + thread = Thread(target=start_flask_app).start() + app.start(port=4000) # POST http://localhost:4000/slack/events diff --git a/docker-compose.yml b/docker-compose.yml index 1c5acd3..23fc332 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,4 +9,5 @@ services: env_file: - ./variables.env ports: + - "3000:3000" - "4000:4000" From 446e95dce077f54752c647f83846e820e7d25de6 Mon Sep 17 00:00:00 2001 From: Brian Marks <brian.marks@taxbit.com> Date: Tue, 9 May 2023 19:58:56 -0400 Subject: [PATCH 14/14] Revert "Add health check on another port" This reverts commit 0e7d3a569530c56771ffe878094c38a1437da7c4. --- app.py | 19 +++++++------------ docker-compose.yml | 1 - 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/app.py b/app.py index 49b9d31..2f91715 100644 --- a/app.py +++ b/app.py @@ -1,9 +1,9 @@ import os import re import sys +import time from threading import Thread -from flask import Flask from revChatGPT.V3 import Chatbot from slack_bolt import App @@ -14,7 +14,6 @@ if os.getenv("OPENAI_ENGINE"): ChatGPTConfig["engine"] = os.getenv("OPENAI_ENGINE") -flask_app = Flask(__name__) app = App() chatbot = Chatbot(**ChatGPTConfig) @@ -57,17 +56,13 @@ def handle_message(event, say): handle_event(event, say, is_mention=False) -def start_flask_app(): - flask_app.run(host='0.0.0.0', port=3000) - - -# Define a health check route that returns a 200 HTTP response code -@flask_app.route('/health', methods=['GET']) -def health_check(): - return 'Bot is healthy' +def chatgpt_refresh(): + while True: + time.sleep(60) if __name__ == "__main__": print("Bot Started!", file=sys.stderr) - thread = Thread(target=start_flask_app).start() - app.start(port=4000) # POST http://localhost:4000/slack/events + thread = Thread(target=chatgpt_refresh) + thread.start() + app.start(4000) # POST http://localhost:4000/slack/events diff --git a/docker-compose.yml b/docker-compose.yml index 23fc332..1c5acd3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,5 +9,4 @@ services: env_file: - ./variables.env ports: - - "3000:3000" - "4000:4000"