Description

When a custom Slack command is triggered, the corresponding command will change the state of a GitHub pull request. A magic night project provided by AWS User Group Hosted by MindTouch.

Tools used in this project

  • Slack: smylee.Slack.com
  • GitHub: GitHub.com/smyleeface/shiny-palm-tree
  • Amazon API Gateway, Lambda, IAM > Roles, Encryption Keys
  • AWS CLI

Prerequisites

Lambda Function

  1. Create a new Lambda Function; skip selecting blueprint.
    • Name the function, and choose Python 2.7.
    • Download and copy/paste the code into the textarea.
    • Replace GITHUB_OWNER. You will replace the other two keys, ENCRYPTED_EXPECTED_TOKEN and GITHUB_TOKEN later.
    • Use the Lambda_basic_execution Role, or the Role created in part 1.
    • Leave the rest of the setting default. You can choose your own VPC, but I’m choosing “No VPC” in this configuration.
    • Review and Create. We’re not quite ready to run this yet.

      Lambda Slack to GitHub

API Gateway

  1. Create the API Gateway or use the API Gateway from the part 1.
  2. Add a new resource from the root of the API. Choose Lambda Function > us-west-2 > smylee_github_slack_action, save. After saving, a permissions prompt will popup choose OK.

    API Gateway Slack to GitHub Settings
  3. Add a new Method > POST.

    API Gateway Method POST

  4. In Integration Request:

    • Body Mapping Templates > When there are no templates defined (recommended)
    • Add mapping template > application/x-www-form-urlencoded > Checkmark.

      Mapping Template FORM
    1. Add mapping template > application/json > Checkmark.

      Mapping Template JSON

    2. Add { “body”: $input.json(“$”) } > Save to both mapping templates.

      Generate Template

  5. Deploy API.

    Deploy API

  6. Once the API is created, within Stages from the left side, drill down to the resource and click the method.

    Deploy URL

  7. This will display an “Invoke URL”, copy this URL and we’ll use it in the Slack Slash Command Setup section.

    Invoke URL

Slack Slash Command Setup

  1. From settings choose “Add an app or integration”.

    Add an app or integration

  2. In the textbox, type and choose “Slash Commands”

    Slash Commands

  3. If this is the first slash command created, click on “install”, otherwise “configure”.

    • Enter the command that will trigger the API Gateway.

    • Paste the Invoke URL from the API Gateway into the URL field for the Slack command.
    • Copy the Token.
    • Complete and save the form.

      Create Slash Commands
  4. You will use the Slack token to create the encryption blob.

KMS Keys

  1. Choose the region from the filter that matches the Lambda function previously setup.
  2. Create a new key and enter an alias.

    Create Key Alias

  3. Do not add any users to Define Key Administrative Permissions, unless there is a user that you want to be able to manage this key.

  4. In Define Key Usage Permissions, find the role used in your Lambda function above.

  5. Review policy and Finish.

  6. Copy the ARN for the Encryption Key account just created.

    Key Summary

Add KMS Decrypt Policy to Role

  1. In IAM, go to Roles, and edit the role created for the Lambda function.
  2. From Permissions > Inline Policy > Create Role Policy > Custom Policy > Select
  3. Enter the policy name.
  4. Download and copy/paste the policy, replacing < your KMS key ARN > with the one copied in the KMS Keys section.
  5. Validate and Apply Policy

    Role Policy

Create the base-64 encoded, encrypted Slack command token

  1. In the command line where aws cli is installed, enter:
    aws kms encrypt --key-id alias/< ENCRYPTION KEY ALIAS > --plaintext "< SLACK TOKEN >" --region us-west-2
  2. Copy the CiphertextBlob in the output from the command line and place into the Lambda function replacing < CIPHERTEXT_BLOB >

    CiphertextBlob

GitHub Token

  1. Under your profile > Settings > Personal access tokens > Generate new token.

    Generate new token

  2. Name the token, and choose the repo checkbox. Generate token.

    Configure Token

  3. Copy the token and paste it into the < GITHUB_TOKEN > in the Lambda function.

    GitHub Token

Setup your Repo

  1. In your repo, create a new file, name the file, add some text, and create a new branch, and propose new file to save.

    Create new file in repo

  2. Click the Create a pull request button.

    Create pull request

  3. If you have your Slack open, you should’ve received a message in the channel.

    Recieve Slack Message

Testing

  1. Download sample payload. (Note: This sample data may throw an error as it is a payload from my setup. You may be able to find your payload in CloudWatch.)
  2. Test the Lambda function (see part 1 for how to test). You could try the Slack command first to check CloudWatch to get the real payload for testing.
  3. Test the api function, deploy if any changes were made. (see part 1 for how to test). You could try the Slack command first to check CloudWatch to get the real payload for testing.
  4. Test the Slack command.
    /github close < repo-name > < pull-request number>
    /github open < repo-name > < pull-request number>
    /github merge < repo-name > < pull-request number>

    Command Response

  5. You should receive two messages for each request. One from the return of the function which runs the GitHub command and second one is a message of the pull request status which is triggered from the setup of part 1 of this guide.

  6. Invalid commands will return with an invalid message.

    Invalid Command

AWS Costs for creating this project

  • AWS provides a lot of services for free for the first 12 months of sign up and beyond. More information can be found on AWS pricing pages.
  • Cost should be less than $1 to create this project.
  • Lambda pricing cost - Doesn’t start to charge until you’ve made 1 million requests and gone over 400,000 GB-Seconds (each billed separately.)
  • API Gateway pricing cost - Different for some regions, but all regions are billed per million calls received, plus the cost of data transfer out, in gigabytes. Plus you only pay for what you use.
  • Key Encryption - $1/month for a key and first 20,000 request/month free, and cost per use after.

Footnotes

  • You can skip using encryption key for this exercise by commenting out lines 13-14 & 27-29 in lambda_smylee_slack_github_action.py.

Resources