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 | ✅ |
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
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
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'
export SLACK_BOT_TOKEN='' # Can be generated at https://api.slack.com/apps/${APP_ID}/oauth
This will expose an http endpoint served by http4s.
> sbt
sbt:scala-slack-bot> serviceJVM/reStart
## JVM debugger available on port 5005.
npm install source-map-support
sbt serviceJS/run
## nodejs debugger available on port 9229.
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
This will start an aws-provided container with lambda runtime
sbt fastOptJS::webpack
./scripts/run-local-lambda-container-js.sh
sbt lambdaJVM/universal:stage
./scripts/run-local-lambda-container-jvm.sh
curl -X POST --location "http://localhost:9876/2015-03-31/functions/function/invocations" \
-d '{
"body":"user_id=111",
"isBase64Encoded": false
}'
Requires aws account and cli setup
This will create all necessary object through CloudFormation Stack
scripts/deploy-cf-stack.sh
sbt lambdaJS/universal:packageBin
scripts/update-lambda-js.sh
sbt lambdaJVM/universal:stage
./scripts/run-local-lambda-container-jvm.sh
> scripts/get-cf-stack-status.sh
Status: "CREATE_COMPLETE"
Lambda url: "my_url"
curl -XPOST my_url -d 'user_id=111'
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'
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)
PRs welcomed!