Skip to content
bitoviPublic
forked from mmcdole/heyemoji

About

a slack recognition bot

Resources

Stars

0 stars

Watchers

0 watching

Forks

Β 
Β 

Latest commit

Β 

History

156 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

heyemoji πŸ† πŸ‘ ⭐

Go Report Card Doc License

The heyemoji bot (Slack-facing name: HeyBitovi) is a self-hosted slack reward system that allows team members to recognize eachother for anything awesome they may have done. This is accomplished with the /heybitovi give slash command, naming a @username along with a pre-configured reward emoji and an optional reason for what they did. The emoji points bestowed to users can be tracked via leaderboards.

Table of Contents

Basic Usage

Give a single user emoji points

/heybitovi give @michael.bolton :star: Great job filling out those TPS reports

Give multiple users emoji points

/heybitovi give @michael.bolton @samir :star: Thanks for coming in this weekend

Give multiple emojis to a user

/heybitovi give @petergibbons :star: :trophy: :clap: :clap: Found my red stapler!

give can be run from any channel, private channel, or a DM with the bot - it doesn't matter where you type it. The public recognition message always posts to one fixed announcement channel (HEY_ANNOUNCE_CHANNEL_ID), and a separate copy also posts in the channel you ran it from (skipped for DMs, and when you ran it in the announcement channel itself). You also always get a DM confirming the points were recorded. In the announcement channel, multiple gives to the same person on the same day thread onto that person's first announcement of the day rather than posting separately; the source-channel copy is always a plain top-level message. Posting into a public channel the bot hasn't joined needs the chat:write.public scope; for a private channel, /invite the bot first.

Bot Commands

Name Description
/heybitovi give @user :emoji: [reason] give someone recognition, with an optional reason
/heybitovi leaderboard <day|week|month|quarter|year|all> see the top point earners for a period
/heybitovi points see how many emoji points you have left to give
/heybitovi help get help with how to send recognition emoji

Setup

heyemoji talks to Slack over Socket Mode, so it needs a Bot User OAuth Token (xoxb-...) and an app-level token (xapp-...) β€” no public URL or Request URL is required to run it locally.

1. Create the Slack app

