Skip to content

Commit

Permalink
add example how to use AWSLambdaReceiver (slackapi#815)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheManWhoStaresAtCode committed May 28, 2021
1 parent 1ac76f4 commit 89dc28b
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 0 deletions.
9 changes: 9 additions & 0 deletions examples/deploy-aws-lambda-receiver/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# node / npm
node_modules/
package-lock.json

# macOS
.DS_Store

# Serverless
.serverless/
21 changes: 21 additions & 0 deletions examples/deploy-aws-lambda-receiver/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020 Slack Technologies, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
143 changes: 143 additions & 0 deletions examples/deploy-aws-lambda-receiver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Deploying to AWS Lambda ⚡️ Bolt for JavaScript

> Slack app example for using the AWSLambdaReceiver of Bolt for JavaScript
## Overview

This is an example app that updates the [Getting Started ⚡️ Bolt for JavaScript app][bolt-app] to use the AWSLambdaReceiver and be deployed to [AWS Lambda][aws-lambda] using the [Serverless Framework][serverless-framework].
You can learn how to build this example app by following our 📚 [Deploying to AWS Lambda guide][bolt-guide-aws-lambda].

Before you begin, you may want to follow our [Getting Started guide][bolt-guide] to learn how to build your first Slack app using the [Bolt for JavaScript framework][bolt-website].

## Getting started

1. [Set up AWS credentials](#1-set-up-aws-credentials)
1. [Set up local project](#2-set-up-local-project)
1. [Create a Slack app](#3-create-a-slack-app)
1. [Deploy to AWS Lambda](#4-deploy-to-aws-lambda)
1. [Update Slack app settings](#5-update-slack-app-settings)
1. [Test your Slack app](#6-test-your-slack-app)
1. [Develop on local machine](#7-develop-on-local-machine)

## 1. Set up AWS credentials

### Install and configure AWS CLI

Follow Amazon's guides to [install the AWS CLI v2 for macOS, Windows, or Linux][aws-cli-install] and [create a new IAM User][aws-cli-configure-user].

When you have the AWS CLI and user credentials, then configure your local machine with the command:

```zsh
aws configure
```

## 2. Set up local project

You can install the app's local development dependencies with the following command:

```zsh
npm install
```

You may also want to [install ngrok][ngrok-install] to start a local tunnel for local development.

## 3. Create a Slack app

### Create an app on api.slack.com

1. Go to https://api.slack.com/apps
1. Select **Create New App**
* Name your app, _don't worry you can change it later!_
1. Select **OAuth & Permissions**
1. Scroll down to **Bot Token Scopes**
1. Add the following bot scopes:
1. Add the scope `app_mentions:read`
1. Add the scope `channels:history`
1. Add the scope `chat:write`
1. Add the scope `groups:history`
1. Add the scope `im:history`
1. Add the scope `mpim:history`
1. Select **Install App to Workspace** at the top of the page

### Export environment variables

```zsh
export SLACK_SIGNING_SECRET=<your-signing-secret> # Slack app settings > "Basic Information"
export SLACK_BOT_TOKEN=<your-xoxb-bot-token> # Slack app settings > "OAuth & Permissions"
```

## 4. Deploy to AWS Lambda

Run the following the command to deploy to AWS Lambda:

```zsh
npx serverless deploy
# ...
# endpoints:
# POST - https://d5c0t1xad4.execute-api.us-east-1.amazonaws.com/dev/slack/events
```

_Please note the endpoint `https://{your-domain}.amazonaws.com/dev/slack/events` because we'll use it in the next section._

## 5. Update Slack app settings

Now that your Slack app is deployed, you can register your AWS Lambda endpoint with the Slack API:

1. Go to https://api.slack.com/apps
1. Select your app
1. Select **Event Subscriptions**
1. Enable **Events**
1. Set the **Request URL** to `https://{your-domain}.amazonaws.com/dev/slack/events`
1. Scroll down to **Subscribe to Bot Events**
1. Add the following bot events:
- `app_mention`
- `message.channels`
- `message.groups`
- `message.im`
- `message.mpim`
1. Select **Save Changes**

## 6. Test your Slack app

You can test your app by opening a Slack workspace and saying "hello" (lower-case):

> 💬 hello
>
> 🤖 Hey there @Jane!
_Remember, your app must be in the channel or DM where you say hello._

## 7. Develop on local machine

Open a terminal session to listen for incoming requests:

```zsh
npx serverless offline --noPrependStageInUrl
```

Open another terminal session to proxy Slack API requests locally:

```zsh
# -subdomain= is avalable only for paid accounts
ngrok http 3000 -subdomain=my-unique-name
```

Update your [Slack app settings][slack-app-settings] to use your ngrok address:
1. **Interactivity & Shortcuts**
1. Set the **Request URL** to `https://my-unique-name.ngrok.io/slack/events`
1. **Event Subscriptions**
1. Set the **Request URL** to `https://my-unique-name.ngrok.io/slack/events`

Follow the steps to [test your app](#6-test-your-slack-app).

[aws-cli-install]: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html
[aws-cli-configure]: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html
[aws-cli-configure-user]: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-creds
[aws-lambda]: https://aws.amazon.com/lambda/
[bolt-app]: https://github.com/slackapi/bolt-js-getting-started-app
[bolt-guide]: https://slack.dev/bolt-js/tutorial/getting-started
[bolt-guide-aws-lambda]: https://slack.dev/bolt-js/deployments/aws-lambda
[bolt-website]: https://slack.dev/bolt-js/
[ngrok-install]: https://api.slack.com/tutorials/tunneling-with-ngrok
[serverless-framework]: https://serverless.com/
[slack-app-settings]: https://api.slack.com/apps
62 changes: 62 additions & 0 deletions examples/deploy-aws-lambda-receiver/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const { App, AwsLambdaReceiver } = require('@slack/bolt');

// Initialize your custom receiver
const awsLambdaReceiver = new AwsLambdaReceiver({
signingSecret: process.env.SLACK_SIGNING_SECRET,
});

// Initializes your app with your bot token and the AWS Lambda ready receiver
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
receiver: awsLambdaReceiver,
// The `processBeforeResponse` option is required for all FaaS environments.
// It allows Bolt methods (e.g. `app.message`) to handle a Slack request
// before the Bolt framework responds to the request (e.g. `ack()`). This is
// important because FaaS immediately terminate handlers after the response.
processBeforeResponse: true
});

// Listens to incoming messages that contain "hello"
app.message('hello', async ({ message, say }) => {
// say() sends a message to the channel where the event was triggered
await say({
blocks: [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `Hey there <@${message.user}>!`
},
"accessory": {
"type": "button",
"text": {
"type": "plain_text",
"text": "Click Me"
},
"action_id": "button_click"
}
}
],
text: `Hey there <@${message.user}>!`
});
});

// Listens for an action from a button click
app.action('button_click', async ({ body, ack, say }) => {
await say(`<@${body.user.id}> clicked the button`);

// Acknowledge the action after say() to exit the Lambda process
await ack();
});

// Listens to incoming messages that contain "goodbye"
app.message('goodbye', async ({ message, say }) => {
// say() sends a message to the channel where the event was triggered
await say(`See ya later, <@${message.user}> :wave:`);
});

// Handle the Lambda function event
module.exports.handler = async (event, context, callback) => {
const handler = await app.start();
return handler(event, context, callback);
}
18 changes: 18 additions & 0 deletions examples/deploy-aws-lambda-receiver/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "bolt-js-aws-lambda-receiver",
"version": "1.0.0",
"description": "Deploying to AWS Lambda ⚡️ Bolt for JavaScript using the AWSLambdaReceiver",
"main": "app.js",
"scripts": {
"start": "node app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"license": "MIT",
"dependencies": {
"@slack/bolt": "^3.2.0"
},
"devDependencies": {
"serverless": "^2.13.0",
"serverless-offline": "^6.8.0"
}
}
17 changes: 17 additions & 0 deletions examples/deploy-aws-lambda-receiver/serverless.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
service: serverless-lambda-receiver-bolt-js
frameworkVersion: '2'
provider:
name: aws
runtime: nodejs12.x
environment:
SLACK_SIGNING_SECRET: ${env:SLACK_SIGNING_SECRET}
SLACK_BOT_TOKEN: ${env:SLACK_BOT_TOKEN}
functions:
slack:
handler: app.handler
events:
- http:
path: slack/events
method: post
plugins:
- serverless-offline

0 comments on commit 89dc28b

Please sign in to comment.