Slack command with API Gateway and AWS Lambda

Stop Sprint 99, and the winner is...

At work we operate the Agile methodology and work in two week sprints. At the end of each sprint we hold the retrospective, something that was introduced a few sprints back was to vote for the past sprints MVP (Most Valuable Player), or as I like to say; Most Valuable Programmer. At the end of the sprint the team leads ask’s for everyone to send their votes for MVP, and for a couple of days up to the sprint this is asked over and over, and also asked during the retro. So I made an assumption, of why people might not be voting.

People are not voting due to in not being anonymous

With this in mind, and having wanted to make a bot for Slack I thought it could not be too hard to create a slack command that users could use to cast their vote for MVP.

For it to be simple and not get too complicated the minimum requirements I set myself were:

  1. People votes by using a slack command and the users name eg: /mvp @matthewroach
  2. You can not vote for yourself
  3. You can only vote once
  4. Voting is per sprint, need a way to start and stop voting
  5. Only one active vote topic at a time
  6. Upon stopping the vote the bot would send an in channel message saying who the winner was

Maybe not a small list to accomplish. Over the course of a weekend I created a slack command that did all the above.

One requirement that Slack enforce for integrations is that they must be using https. With this is mind and not wanting to set up SSL and host things myself for something that’s likely to used very infrequent. I decided to use AWS services to handle this, most notable API Gateway and Lambda, for storing the data I went with MongoDB using mLab, mainly because I am familiar with Mongo. mLab offer a free 500mb sandbox database that would be ideal for this.

Slack slash commands

Slash commands are commands that allow users to interact with a third party service. The part of the / (slash) is the command name, then any text after the command is used by the service to do what it needs to do. A slash command can use either a GET or POST request. I decided to use the POST verb to pass along the data from the command.

Slash commands can either post back to use anonymously, or send back the result to the channel it was triggered in. By default it’s anonymous. The other options that you have like better formatting of messages, attachments you can see at their documentation.

AWS API Gateway

API Gateway act’s as a “front door” for applications to access data, business logic or functionality from your back-end services.

API gateway is not limited to the AWS infrastructure, for the slack command I hooked up a POST interface to a lambda function.

Once you deploy your API to an environment, Amazon allows you to deploy your API to multiple stages so you can have a test, staging and production set up. With each stage you get a different URL you can use to call your endpoints with.

The UI for setting up API’s via the AWS console is not the greatest and takes quite a few clicks to go through the different steps. Also, when you hook up an API to a lambda function you need to create a body mapping template that will take the incoming requests and convert to a format you wish to consume in your lambda function. In this case I added a mapping for the content type: application/x-www-form-urlencoded that look like this:

## convert HTTP POST data to JSON for insertion directly into a Lambda function
 
## first we we set up our variable that holds the tokenised key value pairs
#set($httpPost = $input.path('$').split("&"))
 
## next we set up our loop inside the output structure
{
#foreach( $kvPair in $httpPost )
 ## now we tokenise each key value pair using "="
 #set($kvTokenised = $kvPair.split("="))
 ## finally we output the JSON for this pair and add a "," if this isn't the last pair
 "$kvTokenised[0]" : "$kvTokenised[1]"#if( $foreach.hasNext ),#end
#end
}

Hopefully the comments in the code make it easy for you to understand what’s happening. Basically we are converting the form body slack pass us into a JSON object of key value pairs.

AWS Lambda

Is a serverless compute service that runs your code in response to events and automatically manages the underlying compute resources for you.

Lambda is where all the magic happens. I wrote some simple nodejs code that handles the different inputs from the slash command, does it’s logic, reads/stores data to MongoDB and then responds with a result for the user issuing the slack command.

I have pushed the code to a repository on my GitHub account if you wish to take a look at the node code.

As I mentioned earlier, I converted the incoming data from slack into a JSON object that is available to my node code under the event object. With this JSON object now available to me within my function I am able to look at the keys I need and do the required actions. The main thing we are after is the text key from the object this holds the text after the /mvp part of the slash command. I use this key to work out what action I should be taking from the caller.

There are only three commands available from to the user using /mvp; that is start, stop and voting. Voting is working about by looking for an @ as the first character of the text. If I don’t match either of these three, I tell the user you can not perform that action.

Some of the other keys I am using for the function is the team_domain, this is used to determine the mongoDB collection I need to look into. This keeps other teams data away for each other, and avoid having huge one huge collection of data. I also use the user_id to track if the user has voted already. The command does not track who voted for who, it will also not let you vote more than once, and you can only vote if we find an active mvp vote, which also means it’s only possible to have one mvp vote at a time.

