If you’re integrating your Amazon Lex chatbots with Slack, chances are you’ll come across Block Kit. Block Kit is a UI framework for Slack apps. Like response cards, Block Kit can help simplify interactions with your users. It offers flexibility to format your bot messages with blocks, buttons, check boxes, date pickers, time pickers, select menus, and more.
Amazon Lex provides channel integration with messaging platforms such as Slack, Facebook, and Twilio. For instructions on integrating with Slack, see Integrating an Amazon Lex Bot with Slack. You can also update the interactivity and shortcuts feature with the request URL that Amazon Lex generated. If you want to use Block Kit and other Slack native components, you need a custom endpoint for the request URL.
This post describes a solution architecture with a custom endpoint and shows how to use Block Kit with your Amazon Lex bot. It also provides an AWS Serverless Application Model (AWS SAM) template implementing the architecture.
In the proposed architecture, we use Amazon API Gateway for the custom endpoint and an AWS Lambda function to process the events. We also introduce an Amazon Simple Queue Service (Amazon SQS) queue to invoke the Lambda function asynchronously. The rest of the architecture includes an Amazon Lex bot and another Lambda function used for initialization, validation, and fulfillment. We use Python for the provided code examples.
Use Slack Block Kit with an Amazon Lex bot to post messages
Each time you want to display a message with blocks, the following steps are required:
Build the block. Block Kit Builder helps you visually format your messages.
Check whether the request originated from Slack before you post the block. This allows you to deploy your bots on multiple platforms without major changes.
Use the chat_postMessage operation from the Slack WebClient to post them in Slack. You can use the following operation to post both text and blocks to Slack:
To illustrate those steps with the OrderFlowers bot, we show you how to use a date picker from Block Kit to re-prompt users for the pick-up date.
First, you build the block in the format Slack expects:
Then, you modify the validation code hook as follows. This checks if the request originated from Slack using the channel-type request attribute.
If the violated slot is PickupDate, you post the block you defined earlier to Slack. Then, you ask Amazon Lex to elicit the slot with the returned validation message:
You can use this approach to complement messages that you had configured at build time with Block Kit.
Now that you know how to use blocks to post your bot messages, let’s go over how you handle users’ interactions with the blocks.
When a user interacts with an action block element, the following steps take place:
Slack sends an HTTP request to API Gateway.
API Gateway forwards the request to Amazon SQS.
Amazon SQS receives the transformed request as a message, and invokes the Lambda function that processes the request.
Let’s take a closer look at what happens at each step.
Slack sends an HTTP request to API Gateway
When a user chooses an action block element, Slack sends an HTTP post with the event details to the endpoint configured as request URL. The endpoint should reply to Slack with an HTTP 2xx response within 3 seconds. If not, Slack resends the same event. We decouple the ingestion and processing of events by using an Amazon SQS queue between API Gateway and the processing Lambda function. The queue allows you to reply to events with HTTP 200, queue them, and asynchronously process them. This prevents unnecessary retry events from flooding the custom endpoint.
API Gateway forwards the request to Amazon SQS
When API Gateway receives an event from Slack, it uses an integration request-mapping template to transform the request to the format Amazon SQS is expecting. Then it forwards the request to Amazon SQS.
Amazon SQS receives and processes the transformed request
When Amazon SQS receives the message, it initiates the process Lambda function and returns the 200 HTTP response to API Gateway that, in turn, returns the HTTP response to Slack.
The Lambda function completes the following steps:
Verify that the received request is from Slack.
Forward the text value associated to the event to Amazon Lex.
Post the Amazon Lex response to Slack.
In this section, we discuss each step in more detail.
Verify that the received request is from Slack
Use the signature module from slack_sdk to verify the requests. You can save and retrieve your signing secret from AWS Secrets Manager. For Slack’s recommendation on request verification, see Verifying requests from Slack.
Forward the text value associated to the event to Amazon Lex
If the request is from Slack, the Lambda function extracts the text value associated with the action type. Then it forwards the user input to Amazon Lex. See the following code:
We use the Amazon Lex client post_text operation to forward the text to Amazon Lex. You can also store and retrieve the bot’s name, bot’s alias, and the channel ID from Secrets Manager. See the following code:
Post the Amazon Lex response to Slack
Finally, we post the message from Amazon Lex to Slack:
From the user’s perspectives, the experience is the following:
The bot re-prompts the user for the pick-up date with a date picker.
The user selects a date.
The bot prompts the user for the pick-up time.
The messages that use Block Kit are seamlessly integrated to the original conversation flow with the Amazon Lex bot.
In this part of the post, we walk through the deployment and configuration of the components you need to use Block Kit. We go over the following steps:
Launch the prerequisite resources.
Update the Slack request URL with the deployed API Gateway endpoint.
Gather information for Secrets Manager.
Populate the secret value.
Update the Lambda function for Amazon Lex fulfillment initialization and validation.
Update the listener Lambda function.
Test the integration.
For this walkthrough, you need the following:
An AWS account.
An Amazon Lex bot integrated with Slack. For instructions to create an Amazon Lex bot if you don’t have one, or to integrate your existing bot, see Integrating an Amazon Lex Bot with Slack.
Install the AWS SAM CLI.
Install Python 3.
Install Docker community edition.
Integrate Amazon Lex and Slack with a custom request URL
To create the resources, complete the following steps:
Clone the repository https://github.com/aws-samples/amazon-lex-slack-block-kit:
Build the application and run the guided deploy command:
These steps deploy an AWS CloudFormation stack that launches the following resources:
An API Gateway endpoint integrated with an SQS queue
A Lambda function to listen to requests from Slack
A Lambda function for Amazon Lex fulfillment, initialization, and validation hooks
AWS Identity and Access Management (IAM) roles associated to the API and the Lambda functions
A Lambda layer with slack_sdk, urllib3, and common operations used by the two Lambda functions
A secret in Secrets Manager with the secret keys our code uses
Update the Slack request URL
To update the Slack request URL, complete the following steps:
On the AWS CloudFormation console, navigate to the stack Outputs tab and copy the ListenSlackApi endpoint URL.
Sign in to the Slack API console.
Choose the app you integrated with Amazon Lex.
Update the Interactivity & Shortcuts feature by replacing the value for Request URL with the ListenSlackApi endpoint URL.
Choose Save Changes.
Gather information for Secrets Manager
To gather information for Secrets Manager, complete the following steps:
On the Slack API console, under Settings, choose Basic Information.
Note down the value for Signing Secret.
Under Features, choose OAuth & Permissions.
Note down the value for Bot User OAuth Token.
On the Amazon Lex console, note the following:
Your bot’s name
Your bot’s alias
The last part of the two callback URLs that Amazon Lex generated when you created your Slack channel (for example, https://channels.lex.us-east-1.amazonaws.com/slack/webhook/value-to-record).
Populate the secret value
To populate the secret value, complete the following steps:
On the Secrets Manager console, from the list of secrets, choose SLACK_LEX_BLOCK_KIT.
Choose Retrieve secret value.
Replace the secret values as follows:
SLACK_SIGNING_SECRET – The signing secret from Slack.
SLACK_BOT_TOKEN – The bot user OAuth token from Slack.
BOT_NAME – Your Amazon Lex bot’s name.
BOT_ALIAS – Your Amazon Lex bot’s alias name.
LEX_SLACK_CHANNEL_ID – The value you recorded from the callback URLs.
Update the Lambda fulfillment function and Lambda initialization and validation for your Amazon Lex bot
If you’re using the OrderFlowers bot, follow the instructions in Step 4: Add the Lambda Function as Code Hook (Console) to add the Lambda function amazon-lex-slack-block-kit-OrderFlowerFunction as code hooks for fulfillment, initialization, and validation.
If you’re not using the OrderFlowers bot, use the Lambda layer slack-lex-block that the stack created if your runtime is Python version 3.6 and later. The layer includes an operation postInSlack to post your blocks:
You can use Slack Block Kit Builder to build your blocks.
Update the listener Lambda function
If you’re using the OrderFlowers bot, move to the next step to test the integration.
Test the integration
To test the integration, complete the following steps:
Go back to the Slack team where you installed your application.
In the navigation pane, in the Direct Messages section, choose your bot.
If you don’t see your bot, choose the plus icon (+) next to Direct Messages to search for it.
Engage in a conversation with your Slack application.
In this post, we showed how to use Block Kit to format Amazon Lex messages within Slack. We provided code examples to post blocks to Slack, listen to events from users’ interactions with the blocks’ elements, and process those events. We also walked you through deploying and configuring the necessary components to use Block Kit. Try the code examples and adapt them for your use case as you see fit.
About the Author
Anne Martine Augustin is an Application Consultant for AWS Professional Services based in Houston, TX. She is passionate about helping customers architect and build modern applications that accelerate their business outcomes. In her spare time, Martine enjoys spending time with friends and family, listening to audio books, and trying new foods.
Read MoreAWS Machine Learning Blog