Tutorial: Build a Serverless API backend for Slack [part 1]
Tags: serverless, tutorial, showdev, java
Published: 2019-09-04 11:32:25

> This article is part of [#ServerlessSeptember](https://dev.to/azure/serverless-september-content-collection-2fhb). You'll find other helpful articles, detailed tutorials, and videos in this all-things-Serverless content collection. New articles are published every day — that's right, every day — from community members and cloud advocates in the month of September.

> Find out more about how Microsoft Azure enables your Serverless functions at https://docs.microsoft.com/azure/azure-functions/.


Webhook backends are a popular use case for Serverless functions. FaaS (Functions-as-a-service) offerings make it relatively easy to provide an HTTP endpoint which hosts the Webhook logic which can be as simple as sending an email to something as entertaining as responding with funny GIFs!

In this tutorial, we will explore **funcy** - a Serverless webhook backend which is a trimmed down version of the awesome [Giphy for Slack](https://get.slack.help/hc/en-us/articles/204714258-Giphy-for-Slack). The (original) Giphy Slack app returns a bunch of GIFs for a search term and the user can pick one of them. **funcy** tweaks it a bit by simply returning a (single) random image for a search keyword using the [Giphy Random API](https://developers.giphy.com/docs/#operation--gifs-random-get).


This blog post provides a step-by-step guide to getting the application deployed to [Azure Functions](https://azure.microsoft.com/en-in/services/functions/?WT.mc_id=servsept_devto-blog-abhishgu) and hooking it up with your Slack workspace. The code is [available on GitHub](https://github.com/abhirockzz/funcy-azure-functions/) for you to grok.


> If you are interested in learning Serverless development with [Azure Functions](https://azure.microsoft.com/en-in/services/functions/?WT.mc_id=servsept_devto-blog-abhishgu), simply [create a free Azure account](https://azure.microsoft.com/en-us/free/?WT.mc_id=servsept_devto-blog-abhishgu) and get started! I would highly recommend checking out the [quickstart guides, tutorials and code samples](https://docs.microsoft.com/en-in/azure/azure-functions/?WT.mc_id=servsept_devto-blog-abhishgu) in the documentation, make use of the [guided learning path](https://docs.microsoft.com/en-in/learn/paths/create-serverless-applications/?WT.mc_id=servsept_devto-blog-abhishgu) in case that's your style or download the [Serverless Computing Cookbook](https://azure.microsoft.com/en-in/resources/azure-serverless-computing-cookbook/?WT.mc_id=servsept_devto-blog-abhishgu).


![](https://thepracticaldev.s3.amazonaws.com/i/pltswm81s6j50dfb2qqk.jpg)

In order to keep this blog concise, the details of the code have been covered in a subsequent post.

{% link https://dev.to/azure/code-walkthrough-for-funcy-a-serverless-slack-app-using-azure-functions-3gmd %}


### Overview

![](https://thepracticaldev.s3.amazonaws.com/i/m0k2emsg9ntyxvrhu4cu.jpg)

`funcy` is built as a Slash Command within Slack. As a user, you can invoke it from your Slack workspace using `/funcy <your search term>`. This, in turn, invokes our webhook deployed to [Azure Functions](https://azure.microsoft.com/en-in/services/functions/?WT.mc_id=servsept_devto-blog-abhishgu) - which is nothing but a bunch of [Java code](https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-java/?WT.mc_id=servsept_devto-blog-abhishgu). It calls the [Giphy Random API](https://developers.giphy.com/docs/#operation--gifs-random-get) and returns the result back to the user.

For example, invoking it from your Slack workspace using `/funcy serverless` will return a random GIF.

![](https://media1.giphy.com/media/MGdfeiKtEiEPS/giphy-downsized.gif)


The upcoming sections will guide you through the following:

- Pre-requisites
- Slack setup and configuration
- Deploying to Azure Functions

### Pre-requisites

Before you proceed, ensure that you have the following ready - it shouldn't take too long


- **Maven** - The [Maven Plugin for Azure Functions](https://docs.microsoft.com/java/api/overview/azure/maven/azure-functions-maven-plugin/readme?view=azure-java-stable&WT.mc_id=servsept_devto-blog-abhishgu) is used to build and deploy your Java function. If you don't have Maven, please install `v 3.0` or above [from here](https://maven.apache.org/).
- **Azure CLI** - [Follow the instructions](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest&WT.mc_id=servsept_devto-blog-abhishgu) to setup and login to the Azure CLI. 
- **Slack Workspace** - [Please create a Slack workspace](https://slack.com/create) if you don't have one.
- **GIPHY API key** - You need to create a GIHPY account (it's free!) and [create an app](https://developers.giphy.com/dashboard/?create=true). Each application you create will have its own API Key.

> Please note down your GIPHY API key as you will be using it later

![](images/giphy-dashboard.jpg)

### Configure Slack

Please note that the instructions in this section have been adapted from the [Slack documentation](https://api.slack.com/slash-commands#creating_commands)

#### Create a Slack App

Sign into your [Slack Workspace](https://slack.com/signin). Start by [creating a new Slack App](https://api.slack.com/apps/new)

![](https://thepracticaldev.s3.amazonaws.com/i/0rjtgorqyqmmwozp5p5b.jpg)

#### Create a Slash Command

Once you're done creating the app, head to your app's settings page, and then click the *Slash Commands* feature in the navigation menu.

![](https://thepracticaldev.s3.amazonaws.com/i/tvpzmlcnjamfbv5mcx5m.jpg)

You'll be presented with a button marked *Create New Command*, and when you click on it, you'll see a screen where you'll be asked to define your new *Slash Command* with the required information.

![](https://thepracticaldev.s3.amazonaws.com/i/hpued2a9qgdvs5rvnc6m.jpg)

Enter the required information. Please note that the **Request URL** field is the one where you will enter the HTTP endpoint of function which will be available after you deploy it. You can use a dummy URL as a placeholder just for the time being  e.g. `https://temporary.com:4242`

![](https://thepracticaldev.s3.amazonaws.com/i/c77tvc0jbihl5xrjsncd.jpg)

Once you're done, hit **Save** to finish.

#### Install the app to your workspace

Once you're done creating the Slash Command, head to your app's settings page, click the *Basic Information* feature in the navigation menu, choose *Install your app to your workspace* and click *Install App to Workspace* - this will install the app to your Slack workspace to test your app and generate the tokens you need to interact with the Slack API.


![](https://thepracticaldev.s3.amazonaws.com/i/jf9nu57x24s4lopbwao9.jpg)


As soon as you finish installing the app, the *App Credentials* will show up on the same page. You need to grab your *Slack Signing Secret* from there

> Make a note of your app Signing Secret as you'll be using it later


![](https://thepracticaldev.s3.amazonaws.com/i/daem7h5ej0lzyo5phcum.jpg)

### Deploy to Azure

Start by cloning the GitHub repository and change into the application directory

        git clone https://github.com/abhirockzz/funcy-azure-functions
        cd funcy-azure-functions

The `pom.xml` file contains the following attributes used by the Azure Functions Maven plugin - application name (`functionAppName`), region (`functionAppRegion`) and resource group (`functionResourceGroup`). It has default values for the above parameters, so you can choose to continue using them if you like.

- `functionAppName` - funcyapp
- `functionAppRegion` - westus
- `functionResourceGroup` - java-functions-group

> Please note that the app name must be **unique** across Azure.

If you wish to wish to change the values, please take a look at this snippet from `pom.xml` which highlights the `<properties>` which need to be updated

        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <azure.functions.maven.plugin.version>1.3.1</azure.functions.maven.plugin.version>
            <azure.functions.java.library.version>1.3.0</azure.functions.java.library.version>
            <functionAppName>YOUR_APP_NAME</functionAppName>
            <functionAppRegion>AZURE_REGION</functionAppRegion>
            <functionResourceGroup>RESOURCE_GROUP_NAME</functionResourceGroup>
            <stagingDirectory>${project.build.directory}/azure-functions/${functionAppName}</stagingDirectory>
        </properties>

> The name of the function is not the same as application name (configured via `pom.xml`) and is specified using the `@FunctionName` annotation in the Java code for the function - in this case, the name is `funcy`.

You can now build the function and deploy it to Azure

    //build
    mvn clean package
    
    //deploy
    mvn azure-functions:deploy

The results from a successful deployment will look something like this

    [INFO] Successfully updated the function app.funcyapp
    [INFO] Trying to deploy the function app...
    [INFO] Trying to deploy artifact to funcyapp...
    [INFO] Successfully deployed the artifact to https://funcyapp.azurewebsites.net
    [INFO] Successfully deployed the function app at https://funcyapp.azurewebsites.net
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS


Use the [Azure CLI](https://docs.microsoft.com/cli/azure/?view=azure-cli-latest&WT.mc_id=servsept_devto-blog-abhishgu) to list your Functions App

    az functionapp list --query "[].{hostName: defaultHostName, state: state}"

You should see a JSON output

    [
        {
            "hostName": "funcyapp.azurewebsites.net",
            "state": "Running"
        }
    ]

> You should be able to see the function (under `Function App` menu) in [Azure Portal](https://portal.azure.com)

Once the deployment is successful, the function should be ready to serve requests and can be accessed over HTTP(s) at the following endpoint - `https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>`

For an application named `funcyapp` with a function called `funcy`, the endpoint would be

    https://funcyapp.azurewebsites.net/api/funcy

You're almost there!

#### Update your Azure Functions app

Now that the Azure Functions app is up and running, you need to update it to seed the `Giphy API Key` and `Slack Signing Secret` as environment variables. 


    az functionapp config appsettings set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --settings "SLACK_SIGNING_SECRET=<SLACK_SIGNING_SECRET>" "GIPHY_API_KEY=<GIPHY_API_KEY>"

e.g.

    az functionapp config appsettings set --name funcyapp --resource-group java-functions-group --settings "SLACK_SIGNING_SECRET=foobarb3062bd293b1a838276cfoobar" "GIPHY_API_KEY=foobarrOqMb5fvJdIuxTCr3WUDfoobar"

> Please refer to the documentation on [How to manage a function app in the Azure portal](https://docs.microsoft.com/en-us/azure/azure-functions/functions-how-to-use-azure-function-app-settings/?WT.mc_id=servsept_devto-blog-abhishgu) for details.

### Update the Slack app

Head to your app's settings page, and then click the *Slash Commands* feature in the navigation menu. Edit the command and replace the value for the *Request URL* field with your function HTTP(s) endpoint

![](https://thepracticaldev.s3.amazonaws.com/i/jczkdyz4sy898ch52n3d.jpg)

### `funcy` time!

From your workspace, invoke the command 

`/funcy <search term>`

Since you can't go wrong with cats, try 

`/funcy cat`

![](https://media.giphy.com/media/13HBDT4QSTpveU/giphy.gif)

Don't worry if you see a `Timeout error` from Slack after the first invocation. This is due to the 'cold start' problem where the function takes a few seconds to bootstrap but [Slack expects a response in 3 seconds](https://api.slack.com/slash-commands#responding_basic_receipt). Just retry (a couple of times) and things should be fine.

> If your application cannot afford the latency due to "idle cold starts", you might want to check out [Azure Functions Premium plan](https://azure.microsoft.com/en-us/blog/announcing-the-azure-functions-premium-plan-for-enterprise-serverless-workloads/?WT.mc_id=servsept_devto-blog-abhishgu) which provides *"pre-warmed instances to run your app with no delay after being idle..."*

### Resources

The below mentioned resources were leveraged specifically for developing the demo app presented in this blog post, so you're likely to find them useful as well!

- [Azure Functions developers guide (general)](https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference/?WT.mc_id=servsept_devto-blog-abhishgu) and the [Azure Functions Java developer guide](https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-java/?WT.mc_id=servsept_devto-blog-abhishgu)
- [Quickstart on how to use Java to create and publish a function to Azure Functions](https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-java-maven/?WT.mc_id=servsept_devto-blog-abhishgu)
- [Maven Plugin for Azure Functions](https://docs.microsoft.com/en-us/java/api/overview/azure/maven/azure-functions-maven-plugin/readme?view=azure-java-stable/?WT.mc_id=servsept_devto-blog-abhishgu)
- [How to code and test Azure Functions locally](https://docs.microsoft.com/en-us/azure/azure-functions/functions-develop-local/?WT.mc_id=servsept_devto-blog-abhishgu)
- [How to manage connections in Azure Functions](https://docs.microsoft.com/en-us/azure/azure-functions/manage-connections/?WT.mc_id=servsept_devto-blog-abhishgu)
- [Maven Plugins for Azure Services on GitHub](https://github.com/microsoft/azure-maven-plugins)

> Don't forget to check out the [second part of this blog post](https://dev.to/azure/code-walkthrough-for-funcy-a-serverless-slack-app-using-azure-functions-3gmd), where I have covered the code in detail

I really hope you enjoyed and learned something from this article! Please like and follow if you did. Happy to get feedback via [@abhi_tweeter](https://twitter.com/abhi_tweeter) or just drop a comment.