Fun with Slack Commands using Azure API and Function Apps
In this example, I'm using an Azure API app with Easy APIs enabled (formerly mobile services...but better) and the preview version of the Azure Function app.
Let me start by saying that there are many different ways to consume and send Slack webhooks. However, since I've used and written about using azure mobile services in the past to do just that, I figured it was time to update those using the latest Azure services. In this example, I'm using an Azure API app with Easy APIs enabled (formerly mobile services...but better) and the preview version of the Azure Function app. My original intention was to use the Function for both ends, but given its preview nature, I ran into quite a few issues trying to work with Service Bus.
Create a new Slash Command
Under custom integration in your Slack app's directory, you can Create a new Slack Command. You give it a name like
/whatsuponlunch then, you have a shiny new command you can use and pass in a plain text argument. For example,
/whatsuponlunch find me tacos would trigger your hard-working process for finding a taco place within a 4-block radius.
Consume the command payload in your API App
In your Azure API app, create a new 'Easy API' called
lunchcommand and make sure it can accept public POST requests. Once that's done, you'll need to make a few more tweaks to the default Express setup so that the
request.body of that POST request can be properly understood. You need to install a couple of packages and add a few lines to
app.js so that the request.body changes from
undefined to the payload you expect from the command.
Now the Express API is ready to parse out the form urlencoded POST that Slack will send with each command execution. Setting up the Express middleware was new to me, but this exposed configuration is a welcome change from the previous iteration of Node Mobile Services.
This next bit of code processes the payload and sends a message to an Azure Service Bus Queue. After the brokered message is sent, it responds with a message for the user who initiated the request.
Use a Function to process the message and respond to the user
Azure Functions are in preview, meaning new features are coming all the time, and use them at your own risk. I found this out firsthand when testing some of the features myself. I did have some success with creating a new C# function that was triggered to run when a new message was received in a Service Bus queue. So each time the above API generates a new message, this function executes. The Portal wizard is the fastest way to create the function, but you can also do everything through code by following the developer reference documentation (shown below).
Now that the Function and trigger are set up let's get into the function setup. First, you'll need to ensure that your NuGet dependencies are installed and available to the function. You'll need to add a
project.json file in your function subdirectory to accomplish this...it should look very familiar if you played with the new project system shipping with .NET Core. The best way to add that quickly is to fire up Visual Studio Online from the Portal.
You've got your packages installed; now for the code. It starts by parsing the Service Bus message body, then doing some longer running work, and finally sending the results back to slack via the private webhook link from the message.
The user just got a private message in the channel they initiated the command from with all of that helpful information. See, I told you it was fun! All this without a server deployed, a service scaled, or even a desktop code editor opened.