Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion examples/aws_lambda/.env.oauth_sample
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ export SLACK_CLIENT_SECRET=
export SLACK_SCOPES=app_mentions:read,channels:history,im:history,chat:write
export SLACK_INSTALLATION_S3_BUCKET_NAME=
export SLACK_STATE_S3_BUCKET_NAME=
export SLACK_LAMBDA_PATH=/default/bolt_py_function
105 changes: 103 additions & 2 deletions examples/aws_lambda/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
# Lazy Lambda Listener Example Bolt App
# AWS Lambda Bolt Python Examples

This directory contains two example apps. Both respond to the Slash Command
`/hello-bolt-python-lambda` and both respond to app at-mentions.

The "Lazy Lambda Listener" example is the simpler application and it leverages
AWS Lambda and AWS API Gateway to execute the Bolt app logic in Lambda and
expose the application HTTP routes to the internet via API Gateway. The "OAuth
Lambda Listener" example additionally includes OAuth flow handling routes and uses
AWS S3 to store workspace installation credentials and OAuth flow state
variables, enabling your app to be installed by anyone.

Instructions on how to set up and deploy each example are provided below.

## Lazy Lambda Listener Example Bolt App

1. You need an AWS account and your AWS credentials set up on your machine.
2. Make sure you have an AWS IAM Role defined with the needed permissions for
Expand Down Expand Up @@ -30,7 +44,7 @@
Started Guide](https://slack.dev/bolt-python/tutorial/getting-started).
6. Let's deploy the Lambda! Run `./deploy_lazy.sh`. By default it deploys to the
us-east-1 region in AWS - you can change this at the top of `lazy_aws_lambda_config.yaml` if you wish.
7. Load up AWS Lambda inside the AWS Console - make sure you are in the correct
7. Load up AWS Lambda inside the AWS Console - make sure you are in the correct
region that you deployed your app to. You should see a `bolt_py_function`
Lambda there.
8. While your Lambda exists, it is not accessible to the internet, so Slack
Expand Down Expand Up @@ -68,3 +82,90 @@
- From this same Monitor tab, you can also click "View Logs in CloudWatch" to
see the execution logs for your Lambda. This can be helpful to see what
errors are being raised.

## OAuth Lambda Listener Example Bolt App

1. You need an AWS account and your AWS credentials set up on your machine.
2. Make sure you have an AWS IAM Role defined with the needed permissions for
your Lambda function powering your Slack app:
- Head to the AWS IAM section of AWS Console
- Click Roles from the menu
- Click the Create Role button
- Under "Select type of trusted entity", choose "AWS service"
- Under "Choose a use case", select "Common use cases: Lambda"
- Click "Next: Permissions"
- Under "Attach permission policies", enter "lambda" in the Filter input
- Check the "AWSLambdaBasicExecutionRole" and "AWSLambdaExecute" policies
- Under "Attach permission policies", enter "s3" in the Filter input
- Check the "AWSS3FullAccess" policy
- Click "Next: tags"
- Click "Next: review"
- Enter `bolt_python_s3_storage` as the Role name. You can change this
if you want, but then make sure to update the role name in
`aws_lambda_oauth_config.yaml`
- Optionally enter a description for the role, such as "Bolt Python with S3
access role"
3. Ensure you have created an app on api.slack.com/apps as per the [Getting
Started Guide](https://slack.dev/bolt-python/tutorial/getting-started).
You do not need to ensure you have installed it to a workspace, as the OAuth
flow will provide your app the ability to be installed by anyone.
4. You will need to create two S3 buckets: one to store installation credentials
(when a new Slack workspace installs your app) and one to store state
variables during the OAuth flow. You will need the names of these buckets in
the next step.
5. You need many environment variables exported! Specifically the following from
api.slack.com/apps:
- `SLACK_SIGNING_SECRET`: Signing Secret from Basic Information page
- `SLACK_CLIENT_ID`: Client ID from Basic Information page
- `SLACK_CLIENT_SECRET`: Client Secret from Basic Information page
- `SLACK_SCOPES="app_mentions:read,chat:write"`: Which scopes this application
needs
- `SLACK_INSTALLATION_S3_BUCKET_NAME`: The name of one of the S3 buckets you
created
- `SLACK_STATE_S3_BUCKET_NAME`: The name of the other S3 bucket you created
6. Let's deploy the Lambda! Run `./deploy_oauth.sh`. By default it deploys to the
us-east-1 region in AWS - you can change this at the top of `aws_lambda_oauth_config.yaml` if you wish.
7. Load up AWS Lambda inside the AWS Console - make sure you are in the correct
region that you deployed your app to. You should see a `bolt_py_oauth_function`
Lambda there.
8. While your Lambda exists, it is not accessible to the internet, so Slack
cannot send events happening in your Slack workspace to your Lambda. Let's
fix that by adding an AWS API Gateway in front of your Lambda so that your
Lambda can accept HTTP requests:
- Click on your `bolt_py_oauth_function` Lambda
- In the Function Overview, on the left side, click "+ Add Trigger"
- Select API Gateway from the trigger list
- Make sure "Create an API" is selected in the dropdown, and choose "HTTP API"
as the API Type
- Under Security, select "Open"
- Click "Add"
9. Congrats! Your Slack app is now accessible to the public. On the left side of
your `bolt_py_oauth_function` Function Overview you should see a purple API Gateway
icon. Click it.
10. Click Details to expand the details section.
11. Copy the API Endpoint - this is the URL your Lambda function is accessible
at publicly.
12. We will now inform Slack that this example app can accept Slash Commands.
- Back on api.slack.com/apps, select your app and choose Slash Commands from the left menu.
- Click Create New Command
- By default, the `aws_lambda_oauth.py` function has logic for a
`/hello-bolt-python-lambda` command. Enter `/hello-bolt-python-lambda` as
the Command.
- Under Request URL, paste in the previously-copied API Endpoint from API
Gateway.
- Click Save
13. We also need to register the API Endpoint as the OAuth redirect URL:
- Load up the "OAuth & Permissions" page on api.slack.com/apps
- Scroll down to Redirect URLs
- Copy the API endpoint in - but remove the path portion. The Redirect URL
needs to only _partially_ match where we will send users.
14. You can now install the app to any workspace!
15. Test it out! Once installed to a Slack workspace, try typing
`/hello-bolt-python-lambda hello`.
16. If you have issues, here are some debugging options:
- Check the Monitor tab under your Lambda. Did the Lambda get invoked? Did it
respond with an error? Investigate the graphs to see how your Lambda is
behaving.
- From this same Monitor tab, you can also click "View Logs in CloudWatch" to
see the execution logs for your Lambda. This can be helpful to see what
errors are being raised.
2 changes: 0 additions & 2 deletions examples/aws_lambda/aws_lambda.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import logging
import sys

sys.path.insert(1, "vendor")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like this works. AWS Chalice seems to include vendor/ automatically but AWS Lambda not so much. I can't find more information on this, but I do remember before this did work! But, it has been probably 2 years or so since I've used Python in Lambda, so perhaps that behaviour has changed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch 👍

from slack_bolt import App
from slack_bolt.adapter.aws_lambda import SlackRequestHandler

Expand Down
3 changes: 0 additions & 3 deletions examples/aws_lambda/aws_lambda_oauth.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import logging
import sys

sys.path.insert(1, "vendor")

from slack_bolt import App
from slack_bolt.adapter.aws_lambda import SlackRequestHandler
Expand Down
5 changes: 2 additions & 3 deletions examples/aws_lambda/aws_lambda_oauth_config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
region: us-east-1

function_name: bolt_py_function
function_name: bolt_py_oauth_function
handler: aws_lambda_oauth.handler
description: My first lambda function
runtime: python3.8
Expand Down Expand Up @@ -31,7 +31,6 @@ environment_variables:
SLACK_SCOPES: ${SLACK_SCOPES}
SLACK_INSTALLATION_S3_BUCKET_NAME: ${SLACK_INSTALLATION_S3_BUCKET_NAME}
SLACK_STATE_S3_BUCKET_NAME: ${SLACK_STATE_S3_BUCKET_NAME}
SLACK_LAMBDA_PATH: ${SLACK_LAMBDA_PATH}


# If `tags` is uncommented then tags will be set at creation or update
Expand All @@ -43,4 +42,4 @@ environment_variables:

# Build options
build:
source_directories: vendor # a comma delimited list of directories in your project root that contains source to package.
source_directories: slack_bolt # a comma delimited list of directories in your project root that contains source to package.
4 changes: 2 additions & 2 deletions examples/aws_lambda/deploy_oauth.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
rm -rf vendor && mkdir -p vendor/slack_bolt && cp -pr ../../slack_bolt/* vendor/slack_bolt/
rm -rf slack_bolt && mkdir slack_bolt && cp -pr ../../slack_bolt/* slack_bolt/
pip install python-lambda -U
lambda deploy \
--config-file aws_lambda_oauth_config.yaml \
--requirements requirements_oauth.txt
--requirements requirements_oauth.txt