[]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.
[]The following diagram illustrates the solution architecture.
[]You can use Block Kit to format messages you configured at build time within the Lambda function associated with an intent. The following example uses blocks to display available flowers to users.
[]Each time you want to display a message with blocks, the following steps are required:
def postInSlack(user_id, message, messageType=’Plaintext’, bot_token=slacksecret[‘SLACK_BOT_TOKEN’]): try: # Call the chat.postMessage method using the WebClient if (messageType == ‘blocks’): result = slackClient.chat_postMessage( channel=user_id, token=bot_token, blocks=message ) else: result = slackClient.chat_postMessage( channel=user_id, token=bot_token, text=message ) except SlackApiError as e: logger.error(f”Error posting message: {e}”) []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.
[]Outside of Slack, the user only receives the validation result message.
[]In Slack, the user receives both the pick-up date block and the validation result 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:
[]The following diagram illustrates the interaction flow.
[]Let’s take a closer look at what happens at each step.
[]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.
[]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.
[]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:
[]In this section, we discuss each step in more detail.
[]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.
[]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:
actions = payload[“actions”] team_id = payload[“team”][“id”] user_id = payload[“user”][“id”] action_type = actions[0][“type”] if action_type == “button”: forwardToLex = actions[0][“value”] elif action_type == ‘datepicker’: forwardToLex = actions[0][‘selected_date’] else: forwardToLex = “None” forward_to_Lex(team_id, user_id, forwardToLex) []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 event received from Slack to Lex and post Lex reply to #Slack def forward_to_Lex(team_id, user_id, forwardToLex): response = lexClient.post_text( botName=slacksecret[‘BOT_NAME’], botAlias=slacksecret[‘BOT_ALIAS’], userId=slacksecret[‘LEX_SLACK_CHANNEL_ID’]+”:”+ team_id+ “:” + user_id, inputText=forwardToLex )
[]Finally, we post the message from Amazon Lex to Slack:
postInSlack(user_id, response[‘message’]) []The following screenshot shows the response on Slack.
[]From the user’s perspectives, the experience is the following:
[]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:
[]For this walkthrough, you need the following:
[]To create the resources, complete the following steps:
git clone https://github.com/aws-samples/amazon-lex-slack-block-kit.git
cd amazon-lex-slack-block-kit sam build sam deploy –guided []
[]These steps deploy an AWS CloudFormation stack that launches the following resources:
[]To update the Slack request URL, complete the following steps:
[]To gather information for Secrets Manager, complete the following steps:
[]To populate the secret value, complete the following steps:
[]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:
helper.postInSlack (channel_id, blocks, ‘blocks’) []You can use Slack Block Kit Builder to build your blocks.
[]If you’re using the OrderFlowers bot, move to the next step to test the integration.
[]If you’re not using the OrderFlowers bot, update the Lambda function starting with amazon-lex-slack-block-kit-ListenFunction to process the actions your blocks used.
[]To test the integration, complete the following steps:
[]If you don’t see your bot, choose the plus icon (+) next to Direct Messages to search for it.
[]Your bot now prompts you with the blocks you configured, as shown in the following example conversation.
[]To avoid incurring future charges, delete the CloudFormation stack via the AWS CloudFormation console or the AWS Command Line Interface (AWS CLI):
aws cloudformation delete-stack –stack-name amazon-lex-slack-block-kit []You also need to delete the Amazon Lex bot resources that you created, the Amazon CloudWatch logs, and the Lambda layer that was created by the stack.
[]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.
[]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.