How to Create a Slack Bot using AWS Lambda in < 1 Hour

Tomas Pilvelis
Glasswall Engineering
5 min readJan 19, 2020

Learn how to create a Slack Bot with unlimited potential using Slack Events API.

There’s not many resources out there in using AWS Lambda functions in Python so here’s one. Whilst it took me around 2/3 hours, this should sort you out in less than 1 hour!

Prerequisites

  • AWS and Slack Account
  • Slack Workspace

1. Create an App on Slack

Head on down to https://api.slack.com/ and select the “Your Apps” tab on the site.

Once on the page you will see a list of your apps on your workspace. “Create New App

You will be presented with a page to name your bot and assign it to the workspace you want the app to belong to.

Upon a successful creation you will be greeted to the “Basic Information” page of your Slack App.

On the sidebar, under the “Features” heading, select “Bot Users” and complete the fields and “Save Changes

Once this is done lets head to “Event Subscriptions

Click on the On/Off switch to “Enable Events

Put this aside, as for now we are done with setting up our App. Now to get crackin’ with some AWS. Let’s accomplish the “challenge” in order to set up the Endpoint in Step 2.

2. Create AWS Lambda function

Log into your AWS Management Console and head on over to “Lambda” in services.

Create Function” > “Author From Scratch

Ensure you use Python 3.6 for this tutorial as some libraries may not be supported. Do use what you require for your project :). “Create function

3. Attach an API Gateway to the function

Designer” > “+ Add trigger

Ensure the following is entered:

  • API Gateway trigger
  • Security: Open

Click on the newly created API Gateway Trigger and a card below should appear with a link. Copy the link (API Endpoint) and let’s test our lambda function works by clicking the link.

4. Take API endpoint and add to events in slack

The link that we copied, take it back to Event Subscription and insert the link. The Slack API will then test the API Gateway and Lambda function. At the moment it is a failure as all we do is return “Hello from Lambda” so we know it works.

The task now is to return the “challenge” value in our lambda function.

To make our life easy and a small debug tip. Insert this line of code:

import jsondef lambda_handler(event, context):
print(f"Received event:\n{event}\nWith context:\n{context}")
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}

This will allow you to view what is passed into the event in the CloudWatch Logs.

To Complete the “challenge” lets add some code in the Lambda function:

import jsondef lambda_handler(event, context):
print(f"Received event:\n{event}\nWith context:\n{context}")

slack_body = event.get("body")
slack_event = json.loads(slack_body)
challenge_answer = slack_event.get("challenge")

return {
'statusCode': 200,
'body': challenge_answer
}

Save this function. Back to the Slack API page and “Retry”. This should then succeed and become Verified!

Next, on the same page select “Subscribe to bot events” and “Add Bot User Event

Add the “message.im” event. This will allow you to message the bot via a direct message.

Finally, back to “Basic Information” > “Install your app to your workspace” > “Allow

Once that is successful. Restart your slack app and install the app and start messaging and programming your slack bot!

Direct Message your newly created slack bot.

Full Lambda Function Code for a simple response (Warts and all) :P

import os
import urllib
def send_text_response(event, response_text):
print("Messaging Slack...")
SLACK_URL = "https://slack.com/api/chat.postMessage"
channel_id = event.get("event").get("channel")

data = urllib.parse.urlencode(
(
("token", os.environ["BOT_TOKEN"]),
("channel", channel_id),
("text", response_text)
)
)
data = data.encode("ascii")

request = urllib.request.Request(SLACK_URL, data=data, method="POST")
request.add_header( "Content-Type", "application/x-www-form-urlencoded" )

# Fire off the request!
x = urllib.request.urlopen(request).read()
def lambda_handler(event, context):
print(f"Received event:\n{event}\nWith context:\n{context}")

send_text_response(event, "Hello World From Lambda")

return "200 OK"

Here’s one I made earlier

Upon upload of a file to Slack the following will take place:

  1. Get the file from the private_url and authenticates using the BOT_TOKEN.
  2. The file will then be stored to an S3 Bucket.
  3. We would then invoke another lambda function which will run the Glasswall Determine File Type test.
  4. The result is then sent.

There is a bug where Slack will make a request upon a bot’s response.

The way I stop this from happening is by checking the username or user_id of the request. This way it partially stops an infinite amount of requests being made. Instead it passes through 2-3 times.

def check_if_from_bot(event):
message_from = event.get("event").get("username")
if message_from == "gwtf-bot":
return True
if event.get("event").get("subtype") == "bot_message":
return True

Please contact me if you have a solution. :D

My challenge to you…

What can you create with a slack bot?

--

--