I added some sample JSON files that I was using for testing the code locally. I used lambda-local to test my function locally, which makes for a much better experience than having to deal with the AWS interface all the time for writing code and testing.

Without going into great depths of lambda, you have up to three function arguments available to you within your main function, event, context, and callback. Data comes in on the event, context contains information about the lambda function that is executing and the callback is used to return information to the caller. The callback is an optional argument. You can read more about this in the lambda documentation.

Screenshots of working /mvp

Starting/ Opening the voting for a given item, I called this vote Sprint 99

Start Voting

Casting your vote for the MVP

/mvp @docbrown

Vote has been cast

Thank you, your vote has been cast

Stopping/ Closing the voting for Sprint 99 and seeing who was the MVP!

Stop Sprint 99, and the winner is...

Better.fyi

Two months I’ve been using Better.fyi for iOS and it’s been a better two months with it. Just noticed they even have an extension for Safari on the Mac which I use as my browser for general browsing.

I recommend you install them both if you are running iOS or Mac, not just for less ads on sites, but also for a safer online experience. All round it’s better!

Coffee shop working this morning

Photo taken at: Starbucks Dumfries

A gentle stroll along the river with Alice

Photo taken at: River Nith Dumfries

Left-Handers Rule

Lunch time view

Choosy

Choosy Browser PickerBeing someone who uses different web browsers for different purposes. I primarily use Chrome and Chrome Canary for developing in, Safari for personal browsing and Opera for random other things. Having to set a default browser is a hard choice because I don’t always want links to open in the default browser. Take for example I want to open a link from the Twitter App, I would like this to be opened in Safari, but if someone messages me on Slack with a URL for a test server or production server issue I will want to open that in one of the Chrome browsers I have open for that environment. The same applies for emails, especially ones that come from ticket systems or source control emails, again I want these to open in the browser I am using for those sites.

Having recently moved back to Mac full time I was confident there would be an App or some solution to fill my needs, and one quick search found Choosy, a preference pane application for the Mac that does exactly want I want and more. After 24 hours of use I am sold, and purchased it.

A great feature of Choosy is you can set up rules so you don’t have to choose the browser you wish for link. You can do it based on URL, or the Application the link is coming from. I have a rule for any links from the Twitter App to open in Safari for example.

One Small Step Can Change Your Life: The Kaizen Way

one-small-step-can-change-your-life

How many times have you set yourself new year resolutions and never completed them? Ever wanted to make big changes in your life and never quite managed to make them?

Kaizen is a Japenese philosophy of continuous improvement. Rather than aiming high and failing it’s about taking small steps regularly that build up to the big goal.

kaizen asks us to be patient. It asks us to have faith that with small steps, we can better overcome the mind’s initial resistance to change

Part of the process is training your brain to accept the changes you are planning, and by doing small steps it allows for your brain to adjust to the changes, rather than it being highly resistant.

Never force the process of kaizen; it works only if you let change happen in a comfortable and easy manner.

Kaizen is not just for personal change, it can be applied to anything. This book gives examples that cover business and personal. Giving real life examples and stories and how kaizen has improved people’s lives and help businesses. If it’s something as simple as reading more, spending more time with your family or increasing sales. Applying kaizen thinking and methodologies to these goals can give you a better success rate of improvement

If you ever feel yourself dreading the activity or making excuses for not performing it, it’s time to cut back on the size of the step

One Small Step Can Change Your Life: The Kaizen Way on Amazon.co.uk

Four Thousand Days

four-thousand-days

I came across this book via Twitter, and actually picked it up on a special promo some time last year. I finally got around to reading it on my trip to USA last month.

It’s a very easy read and keeps you very interested and wanting to keep on read to find out what happened next. Duane got tied up in something bad to help pays some bills and then turned his life around from entering prison to selling his on-line business and becoming a very wealthy man, all within 4000 days. Prison is an interesting subject, and a majority of the book focuses on Duane’s time behind bars. Later on in the books he talks about running a business and going through the process of selling his business. If you are interested in the “start-up” culture and knowing more of what’s involved and goes on in big companies buying the small fish this book gives you a great insight to this including lots of details of the steps and money involved.

Rather than giving away too many details of the book, I recommend you pick the book up and give it a read.

Four Thousand Days: My Journey From Prison To Business Success on Amazon.co.uk