Skip to content

Krever/scala-slack-bot

Repository files navigation

Scala Slack Bot Example

The goal of this repository is showcase how to build and deploy a simple slack bot in scala. It focuses on composing existing pieces together while exploring deployment options and developer experience that comes with them.

Checkout the article for a proper tutorial.

At the moment this repository supports the following run scenarios

Local Remote
Native Docker
Service Scala.js ❌ Could be added
Scala JVM ✅ on fly.io
Lambda Scala.js ✅ on AWS
Scala JVM

Create Slack App

export WEBHOOK_URL='' # Webhook handler for the slack app
export APP_CONF_TOKEN='' # Can be generated at https://api.slack.com/apps
scripts/create-slack-app.sh

Update the app

Whenever you want to update the webhook URL

export WEBHOOK_URL='' # Webhook handler for the slack app
export APP_CONF_TOKEN='' # Can be generated at https://api.slack.com/apps
scripts/update-slack-app.sh

Run locally

Ngrok

Slack requires https traffic and current server implementation exposes only http endpoint. This means you can't simply expose the port on your router. Instead, you can use ngrok to create a http proxy.

brew install --cask ngrok

ngrok http 9876 

# public url will be shown in the terminal. Alternatively you can get it with
curl -s localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url'

Prerequisites

export SLACK_BOT_TOKEN='' # Can be generated at https://api.slack.com/apps/${APP_ID}/oauth 

As a service

This will expose an http endpoint served by http4s.

JVM

> sbt 
sbt:scala-slack-bot> serviceJVM/reStart
## JVM debugger available on port 5005.

Scala.js

npm install source-map-support

sbt serviceJS/run
## nodejs debugger available on port 9229.

Verify

Both runtimes work the same way and can be called with:

curl localhost:9876/hello

curl -XPOST localhost:9876/lambda -d 'user_id=111' # need proper user id to work correctly

As a lambda

This will start an aws-provided container with lambda runtime

Scala.js

sbt fastOptJS::webpack
./scripts/run-local-lambda-container-js.sh

JVM

sbt lambdaJVM/universal:stage
./scripts/run-local-lambda-container-jvm.sh

Verify

curl -X POST --location "http://localhost:9876/2015-03-31/functions/function/invocations" \
    -d '{
  "body":"user_id=111",
  "isBase64Encoded": false
}'

Run remotely

As a lambda on AWS Lambda

Requires aws account and cli setup

Set up

This will create all necessary object through CloudFormation Stack

scripts/deploy-cf-stack.sh

Scala.js

sbt lambdaJS/universal:packageBin
scripts/update-lambda-js.sh

JVM

sbt lambdaJVM/universal:stage
./scripts/run-local-lambda-container-jvm.sh

Verify

> scripts/get-cf-stack-status.sh
Status:  "CREATE_COMPLETE"
Lambda url:  "my_url"

curl -XPOST my_url -d 'user_id=111'

As a service on fly.io

fly auth login
fly auth docker

sbt serviceJVM/docker:publish

fly deploy -c resources/fly.tom 
fly secrets set -c resources/fly.toml SLACK_BOT_TOKEN=$SLACK_BOT_TOKEN

flyurl=$(fly status -c resources/fly.toml --json | jq -r .Hostname)
curl -XPOST fly_url/lambda -d 'user_id=111'

Alternatives

Localstack

This bot could be deployed to localstack but with significant limitations:

  • AWS::ApiGatewayV2::Api resource is not supported in localstack community edition, so this part would have to be done separately (outside of cloud formation)

Scala native & GraalVM

PRs welcomed!

Acknowledgements

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published