{"id":22025277,"url":"https://github.com/gabrielkoo/chatgpt-faq-slack-bot","last_synced_at":"2025-05-07T09:34:48.668Z","repository":{"id":155151785,"uuid":"632505050","full_name":"gabrielkoo/chatgpt-faq-slack-bot","owner":"gabrielkoo","description":"A user-trainable Knowledge Base / FAQ Slack Bot on AWS SAM based on ChatGPT and Embeddings.","archived":false,"fork":false,"pushed_at":"2025-04-13T07:59:59.000Z","size":1026,"stargazers_count":21,"open_issues_count":9,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-13T08:42:58.972Z","etag":null,"topics":["aws","aws-lambda","chatbot","chatgpt","embedding","faq","kbqa","knowledge-base","openai","qna","question-answering","retrieval-augmented-generation","sam","serverless","slack","slack-bot","slackbot"],"latest_commit_sha":null,"homepage":"https://dev.to/aws-builders/enhance-your-slack-workspace-with-a-user-trainable-chatgpt-integrated-faq-bot-2pj3","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gabrielkoo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-04-25T14:43:55.000Z","updated_at":"2025-04-13T08:00:02.000Z","dependencies_parsed_at":"2025-04-13T08:47:49.933Z","dependency_job_id":null,"html_url":"https://github.com/gabrielkoo/chatgpt-faq-slack-bot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrielkoo%2Fchatgpt-faq-slack-bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrielkoo%2Fchatgpt-faq-slack-bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrielkoo%2Fchatgpt-faq-slack-bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrielkoo%2Fchatgpt-faq-slack-bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gabrielkoo","download_url":"https://codeload.github.com/gabrielkoo/chatgpt-faq-slack-bot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252851649,"owners_count":21814188,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","aws-lambda","chatbot","chatgpt","embedding","faq","kbqa","knowledge-base","openai","qna","question-answering","retrieval-augmented-generation","sam","serverless","slack","slack-bot","slackbot"],"created_at":"2024-11-30T07:15:31.049Z","updated_at":"2025-05-07T09:34:48.636Z","avatar_url":"https://github.com/gabrielkoo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chatgpt-faq-slack-bot\n\n![](https://img.shields.io/badge/Python-3776AB.svg?\u0026logo=Python\u0026logoColor=white)\n![](https://img.shields.io/badge/Serverless-FD5750.svg?\u0026logo=Serverless\u0026logoColor=white)\n![](https://img.shields.io/badge/AWS%20Lambda-FF9900.svg?\u0026logo=AWS-Lambda\u0026logoColor=white)\n![](https://img.shields.io/badge/Amazon%20S3-569A31.svg?\u0026logo=Amazon-S3\u0026logoColor=white)\n![](https://img.shields.io/badge/OpenAI-412991.svg?\u0026logo=OpenAI\u0026logoColor=white)\n![](https://img.shields.io/badge/Slack-4A154B.svg?\u0026logo=Slack\u0026logoColor=white)\n\n**UPDATE [2024-07-17]**: I have created another repo with similar functionality but with all AWS services only. Though it requires more experience on e.g. AWS VPC and Amazon Aurora's query editor, but it should be more robust and scalable than the solution in this repo. Do take a look! [gabrielkoo/self-learning-rag-it-support-slackbot](https://github.com/gabrielkoo/self-learning-rag-it-support-slackbot).\n\n---\n\nThe bot uses ChatGPT to answer based on your own FAQ database, while allowing users to submit new articles into it with a [Slash Command](https://slack.com/help/articles/201259356-Slash-commands-in-Slack), so that it can answer with new knowledge **immediately**, as it updates the model **on the fly in the cloud**!\n\nRead my [dev.to](https://dev.to) article below to know more about why and how I created this solution!\n\nI have also included a pricing estimate on the cost breakdown of using this solution (it's at US$0.009 per question as of Apr 2023 pricings).\n\nhttps://dev.to/aws-builders/enhance-your-slack-workspace-with-a-user-trainable-chatgpt-integrated-faq-bot-2pj3\n\n## Example\n\nA sample dataset is included in the `./sample_data` directory, and it's built based on Wikipedia pages on the Disney+ series \"The Mandalorian\".\n\nSo it does know who is Grogu:\n![Who is Grogu](docs/who-is-grogu.png)\n\nBut doesn't know who I am:\n![Who is Gabriel Koo](docs/who-is-gabriel-koo.png)\n\nSo I can submit a new article to the bot:\n![Submit a new article](docs/submit-new-article.png)\n\nAnd now the bot knows how to answer my question:\n![Who is Gabriel Koo](docs/answer-with-new-article.png)\n\n## Background\n\nSince ChatGPT's API became available in 2023 Mar, the world has been of great hype on building a lot of great integrations around it. Two of these integrations are especially appealing to me:\n\n1. [Combing Embedding Search with ChatGPT](https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb) to build a FAQ engine - it's a way of:\n[Knowledge Base Question Answering (KBQA)](https://arxiv.org/pdf/2108.06688.pdf) - combining\n\n   - natural language understanding (via a text embedding on the question)\n   - information retrieval (via a text embedding on the articles, matches  against the one for the question)\n   - knowledge representation (via ChatGPT with the selected information)\n\n2. Connecting the AI with a programmable messaging platform like Slack\n\nBut so far, I have not seen any open-source project that:\n\n1. combines the two together\n2. provides a easy hosting method like AWS SAM, and lastly\n3. provides a functionality to **let the user submit extra knowledge into the embedding dataset**.\n\nThe **3rd** point is very important to me, because in this post-OpenAI era, you should no longer rely on an expensive data scientist to build a FAQ engine for you. Instead, you should let your users submit their own knowledge into the dataset, so that the AI can learn from the collective intelligence of your users.\n\nSo I decided to build one myself.\n\n## Architecture and Infrastructure\n\nThe infrastructure is built with AWS SAM, and it consists of the following components:\n\n- A Lambda function that handles the Slack API requests, it's possible with the new [Function URL](https://aws.amazon.com/blogs/aws/announcing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices/) feature that was released in 2022. This saves us from the trouble of setting up an API Gateway.\n- A AWS S3 bucket to store the datafiles, that includes a CSV file of the articles, and a CSV file of the document embeddings.\n\nYeah that's it! With [AWS SAM](https://aws.amazon.com/serverless/sam/), things are simply so simple, and all these are defined in `template.yml`.\n\n![Architecture Diagram](docs/architecture-diagram.jpg)\n\nSequence diagram for the Q\u0026A flow:\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant Slack\n    box gray AWS SAM\n        participant Lambda\n        participant S3Bucket\n    end\n    participant OpenAI\n\n    User-\u003e\u003eSlack: Asks a question\n    Slack-\u003e\u003eLambda: POST request with question\n    Lambda-\u003e\u003eS3Bucket: Fetch FAQ datafile and text embeddings\n    S3Bucket-\u003e\u003eLambda: Returns data files\n    Lambda-\u003e\u003eOpenAI: 1) Create a text embedding of the question\n    OpenAI-\u003e\u003eLambda: Returns text embedding of the question\n    Lambda-\u003e\u003eLambda: 2) Match embeddings and find relevant FAQ articles\n    Lambda-\u003e\u003eOpenAI: 3) Feed question and relevant articles to ChatGPT\n    OpenAI-\u003e\u003eLambda: Returns response\n    Lambda-\u003e\u003eSlack: Returns answer based on FAQ dataset\n    Slack-\u003e\u003eUser: Replies with the answer\n```\n\nSequence diagram for the new training article submission flow:\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant Slack\n    box gray AWS SAM\n        participant Lambda\n        participant S3Bucket\n    end\n    participant OpenAI\n\n    User-\u003e\u003eSlack: /submit_train_article command\n    Slack-\u003e\u003eLambda: POST request with open modal request\n    Lambda-\u003e\u003eSlack: Returns modal configuration\n    Slack-\u003e\u003eUser: Shows modal with form fields\n    User-\u003e\u003eSlack: Fills in the form fields of the new article\n    Slack-\u003e\u003eLambda: POST request with the article\n    Lambda-\u003e\u003eS3Bucket: Fetch FAQ datafile and text embeddings\n    S3Bucket-\u003e\u003eLambda: Returns data files\n    Lambda-\u003e\u003eOpenAI: Compute text embedding for new article\n    OpenAI-\u003e\u003eLambda: Returns text embedding for new article\n    Lambda-\u003e\u003eS3Bucket: Update FAQ CSV file and embeddings file\n    S3Bucket-\u003e\u003eLambda: Confirm update\n    Lambda-\u003e\u003eSlack: Returns success message\n    Slack-\u003e\u003eUser: Replies with success message\n```\n\n## Pre-requisites\n\n- Prepare a `.env` file at the root directory, according to the template `.env.example`.\n- AWS SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)\n- Docker - [Install Docker](https://docs.docker.com/get-docker/)\n- An OpenAI API Key\n  - [Get an OpenAI API Key](https://platform.openai.com/docs/api-reference/authentication) and put it in the `OPENAI_API_KEY` environment variable.\n  - Alternatively, you can also get one from Azure if you have access to the [Azure OpenAI Service](https://azure.microsoft.com/en-us/products/cognitive-services/openai-service).\n- A Slack App - [Create a Slack App](https://api.slack.com/apps?new_app=1)\n\n### Create a Slack App\n\n![Create a Slack App](docs/slack-create-new-app.png)\n\nThe following scopes are required (Configure in the \"OAuth \u0026 Permissions\" page \u003e \"Scopes\" \u003e \"Bot Token Scopes\"):\n\n- `chat:write`\n- `commands`\n- `im:history`\n- `im:write`\n\nThe following event subscriptions are required:\n(but you can't set these yet until the deployment of the AWS SAM infrastructure is done):\n\n- `message.channels`\n- `message.groups`\n- `message.im`\n- `message.mpim`\n\nEnable \"Allow users to send commands and messages from the messages tab” in the “App Home” settings.\n![Enable \"Allow users to send commands and messages from the messages tab” in the “App Home” settings](docs/slack-allow-user-messages.png)\n\nLastly, make sure to install the app to your workspace\n![Install the app to your workspace](docs/slack-create-new-app.png)\n\nPrepare the following environment varaibles into the `.env` file\n\n- put the bot OAuth token as `SLACK_BOT_TOKEN`\n- the signing secret as `SLACK_SIGNING_SECRET`\n\n## Build and deploy\n\n1. Setup your shell for AWS credentials. There are various ways of doing so, and you may refer to [this documnetation](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-authentication.html).\n\n   For example, you may run `aws sso login --profile name-of-your-profile` if you have configured your AWS credentials with AWS Identity Center (originally named AWS SSO) before.\n2. Run the `./deploy.sh` script, it will provision everything for you.\n\nAfter the deployment, you still need to manually upload the initial datafiles.\n\n## Prepare the datafiles\n\n- Prepare a file in `.data/articles.csv`, with three columns `(title, heading, content)`.\n\n   ```bash\n   #!/bin/bash\n   cd function\n   export LOCAL_DATA_PATH=./\n   python3 -c 'from embedding import *; prepare_document_embeddings()'\n   ```\n\n   Be sure to escape e.g. newline characters into `\\n` in the `column` field.\n\n   Then, a file should be created at `./data/document_embeddings.csv`.\n- Upload both files onto the S3 bucket that was created by the CloudFormation template, at the following paths:\n  - `s3://$DATAFILE_S3_BUCKET/data/articles.csv`\n  - `s3://$DATAFILE_S3_BUCKET/data/document_embeddings.csv`\n\n  If you want to use the command line, you can run the following command:\n\n  ```bash\n  aws s3 cp --recursive ./function/data/*.csv s3://$DATAFILE_S3_BUCKET/data/\n  ```\n\nThat's it!\n\nIf you want to be a bit lazy and start with my sample data, just run the following command instead\n\n```bash\naws s3 cp --recursive ./sample_data/*.csv s3://$DATAFILE_S3_BUCKET/data/\n```\n\n## Making Everything End-to-End\n\n1. Go to the `Outputs` tab of the deployed CloudFormation template (e.g. `https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks`), copy the URL value of `FunctionUrlEndpoint`.\n2. Go back to the config page of your custom Slack App, and paste it at\n\n   \"Event Subscriptions\" \u003e \"Enable Events\" \u003e \"Request URL\" and verify it.\n3. Once done, you can go to Slack and try messaging your bot with a question that is supposed to be answerable with the help of your own FAQ dataset!\n\n## Setting up the `/submit_train_article` command\n\nIn addition you can also create a `/submit_train_article` slack command so that your users can self-serve submit extra articles into the dataset. The handlers are defined in the following methods of `lambda_function.py`: `handle_submit_train_article_command` and `handle_submit_train_article_submission`.\n\n### Setup\n\n- In your Slack App's config, go to `Features` \u003e `Slack Commands` \u003e `Create New Command`\n- After the modal is opened, enter the following details:\n  - Command: `/submit_train_article`\n  - Request URL: Paste the value of `FunctionUrlEndpoint`\n- Then click \"Save\".\n\n## TODO\n\n- [ ] Use AWS System Manager Parameter Store instead of plaintext Lambda environment variables - [Tutorial Here](https://docs.aws.amazon.com/systems-manager/latest/userguide/ps-integration-lambda-extensions.html)\n- [ ] Use API Gateway instead of Lambda function Urls - [AWS SAM Example](https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway-template.html)\n- [ ] Add a WAF to the API Gateway - [Documentation](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-aws-waf.html)\n- [ ] Put the whole setup into an AWS VPC - [Documentation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#:~:text=Lambda%3A%3AVersion%20resource.-,VpcConfig,-The%20configuration%20that)\n- [ ] Switch to AWS EFS for the datafiles - [Documentation](https://aws.amazon.com/blogs/compute/using-amazon-efs-for-aws-lambda-in-your-serverless-applications/)\n- [ ] Preserve user's message context with DynamoDB - [Documentation](https://docs.aws.amazon.com/lambda/latest/dg/kinesis-tutorial-spec.html)\n\n## Thanks\n\nThis project is based on the following projects:\n\n- [openai/openai-cookbook - \"Embedding Wikipedia articles for search\"](https://github.com/openai/openai-cookbook/blob/d67c4181abe9dfd871d382930bb778b7014edc66/examples/Embedding_Wikipedia_articles_for_search.ipynb)\n- [openai/openai-cookbook - \"Question answering using embeddings-based search\"](https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb)\n- [Slack Bolt Examples - AWS Lambda](https://github.com/slackapi/bolt-python/blob/main/examples/aws_lambda/aws_lambda.py)\n- [OpenAI - Introducing text and code embeddings](https://openai.com/blog/introducing-text-and-code-embeddings)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrielkoo%2Fchatgpt-faq-slack-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgabrielkoo%2Fchatgpt-faq-slack-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrielkoo%2Fchatgpt-faq-slack-bot/lists"}