Slack Smart Bot: Connecting AWS lambda with Slack Events

New project time. Today i’m our lead developer for our Ansible collection at work, and we do all our support today in Slack. I want to automate some of this support to help resolve issues quickly for users and free up more time for the dev team to develop.

The plan is to make a smart slack bot that will respond to users who need help, ask for the required information. If there is a known fix give the user the information on the fix. If not, let the dev team know if all the information needs to look into the issue.

I plan to do with slack sending event to AWS Lambda, and have a python script respond to it. The app will listen to the chat in the channel and only respond if the user need help.

Setting up Slack

First we’ll create a new slack app https://api.slack.com/apps

OAuth & Permissions

We’ll need to add some scope so that the bot and read and respond to IM and message in a channel

  • Channels:history
  • channels:read
  • chat:write
  • group:history
  • im:history
  • im:read
  • im:write

Setting up Lamdba

In AWS Lambda create a new function.

  • Runtime Python 3.8 — though could be any python version

Api Gateway

Once the function is created, you’ll want to click on + Add trigger
Here you want to select Api Gateway

  • APi = Create an APi
  • API type = http API
  • Security = open

Once this is created, the API Gateway will create an API-endpoint url, copy this as we will need this for the next steps in Slack

Back to in Slack

Event Subscription

Enable Events, and in the Request URL add your API-endpoint url from AWS

Next in this same window go down to Subscribe to bot events and add

  • Message.channels
  • message.group
  • message.im

For channels, group, and IM the bot is part of the bot will send an event to AWS Api gateway any time a message is sent.

Basic Information

Now in the Basic Information window in the slack app click on install your app. This will install your app in your workspace

Oauth & Permissions

Copy the Bot user Oauth Token. We will need to add this to the AWS side

Back To AWS

In your lambda function page you want click on Configuration and then Environment Variables. Here you want to add a new environment variable called BOT_TOKEN and the value should be your bot token

Testing if it works

First make sure the bot is added to the channel in slack for this to work).
if you type help in as a message in the channel, the bot will respond with “help is on the way”

import os
from six.moves import urllib
import json


def send_text_response(event, response_text):
    # use postMessage if we want visible for everybody
    # use postEphemeral if we want just the user to see
    SLACK_URL = "https://slack.com/api/chat.postMessage"
    channel_id = event["event"]["channel"]
    user = event["event"]["user"]
    bot_token = os.environ["BOT_TOKEN"]
    data = urllib.parse.urlencode({
        "token": bot_token,
        "channel": channel_id,
        "text": response_text,
        "user": user,
        "link_names": True
    })
    data = data.encode("ascii")
    request = urllib.request.Request(SLACK_URL, data=data, method="POST")
    request.add_header("Content-Type", "application/x-www-form-urlencoded")
    res = urllib.request.urlopen(request).read()
    print('res:', res)


def check_message(text):
    if 'help' in text:
        return 'help is on the way'
    if 'carchi8py' in text:
        return 'carchi8py is my maker'
    return None


def is_bot(event):
    return 'bot_profile' in event['event']


def lambda_handler(event, context):
    event = json.loads(event["body"])
    print('event', event)
    if not is_bot(event):
        message = check_message(event["event"]["text"])
        if message:
            send_text_response(event, message)

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

How this works

The bot we made in Slack will send an event message to Api gateway which will trigger as Lambda function by calling the lambda_handler function. The Event is the json event that slack sent us. So we do a json.loads so we have a dictionary to work with.

First thing we want to do is check if the message was sent by a bot, (if you don’t know this, your bot will respond to it self and create an infinite loop. We only want to respond to humans

Next we pass the text of the message to the check_message, which check to see if a specific word exists, and if so return a specific message to send back to slack

Last we call the send_text_response to Slack. This set up a message so that we can send it back to slack. This uses the BOT_TOKEN we set up as an environment variable

One thought on “Slack Smart Bot: Connecting AWS lambda with Slack Events

Add yours

Leave a comment

Blog at WordPress.com.

Up ↑