The fastest way is from a manifest, which sets up the bot user, slash command, scopes, and Socket Mode all at once.

  1. Go to api.slack.com/apps and click Create New App > From an app manifest.

  2. Pick the workspace you want to test in (use a personal/sandbox workspace or a dedicated test workspace if you don't want this showing up for everyone yet).

  3. Choose YAML, paste the manifest below (rename name / display_name if you're creating more than one test app), and click Next > Create.

    display_information:
      name: HeyBitovi
      description: Give teammates recognition with emoji points
      background_color: "#4A154B"
    features:
      app_home:
        home_tab_enabled: false
        messages_tab_enabled: true
        messages_tab_read_only_enabled: false
      bot_user:
        display_name: HeyBitovi
        always_online: true
      slash_commands:
        - command: /heybitovi
          description: Give recognition, check the leaderboard, and more
          usage_hint: "give @user :emoji: [reason] | leaderboard <day|week|month|quarter|year|all> | points | help"
          should_escape: false
    oauth_config:
      scopes:
        bot:
          - chat:write
          - chat:write.public
          - commands
          - users:read
    settings:
      org_deploy_enabled: false
      socket_mode_enabled: true
      token_rotation_enabled: false

    Don't want to use a manifest? Click through it manually instead: Slash Commands > create /heybitovi (leave Request URL blank β€” Socket Mode delivers it); OAuth & Permissions > Scopes > add the chat:write, chat:write.public, commands, and users:read Bot Token Scopes; Socket Mode > toggle it on; App Home > Show Tabs > enable Messages Tab and check "Allow users to send Slash commands and messages from the messages tab" (without this, DMing the bot shows "Sending messages to this app has been turned off" and you can't type anything into the DM, slash commands included).

    Renaming an app you already created? Basic Information > Display Information > update App Name; App Home > Your App's Presence in Slack > update the bot's Display Name; Slash Commands > edit the existing command's Command field from /heyemoji to /heybitovi (Slack lets you rename a command in place, no need to delete and recreate it).

2. Generate your tokens

  1. App-level token (for HEY_SLACK_APP_TOKEN): Basic Information > App-Level Tokens > Generate Token and Scopes. Give it any name, add the connections:write scope, click Generate, and copy the xapp-... token.
  2. Bot token (for HEY_SLACK_BOT_TOKEN): OAuth & Permissions > Install to Workspace (or Install App, if this is a reinstall) > Allow. Copy the Bot User OAuth Token (xoxb-...) from the top of that page.

3. Configure and run

  1. Create a .env file in the heyemoji root folder:
    HEY_SLACK_BOT_TOKEN=xoxb-...
    HEY_SLACK_APP_TOKEN=xapp-...
    DATABASE_URL=postgres://<user>:<password>@postgres:5432/heyemoji?sslmode=disable
    
    (user/password are heyemoji/heyemoji, matching the Postgres service already defined in docker-compose.yaml β€” no separate setup needed. DATABASE_URL is the one setting without a HEY_ prefix: in production it's injected by the platform's Postgres dependency under this exact, fixed name.)
  2. Run docker-compose up --build. The app will run its Postgres migrations on startup and connect to Slack over Socket Mode.
  3. In Slack, invite the bot to a channel you want to test in: /invite @HeyBitovi.
  4. Try it out: /heybitovi help, then /heybitovi give @someone :star: nice work, then /heybitovi leaderboard.

Each teammate testing separately should create their own app this way (or share one app's tokens) β€” a Slack app, its slash command, and its tokens are scoped to whichever workspace you installed it into in step 1.

Web UI Setup

A small read-only web UI (leaderboard + recognition feed) is served from the same container as the bot, at whatever port HEY_HTTP_PORT is set to (default 8080). It's gated by OIDC sign-in against the Bitovi Platform Keycloak (not Slack), which brokers Google and only lets bitovi.com accounts through. The web server simply doesn't start until all four of OIDC_ISSUER_URL, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, and HEY_SESSION_SECRET are set (you'll see web UI disabled: ... in the logs until then) β€” the Slack bot itself works fine either way.

In production you don't set the OIDC_* variables yourself: the sso dependency in deploy/values.yaml has the platform create the Keycloak client heyemoji-sso (redirect URI {HEY_BASE_URL}/auth/callback) and inject all three. Note they have no HEY_ prefix, like DATABASE_URL, because the platform sets those names.

For local testing without a Keycloak client, set HEY_WEB_AUTH_DISABLED=true β€” this starts the web UI with no sign-in required, reachable by anyone who can reach the port. It logs a loud warning on startup so it can't accidentally stay on unnoticed. Never use this for anything other than local testing.

Running the real sign-in locally

You need a Keycloak client whose redirect URIs include http://localhost:8080/auth/callback (ask the platform operator; a staging overlay can add one with extraRedirectUris). Then add to your .env:

OIDC_ISSUER_URL=https://keycloak.bitovi-tools.com/realms/bitovi
OIDC_CLIENT_ID=...
OIDC_CLIENT_SECRET=...
HEY_SESSION_SECRET=some-long-random-string

HEY_SESSION_SECRET just needs to be a long random string (e.g. openssl rand -hex 32) β€” it signs the login session cookie.

Restart (docker-compose up --build), then visit http://localhost:8080 β€” it redirects to Keycloak, then Google, and lands on the leaderboard once you're signed in.

Configuration

ENV Var Default Required Note
HEY_BOT_NAME HeyBitovi No The display name of the bot (currently unused by the app itself; the name shown in Slack is whatever you set on the Slack app)
DATABASE_URL Yes Postgres connection string. No HEY_ prefix β€” in production this is injected by the platform's Postgres dependency under this exact, fixed name.
HEY_SLACK_BOT_TOKEN Yes The Bot User OAuth Token for the Slack API
HEY_SLACK_APP_TOKEN Yes The app-level token used for Socket Mode
HEY_SLACK_EMOJI star:1 No Comma delimited set of emoji "name:value" pairs
HEY_SLACK_DAILY_CAP 5 No The max number of emoji points that can be given out in a day
HEY_ANNOUNCE_CHANNEL_ID No Slack channel ID (e.g. C0123456789, not a channel name) every /heybitovi give announcement posts to and threads under, regardless of which channel or DM the command was run from (a separate copy also posts in the source channel). The bot must be a member of it. If unset, gives are still recorded but no public announcement is posted - the giver still gets a DM confirmation.
HEY_MAX_LEADER_ENTRIES 10 No Max number of entries contained in the leaderboards
HEY_TEST_MODE false No When true, disables the daily give cap entirely (everyone has unlimited points). Every place that would normally show the cap as a number instead says "unlimited (test mode)". Not for production use.
HEY_HTTP_PORT 8080 No Port the web UI listens on
HEY_BASE_URL http://localhost:8080 No Public URL the app is reachable at; used to build the sign-in redirect URI ({HEY_BASE_URL}/auth/callback)
HEY_SESSION_SECRET Only for web UI Random string used to sign the web UI's login session cookie
OIDC_ISSUER_URL Only for web UI Keycloak realm URL, e.g. https://keycloak.bitovi-tools.com/realms/bitovi. Platform-injected in production.
OIDC_CLIENT_ID Only for web UI Keycloak client ID. Platform-injected in production.
OIDC_CLIENT_SECRET Only for web UI Keycloak client secret. Platform-injected in production.
HEY_WEB_AUTH_DISABLED false No When true, the web UI starts with no sign-in required at all. For local testing only - never for anything reachable by anyone but you.

Specifying Custom Reward Emoji

The HEY_SLACK_EMOJI setting lets you specify multiple different reward emoji as well as different point values for each. So, if you wanted the following emoji and reward values:

Emoji Value
⭐ 1
πŸ‘ 2
πŸ† 3

You would specify the HEY_SLACK_EMOJI as: star:1,clap:2,trophy:3

Deploy

heyemoji runs on Bitovi's internal Kubernetes platform (GitOps via Argo CD). The whole app is described by deploy/values.yaml β€” workload, its Postgres dependency, and its domain (heybitovi.bitovi-tools.com). Secrets (Slack tokens, session secret) live in the bitovi-platform/heyemoji-secrets 1Password item, synced in via External Secrets Operator; see the comments at the top of deploy/values.yaml for the exact field labels it expects.

Pushing a vX.Y.Z tag runs .github/workflows/deploy.yml: tests, then builds and pushes the image, then writes the new tag back into deploy/values.yaml, which Argo CD picks up and rolls out. Every pull request against main runs .github/workflows/test.yml.

Moving the web UI to Keycloak (one-time rollout)

The web UI used to sign in with Google directly; it now signs in through the platform Keycloak (the sso dependency in deploy/values.yaml). Because deploy/values.yaml goes live as soon as it merges to main, but the image only changes when a v* tag is pushed, roll it out in this order:

  1. Merge the Keycloak PR. Argo CD applies the new deploy/values.yaml. The still-running v0.3.5 image keeps signing in with Google (its HEY_GOOGLE_* fields are still in 1Password), and HEY_GOOGLE_ALLOWED_DOMAIN is still set, so it stays restricted to bitovi.com. Check that the platform created the client and its Secret:
    kubectl get oidcclient heyemoji-sso -n heyemoji      # READY True
    kubectl get secret heyemoji-sso-oidc -n heyemoji
    
  2. Tag a release (the next vX.Y.Z after v0.3.5). The deploy workflow builds the image and writes the tag back into deploy/values.yaml, and Argo CD rolls it out. Then:
    • Visit https://heybitovi.bitovi-tools.com. It should redirect to keycloak.bitovi-tools.com, then to Google, and land on the leaderboard.
    • The pod log shows no web UI disabled line.
    • If the pod sits in CreateContainerConfigError, the heyemoji-sso-oidc Secret doesn't exist yet. Check the OIDCClient from step 1.
  3. Clean up once sign-in works:
    • Remove HEY_GOOGLE_ALLOWED_DOMAIN (and its comment) from deploy/values.yaml. The Keycloak build doesn't read it.
    • Delete the HEY_GOOGLE_CLIENT_ID and HEY_GOOGLE_CLIENT_SECRET fields from the bitovi-platform/heyemoji-secrets 1Password item.
    • Delete the old Google OAuth client (redirect URI .../auth/google/callback) in the Google Cloud console.

Rollback: until step 3, set image.tag in deploy/values.yaml back to v0.3.5 and merge that. The old image signs in with Google again, because its credentials and HEY_GOOGLE_ALLOWED_DOMAIN are still in place. The leftover OIDC_* env and sso client do nothing to it. After step 3, rolling back also means restoring the Google client and those fields.

About

a slack recognition bot

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages