/pickem-slackbot

Slackbot with per channel state of picked and excluded users

Primary LanguageTypeScript

pickem-slackbot

slackbot that will pick people at random from a channel, weighting folks that haven't been picked recently. It also supports exclusion.

This implementation stores the state in in S3.

It uses the serverless framework for easy development and deployment.

Development

docker-compose build
docker-compose run --rm --entrypoint yarn sls install

Running tests

docker-compose run --rm --entrypoint yarn sls test

Running server for local development

You will need to set the SLACK_SIGNING_SECRET, SLACK_API_TOKEN, and STATE_URL environment variables.

The first two come from your slack configuration. The latter is a URL where the JSON for the channel state is stored. See more in Configuration

docker-compose up

Configuration

Slack

  1. In "OAuth & Permissions", under Scopes, this bot will need
    1. channel:read
    2. chat:write
    3. chat:write.public
    4. commands
  2. In Slash Commands, create a new command called /pickem. The Request URL is the URL printed by serverless after deployment to AWS. The Short Description can be Pickem Bot or whatever you want. The Usage Hint might be help.
  3. Set escaped usernames and channels
  4. Under "Basic Information", get the "Signing Secret" and save it for later use as SLACK_SIGNING_SECRET.
  5. Under "Install App", get the "Bot User OAuth Access Token" and save it for later use as SLACK_API_TOKEN.

Settings

The state configuration is a URL that points to a location in s3 (e.g. s3://bucket/key).

The Signing Secret is under ther Basic Information section of your slackbot as Signing Secret.

The Api Token is under they Install App as Bot User OAuth Access Token.

Local Development

Start docker compose

docker-compose -f docker-compose.yml run --rm --service-ports sls bash

Set up your environment variables

export SLACK_API_TOKEN=abcxyz
export SLACK_SIGNING_SECRET=123pdq

Start the server with hot reloading

./node_modules/.bin/ts-node-dev \
  ./node_modules/.bin/sls offline --host 0.0.0.0 --printOutput

Start ngrok.

Configure the Request Url in slack to be the URL from ngrok with /slack. e.g. https://something.ngrok.io/slack

Deploying

In development, the configuration is taken from environment variables. When deploying to AWS, they are fetched from AWS Parameter store.

While serverless can manage more than the lambdas and API Gateway, we have decided not to use it that way

That means you'll need to manage the S3 bucket and AWS lambda role somewhere else.

Do something like:

aws ssm put-parameter --type SecureString \
    --name /app/pickembot/dev/slack-api-token \
    --value 'THE-REAL-TOKEN'

aws ssm put-parameter --type SecureString \
    --name /app/pickembot/dev/slack-signing-secret \
    --value 'THE-REAL-SECRET'

aws ssm put-parameter --type SecureString \
    --name /app/pickembot/dev/state-url \
    --value s3://SOME-REAL-BUCKET/state.json

aws ssm put-parameter --type String \
    --name /app/pickembot/dev/slackbot-lambda-role \
    --value arn:aws:iam:SOME:REAL_ARN:HERE

Create a docker-compose.override.yml with your AWS credentials. Something like:

version: '3'
services:
  sls:
    environment:
      - AWS_ACCESS_KEY_ID
      - AWS_SECRET_ACCESS_KEY

Or

version: '3'
services:
  sls:
    environment:
      - AWS_PROFILE
    volumes:
      - "~/.aws:/root/.aws"

Then do

docker-compose run --rm sls npx sls deploy