Triggering a Lambda function from Slack

Introduction

There are times when automated processes need to be triggered by a person. As an example, you may have an automated process for publishing code to a test or QA server. Then, after a person has sanity checked it, you want to trigger the deploy to production.

One convenient way to do this is from Slack. In Slack, you can configure a Slash Command to post to a URL. This URL can be an AWS API Gateway that triggers an AWS Lambda function.

For a discussion of setting up a Lambda function like this, please see the article Python Lambda functions and API Gateway.

Slack's Slash Commands

Slack has a number of ways to plug into other technologies. The Slash Command allows you to configure a custom Slack command, in the format:

/my-command argument1 argument2 ...

When this command is submitted, the text of your command, along with all of its arguments, will be posted to a URL that you specify when you create the command. This URL will be the API Gateway URL that is generated when you create the gateway. This text will then be passed on to a Lambda function that can then process it in any way you wish. A number of other Slack specific paramters will also be posted along with your text.

Create and Configure the Slash Command

To begin, log into Slack in your browser and navigate to <yourgroup>.slack.com/apps/manage/custom-integrations. Click on the Slash Commands link and then click the green Add Configuration button on the left side.

In the input field, specify the command you want to define, like:

/deploy

then click on the green Add Slash Command Integration button. This will take you to where you can configure your Slack Lambda integration. In the Integration Settings section, specify the URL that was created for your API Gateway, make a note of the command's Token, and configure the rest of it the way you would like to.

The Lambda Function

Configuring the Lambda Function

As mentioned in the previous the article, the last main section of the serverless.yml file is the functions section. This section defines the name of the function, the python function that is called, any environment variables, and the events that trigger the Lambda function.

For our Slash Command, we need to define a function named deploy, triggered by an API Gateway, with an environment variable SLACK_TOKEN defined:

functions:
    deploy:
        handler: handler.deploy
        environment:
            SLACK_TOKEN: gIkuvaNzQIHg97ATvDxqgjtO
        events:
            - http:
                path: deploy
                method: post

For security purposes, you can avoid saving credentials in your code by using local environment variables. For example, you could replace the environment subsection with:

        environment:
            SLACK_TOKEN: ${env:SLACK_TOKEN}

This would look for a local environment variable defined as SLACK_TOKEN.

Writing the Lambda Function

Now that our Lambda function has been configured, we are ready to write the code to handle the incoming Slash Command. We've defined the handler to be handler.deploy which translates to the deploy function within the handler.py file.

We start with the following:

import urlparse

def deploy(event, context):
    data = event['body']
    args = dict(urlparse.parse_qsl(data))
    token = args.get('token', "")
    text = args.get('text', "")

The function deploy will be called when the Lambda function is triggered, and the parameters event and context will be passed in. You can retrieve the data that Slack posted from the event parameter:

    data = event['body']

This can then be broken down into the individual posted parameters with:

    args = dict(urlparse.parse_qsl(data))

Slack posts a number of parameters with a Slash Command:

token=gIkuvaNzQIHg97ATvDxqgjtO
team_id=T0001
team_domain=example
channel_id=C2147483705
channel_name=test
user_id=U2147483697
user_name=Steve
command=/weather
text=94070
response_url=https://hooks.slack.com/commands/1234/5678

At a minimum, you would use the token parameter to verify that the post came from your Slash Command. Once verified, you would act on the content of the text command. If appropriate, you might use Python's argparse module to parse the command.

You should post a response to the user - as discussed in the previous article. This response must be within 3 seconds. If it takes any longer, you can post a response to the response_url that Slack posted along with your other data.

Deploying the Lambda function and API Gateway

Once you've finished updating the Lambda function code, deploy it:

serverless deploy

It will return the URL of the API Gateway that it created or updated. This is the URL to which the Slash Command is configured to post.

Comments