Skip to content

Antolius/serious-callers-only

Repository files navigation

Serious callers only

A declarative framework for building Slack bots.

Table of contents

Introduction

Animaton showcasing abstract conversation tree, Serious Callers Only script for it and an actual Slack conversation.

Slack provides a powerful API for building integrations and bots. However, a lot of interactions include writing callback code. In case of multiple chained interactions it can be difficult to track state of the conversation between individual callbacks. Serious callers only (Callers for short) aims to help with this.

The Callers framework draws inspiration from declarative UI frameworks such as Rect and Flutter. It provides you with two distinct components:

  • A DSL for writing your bot's logic.
  • A runtime that will run your DSL scripts against Slack API.

Technologies

Callers framework itself is developed in Kotlin. It leverages Kotlin's type-safe builders features to define it's DSL. Further more it uses Kotlin's scripting support to offer a coding environment in IntelliJ IDEA. Lastly, the runtime component is wrapped in a Spring Boot application, packaged as a Docker image. This enables you to easily write your scripts with IDE support and ship them in a pre-built runtime environment, ready for deployment.

Install

For now, you'll need to locally build the framework in order to try it out.

Prerequisites

You will need locally installed Java in order to either build the framework or write call scripts. Framework itself compiles to Java version 1.8 (in order for the IntelliJ support to work). I suggest using Open JDK for your development needs.

Additionally, if you are interested in packaging your scripts as a Docker image you'll also need to install Docker.

Build

Open a terminal inside the project root directory and run:

./gradlew clean build publish docker

This will:

  1. Build the project by pulling its dependencies, compiling the code and running tests.
  2. Publish the DSL library as a maven package in your local repository (usually found under ~/.m2 directory).
  3. Build a docker image for the Spring boot app that's wrapping the framework runtime.

Produced artifacts:

  • Maven package for the DSL: hr.from.josipantolis.seriouscallersonly:api:0.1.0-SNAPSHOT
  • Docker image for runtime: hr.from.josipantolis/serious-callers-only:latest

Usage

Scripting

You can write your Serious callers only scripts in 2 ways:

  1. Using a provided DSL library to declaratively define bot behaviour.
  2. Using exposed underlying classes to imperatively build the bot.

Declarative approach

Example of DSL using script:

this register botJoinedChannelReplier { (channel, _) ->
    replyPublicly {
        +section("Hello there!".txt)
        +context {
            +"Posted in ${channel.mention}".md
            +"Channel id: `${channel.id}`".md
        }
    }
}

This will make the bot post Hello there! in every channel it joins.

For more examples take a look at:

Imperative approach

The same Hello there! script from the previous section can be written programmatically as:

register(EventReplier.BotJoinedChannelReplier { (channel, _) ->
    Reply.Message(
        blocks = listOf(
            Block.Section(
                text = Element.Text.Plain("Hello there!")
            ),
            Block.Context(
                elements = listOf(
                    Element.Text.Markdown("Posted in ${channel.mention}"),
                    Element.Text.Markdown("Channel id: `${channel.id}")
                )
            )
        )
    )
})

Both scripts will result in the same bot behavior.

For more examples of imperative style take a look at:

Running

When it comes to packaging and running your call scripts you again have 2 options:

  1. You can write only the bot scripts and run them using the provided Serious Callers Only docker image.
  2. Or you can use the runtime library and incorporate it in your own Kotlin or Java app.

The provided example project in this repository showcases the first approach. That one is generally quicker to implement, and it allows you to focus on defining your bot's behavior. If you pick this approach you'll need to:

When you run the Serious Callers Only docker image it will expose 2 sets of endpoints:

  • http://localhost:3000/slack/events which can be used as a webhook for Slack events.
  • http://loalhost:3001/actuator which runs Spring Actuator endpoints that you can use to monitor the state of your app. In addition to standard actuator stuff the Callers app adds 2 extra endpoints:
    • /actuator/bot will list all features of currently running bot
    • /actuator/conversations will list all currently ongoing conversations that your bot is engaged in

The second approach is implemented in the app module of this project. That is the Spring Boot app that is packages into the Serious Callers Only docker image. You can take the same approach if you already have or anticipate needing a full-blown app around your scripts. In this case you may not need to write the call scripts in their own files. All you need is to:

When starting your bot locally you'll still need a public URL endpoint that will be accessible to Slack servers. For this you can use ngrok. It's a tool for exposing your local server on a temporary domain on the public internet. It will also provide an HTTPS endpoint, which is required by Slack.

Slack config

No matter how you choose to implement or run your Callers powered bot, you'll need to configure it on Slack itself. The framework currently doesn't support installation to multiple workspaces, so auth is based on bot token.

To configure your bot:

  1. Visit Slack App configuration page.
  2. Create a new app (or pick one that already exists)
  3. Go to Basic Information (in the left menu) > Add features and functionality. Copy the Signing Secret from this page and:
    1. Enable Interactive Components by providing it with your apps public URL. If you are running the Serious Callers Only docker image and exposing it via ngrok your URL will be: https://[some-hash].ngrok.io/slack/events.
    2. Define Slash Commands in case your bot exposes them. Your URL will be the same as in the previous step.
    3. Enable Event Subscriptions and subscribe to following bot events:
      • member_joined_channel
      • message.channels
      • message.groups
      • message.im
      • message.mpim
    4. Enable Permissions. Copy the Bot User OAuth Access Token from this page and add following Bot Token Scopes:
      • channels:history
      • channels:join
      • channels:read
      • channels:write
      • chat:write
      • commands
      • groups:history
      • groups:read
      • im:history
      • mpim:history

After this your Slack config should be filled, and you should have Signing Secret and Bot User OAuth Access Token. You'll need to provide those values to the framework runtime. If you're running the docker image just set them as environment variables.

Project status

The Serious Callers Only is in early development phase. It's operational, but not yet production worthy. At this stage my goals are to:

  1. [] Validate the idea by building some larger projects with the framework.
  2. [] Add plugins to call scripts that will enable easy integration with stuff like Git repos, CI pipelines, Task trackers, Wikis, etc.
  3. [] Add support for Slack Modals and Home tab.

Despite the early stages of the project, it does adhere to semantic versioning. Currently, project is in per-release phase (with versions in 0.y.z range), so you can expect some breaking changes to the API.

Authors

  • Josip Antoliš - Initial development - Antolius

License

Distributed under the MIT License. See LICENSE.txt for more information.

Acknowledgements

None of this would be possible without wonderful folks over at Slack, and particularly the slack-java-sdk.

Almost as crucial are the devs from JetBrains with their various Kotlin language features and scripting support on IntelliJ IDEA side.

Lastly, I've learned a great deal from Rodrigo Oliveira's Implementing the Gradle Kotlin DSL Kotlinconf 2019 talk.

About

A declarative framework for building Slack bots.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages