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
- GitHub Pull Request Alert on Slack (Magic Night Project - Part 1)
- The AWS CLI installed with a user and valid API key with an authorized user to run the kms command before continuing.
See http://docs.aws.amazon.com/cli/latest/userguide/installing.html for details.
Lambda Function
- 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.
API Gateway
-
Create the API Gateway or use the API Gateway from the part 1.
-
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.
-
Add a new Method > POST.
-
In Integration Request:
- Body Mapping Templates > When there are no templates defined (recommended)
-
Add mapping template > application/x-www-form-urlencoded > Checkmark.
-
Add mapping template > application/json > Checkmark.
-
Add { “body”: $input.json("$") } > Save to both mapping templates.
-
Deploy API.
-
Once the API is created, within Stages from the left side, drill down to the resource and click the method.
-
This will display an “Invoke URL”, copy this URL and we’ll use it in the Slack Slash Command Setup section.
Slack Slash Command Setup
-
From settings choose “Add an app or integration”.
-
In the textbox, type and choose “Slash Commands”
-
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.
- Enter the command that will trigger the API Gateway.
-
You will use the Slack token to create the encryption blob.
KMS Keys
-
Choose the region from the filter that matches the Lambda function previously setup.
-
Create a new key and enter an alias.
-
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.
-
In Define Key Usage Permissions, find the role used in your Lambda function above.
-
Review policy and Finish.
-
Copy the ARN for the Encryption Key account just created.
Add KMS Decrypt Policy to Role
- In IAM, go to Roles, and edit the role created for the Lambda function.
- From Permissions > Inline Policy > Create Role Policy > Custom Policy > Select
- Enter the policy name.
- Download and copy/paste the policy, replacing < your KMS key ARN > with the one copied in the KMS Keys section.
- Validate and Apply Policy
Create the base-64 encoded, encrypted Slack command token
- 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
- Copy the CiphertextBlob in the output from the command line and place into the Lambda function replacing < CIPHERTEXT_BLOB >
GitHub Token
-
Under your profile > Settings > Personal access tokens > Generate new token.
-
Name the token, and choose the repo checkbox. Generate token.
-
Copy the token and paste it into the < GITHUB_TOKEN > in the Lambda function.
Setup your Repo
-
In your repo, create a new file, name the file, add some text, and create a new branch, and propose new file to save.
-
Click the Create a pull request button.
-
If you have your Slack open, you should’ve received a message in the channel.
Testing
-
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.)
-
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.
-
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.
-
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>
-
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.
-
Invalid commands will return with an invalid message.
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
- https://developer.GitHub.com/v3/pulls/#merge-a-pull-request-merge-button
- https://developer.GitHub.com/v3/pulls/#update-a-pull-request
- http://stackoverflow.com/questions/4511598/how-to-make-http-delete-method-using-urllib2
- Lambda > New function using blueprint Slack-echo-command-python
- GitHub Pull Request Event API Information
- Emoji Cheat Sheet