Deploying a Kotlin app to Heroku (a Slack bot)

This is the minimum needed to create and deploy an app that replies to Slack commands.

Luís Soares
CodeX
3 min readMay 19, 2022

--

Photo by Brett Jordan on Unsplash

📝 You might want to learn How to deploy a Kotlin app to Railway as well.

1. Init project

  1. Create a new Kotlin project.
  2. If you haven’t yet made git init, you should do it now. Heroku needs Git so that you can easily push to deploy to Heroku.
  3. Make sure you have a .gitignore file at the root with:

2. Heroku app

We need to create a Heroku app which will serve our Kotlin app created before. This was based on the official Heroku docs.

  1. Install the Heroku CLI. This allows a quick way to interact with Heroku— using the terminal.
  2. Create a Heroku app by running:
    heroku apps:create HEROKU_APP_NAME
    HEROKU_APP_NAME needs to be unique. This will bind the current Git repository to the Heroku app. You can confirm that the app exists on Heroku Dashboard. You can check that Git is set up by running git remote -v in the terminal.
  3. On the Kotlin app’s root folder, create a file named Procfile with the following content:
    web: java -jar build/libs/PROJ_ID-1.0-SNAPSHOT-all.jar
    (to get PROJ_ID, check settings.gradle.kts).
    This represents the command that Heroku runs to launch the web app.
  4. Heroku requires a stage target. At the bottom of build.gradle.kts, add:
task("stage") {
dependsOn("shadowJar")
}

3. Slack Bolt app

  1. Add the following dependencies to build.gradle.kts:
dependencies {
implementation("org.slf4j:slf4j-simple:1.+")
implementation("com.slack.api:bolt:1.+")
implementation("com.slack.api:bolt-servlet:1.+")
implementation("com.slack.api:bolt-jetty:1.+")
}

2. Add Gradle Shadow build.gradle.kts (this will enable the creation of a single fat jar that can be run later in Heroku):

plugins {
id("com.github.johnrengelman.shadow") version "7.+"
application
}
// at the bottom:
application {
mainClass.set("SlackMainKt")
}

📝 You may need to click the buttons to refresh Gradle, in the top-right corner of the file at the IDE.

3. At src/main/kotlin/SlackMain.kt, put:

fun main() {
val app = App()
app.command("/hello") { _, _ ->
Response.ok("world")
}
SlackAppServer(app, getenv("PORT")?.toInt() ?: 8080)
.start()
}

📝 PORT is an environment variable provided by Heroku. It represents the port that Heroku exposes. Therefore, we need to serve our app at that port.

4. Commit all the local Git changes.

5. Run git push heroku to deploy the app into Heroku (in fact, the first push needs another command, but the message will tell which).

4. Slack app configuration

Based on the official docs: Building an app with Bolt for Java and Getting Started with Bolt.

  1. Go to Slack Apps ▶ click “Create New App”.
  2. Pick “From scratch” ▶ click “Next” ▶ name the app ▶ assign it to a workspace.
  3. On the left-side menu, go to “OAuth & Permissions” ▶ scroll to “Scopes” ▶ add chat:write.
  4. In the menu, click “Slash Commands” ▶ “Create New Command”.
  5. Fill in the details with:
    Command: hello
    Request URL: BASE_APP_URL/slack/events
    To get BASE_APP_URL, run heroku apps:info in the terminal (it’s the Web URL).
    Short Description: hello world
    Save the changes.
  6. We need to copy the Slack environment variables from Slack UI to Heroku. To do it: go to “Basic Information” ▶ “App Credentials” ▶ “Signing Secret” ▶ click “Show” ▶ copy it. Go to Heroku Dashboard ▶ pick the created app ▶ “Settings” ▶ “Reveal Config Vars” ▶ add a new one named SLACK_SIGNING_SECRET with the value copied from before.
  7. Going back to the Slack UI ▶ go to “OAuth & Permissions” ▶ click the button “Install to Workspace” ▶ copy the value at “Bot User OAuth Token”. Go back to Heroku ▶ create another env var named SLACK_BOT_TOKEN ▶ paste the copied value.
  8. Time to test the app! Go to Slack itself ▶ type /hello at any channel ▶ press Enter; you should get world as reply.

📝 If there are issues, you can invoke heroku logs --tail in the terminal.

--

--

Luís Soares
CodeX

I write about automated testing, Lean, TDD, CI/CD, trunk-based dev., user-centric dev, domain-centric arch, ...