seratch/ChatGPT-in-Slack

Instructions to deploy it in AWS Lambda func please :)

QAInsights opened this issue · 4 comments

⬆️

Hi @QAInsights, thanks for asking the question!

The OAuth-enabled app (the same with the live demo app)

The OAuth-enabled live demo app is running on AWS Lambda + S3. If you want to run the same one, first off, you can create a new Slack app configuration using https://github.com/seratch/ChatGPT-in-Slack/blob/main/manifest-prod.yml The TODO.amazonaws.com URLs need to be updated later.

And then, the steps here should work for you. here are the same commands with comments:

# You can find these three crendentials in your Slack app admin page
export SLACK_CLIENT_ID=
export SLACK_CLIENT_SECRET=
export SLACK_SIGNING_SECRET=

# This list is static
export SLACK_SCOPES=app_mentions:read,channels:history,groups:history,im:history,mpim:history,chat:write.public,chat:write

# Create these three S3 buckets beforehand
export SLACK_INSTALLATION_S3_BUCKET_NAME=
export SLACK_STATE_S3_BUCKET_NAME=
export OPENAI_S3_BUCKET_NAME=

# Install serverless framework and its required plugin
npm install -g serverless
serverless plugin install -n serverless-python-requirements

# Deploy the app with above env variables
serverless deploy

Once the app is deployed, you will see three URLs on the terminal console.

endpoints:
  POST - https://xxx.amazonaws.com/slack/events
  GET - https://xxx.amazonaws.com/slack/install
  GET - https://xxx.amazonaws.com/slack/oauth_redirect

Use these URLs for Request URLs and OAuth Redirect URL.

  • https://xxx.amazonaws.com/slack/events - you can set all the Request URLs in your Slack app admin pages (Interactivity & Shortcuts, Event Subscriptions)
  • https://xxx.amazonaws.com/slack/oauth_redirect - You can set OAuth Redirect URL to this one

Once all the above are ready, you can visit the /slack/install URL to start the installation folow.

  • https://xxx.amazonaws.com/slack/install - No need to set this URL in the admin page; Your end-users can visit this URL to start the installation flow

Single-workspace app (internal app only for your workspace)

If you want to deploy the app with a single OpenAI auth key for a specific workspace, the procedure can be bit simpler.

  • Remove the oauth_config.redirect_urls from the App Manifest YAML, and then create a new app settings with it
  • Install the app from the admin page and save the bot user token as SLACK_BOT_TOKEN env variable
  • Head to Basic Settings section in the admin page and save Signing Secret as SLACK_SIGNING_SECRET env variable
  • Set OPENAI_API_KEY env variable

Here are the commands for the above.

# You can find these crendentials in your Slack app admin page
export SLACK_BOT_TOKEN=
export SLACK_SIGNING_SECRET=

# You can grab this API key in the OpenAI user page
export OPENAI_API_KEY=

With the above, your serverless.yml can be quite simple as below:

frameworkVersion: '3'
service: slack-chat-gpt-bot
provider:
  name: aws
  runtime: python3.9
  region: us-east-1
  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - lambda:InvokeFunction
            - lambda:InvokeAsync
          Resource: "*"
  environment:
    SERVERLESS_STAGE: ${opt:stage, 'prod'}
    SLACK_SIGNING_SECRET: ${env:SLACK_SIGNING_SECRET}
    SLACK_BOT_TOKEN: ${env:SLACK_BOT_TOKEN}
    OPENAI_API_KEY: ${env:OPENAI_API_KEY}
    OPENAI_TIMEOUT_SECONDS: 10

functions:
  app:
    handler: app_prod.handler
    timeout: 12
    events:
      - httpApi:
          path: /slack/events
          method: post

package:
  patterns:
    - "!.venv/**"
    - "!node_modules/**"
    - "!.idea/**"

plugins:
  - serverless-python-requirements
custom:
  pythonRequirements:
    zip: true
    slim: true
    dockerizePip: true  # This option must be enabled for including Linux compatible *.so files

And then your app_prod.py can be simple too:

# Unzip the dependencies managed by serverless-python-requirements
try:
    import unzip_requirements  # type:ignore
except ImportError:
    pass

#
# Imports
#

import logging
import os
from slack_bolt import App, BoltContext
import openai
from slack_sdk.web import WebClient
from slack_sdk.http_retry.builtin_handlers import RateLimitErrorRetryHandler

from app import register_listeners
from slack_bolt.adapter.aws_lambda import SlackRequestHandler

SlackRequestHandler.clear_all_log_handlers()
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.WARN)

client = WebClient(token=os.environ["SLACK_BOT_TOKEN"])
client.retry_handlers.append(RateLimitErrorRetryHandler(max_retry_count=2))


def handler(event, context_):
    app = App(
        process_before_response=True,
        client=client,
    )
    register_listeners(app)

    @app.middleware
    def set_openai_api_key(context: BoltContext, next_):
        context["OPENAI_API_KEY"] = os.environ["OPENAI_API_KEY"]
        next_()

    slack_handler = SlackRequestHandler(app=app)
    return slack_handler.handle(event, context_)

Lastly, the commands for deployment remain the same.

# Install serverless framework and its required plugin
npm install -g serverless
serverless plugin install -n serverless-python-requirements

# Deploy the app with above env variables
serverless deploy

I hope this helps!

If you have follow-up questions on AWS and/or serverless framework in general, please ask those questions in AWS/serverless communities instead. Since this is my side project, I am not able to secure enough time to support you on hands-on instructions. It'd be appreciated if you could understand this 👋

Many thanks @seratch 🙏