An easy way to start a fight is to ask a bunch of developers which team communication platform is best. People can spend a large chunk of their time using it so the stakes can be quite high. Using one platform over another can be the difference between no change in workflow -v- a steep learning curve and having to set up applications on multiple devices just to communicate with one particular team.
Slack isn’t perfect but it’s been around for quite a while and their free plan is a popular option for teams on a budget of zero. One of the benefits of using slack over another platform is their API and relative ease at which you can integrate custom bots and apps.
For this demo, we’re going to create a slack app that will respond to slash commands to get the price of Bitcoin in various fiat currencies. For the tl;dr version and if you just want the code, it’s available on a github repo here: https://github.com/seanmacentee/Sample-AWS-Slack-App
You may need to read on however to understand how it all fits together, in particular what roles / permissions your slack app needs and also how to get it playing nicely with API Gateway.
When we type the slash command “/bitcoin_price USD” we want our app to respond to the sender privately (in whatever channel they submitted the message in). However we also want to include interactive buttons so that the user will have the option of making that message public or deleting it. Finally, we’ll add a button which links to Bitcoin on coinmarketcap. Here’s one I made earlier:
1. Create your app on slack
This is the easy bit where you fill in some fields and click buttons:
Go to: https://api.slack.com/apps and create a new app, give it a name and assign it to your chosen workspace.
That’s it on slack, for now. We’ll be changing settings and coming back to it later.
2. Create your app locally
Open your terminal window / command prompt and navigate to whatever folder you want this project to sit in and initialise it. You can do that using this code:
mkdir btcslackapp cd btcslackapp npm init
Follow the prompts and this will set up a basic package.json file within a new folder called ‘btcslackapp’. Next, install the axios library which will help us later when fetching and sending data. You don’t *have* to use axios of course, but I still find it makes life a little easier than using fetch alone.
npm install axios
You now need to create an index.js file. This is where the magic happens and where we start writing code that does something.
You’ll find the index.js file on the github repo I set up here: https://github.com/seanmacentee/Sample-AWS-Slack-App
In summary it checks to see if we’re authorized and if we are it processes our slack command, downloads currency prices from an endpoint and if the currency we enter matches one of the currencies listed at the endpoint, it will return the relevant price.
3. Set up an AWS lambda function
Lambda functions enable us to carry out server side tasks triggered by certain events. We basically rent server side processing power for the time it takes to carry out the task. For a small app like this, typically the free tier will have more than enough resources included. Cost should be zero unless you have a super active community or a rogue bit of code that’s unintentionally running your function constantly.
Create a blank function from scratch, give it a name and ‘create function’.
Once your function is created, you’ll need to create two environment variables. ACCESS_TOKEN and VERIFICATION_TOKEN. These can be called anything, they’re just what I’ve used in my code on github and by using environment variables it means I don’t need to hard code tokens in to code which keeps things cleaner and safer.
The ACCESS_TOKEN value is your OAuth Access Token in your Slack app. You’ll find this under the ‘OAuth & Permissions’ menu on your slack app.
VERIFICATION_TOKEN value is found in your slack app under the ‘Basic Information’ menu and App Credentials subsection.
After adding those tokens to your lambda function, you’ll now want to add a ‘trigger’ which makes the function run. In our case it’s a slack command which hits an endpoint (AWS API Gateway) which we’ll create next.
4. Set up an API Gateway
Once your lambda function is created, add a trigger by selecting “API Gateway”.
Create a new API, set the Security set to ‘Open’, give it a name (in additional settings) and save. Once saved, go to your AWS management console and select or search for ‘API Gateway’ from the services menu. You should find your newly created API gateway. Select it and you should see a submenu (as in screenshot below). Navigate to the ‘Stages’ and from here you’re looking for an Invoke URL. This is the url that upon receiving a POST request, will trigger your Lambda function. Copy this URL as you’ll need it in the next step.
5. Configure Slack app settings
Turn interactive components on and make sure you set your ‘request url’ to match that of your AWS Gateway invoke url (which you copied from the last step). This is the glue that connects your Slack app to your Lambda function.
OAuth & permissions
One of the many gotchas when creating slack apps is the whole permission / scopes area. Not having a correct permission can make troubleshooting difficult so in general I prefer to assign a bunch of admin permissions, get the app working and then start removing permissions until the app stops working. Needless to say, this is *not* a good idea if you’re working on some super important ‘production’ workspace of course which is why I also use some test workspaces and users to experiment with.
For this app, we need to enable the following permissions:
- slash commands
We then need to actually add a slash command and a description so that users know how to interact with our app. In this case our slash command is “bitcoin_price”.
And lastly we need to install the app to our Slack workspace. You may have been asked to do this earlier as Slack tends to ask you to install or reinstall any time permissions get changed.
And that’s it. You’ve just created a serverless, interactive slack app that will (hopefully) respond to your slash command and fetch the price of Bitcoin in a currency of your choice.
You can of course easily adapt this to fetch data from any API, you’re only limited by your imagination…