Skip to content

accurec/KarrotAwards

Repository files navigation

KarrotAwards

Logo

Table of contents

Overview

At my workplace we use Slack for communication and we used to have different types of Karma bots and apps. However, we eventually got rid of them. Instead of giving karma, we started giving each other different emojis like carrot, beer and potato. One person would keep track of all awards that people got in a Word document. So I decided to create a Slack application specifically for purpose of awarding emojis and keeping track of them. I came up with the name KarrotAwards - a combination of Karma + Carrot 😆 - and this is how this fun application has started! 😆

Functions

The application is a global Slack command that is available to any User in any channel, except threads.

The application has 4 main functions:

  • Help -> this will send private message to the User who called it. The message will explain all available functions and what they do. All User needs to do is to type /karrotawards help.

Help command example

  • Assign award -> This is the main data entry point for the application and, once called, it will generate a new modal window to collect data from the User about whom they are giving the awards to, which awards they are willing to assign, and also a message text. For all 3 fields there is validation. After the User inputs the data and clicks submit button, the application will announce the event in the channel with a randomly selected message from predefined set of funny messages stored in the backend. To invoke the command User needs to type /karrotawards and hit enter. Each award has its own score that will contribute to the total User's score.

Assign award example

  • Leaderboard -> This command allows User to see how many different awards top X Users have and their total score. Once the command is executed the application will generate an HTML table image in the backend and send it back to the channel. The command for this is /karrotawards leaderboard. It has a default top X value, but it is also possible to specify a number that User wants (up to a specific max number). To do that User could do /karrotawards leaderboard 12 for example, which would give top 12 Users as a result.

Leaderboard example

  • Scorecard -> This is a special case for the leaderboard command. To avoid having to always spam leaderboard to the channel, or in case the User didn't have enough points to be included in the leaderboard top X, I've added an ability to view a scorecard for one specific User - which would be sent as a private message.

Scorecard example

In addition, all above functions take invalid User inputs into consideration and give explanation on what went wrong and where to seek help.

User input validation example

Components and limitations

This is a NodeJS application, coded using Slack Bolt SDK. It is set up as Slack application. In the backend the data is stored in MongoDB; uDrop service is used to host generated images. The code is setup to be deployed to Heroku platform.

The application uses Got and Node HTML to Image packages to make API requests and generate images from HTML.

Although not actively used in the code as an API to produce and send messages back, half of the messages that are referenced in the message templates were generated (with very minor tweaks) by using OpenAI API Beta playground portal. I've got access to the open beta halfway through working on this project and was very impressed with the results that I was able to produce!

Since in this application we need to have actual emoji images to generate HTML table, the limitation of the application is that we need to add KarrotAwards custom emojis to Slack workspace to be able to generate leaderboard and scorecards.

Another limitation is that it looks like as of January 16, 2021 Slack commands are not supported in Slack Threads, so this application will not work there.

Setup and testing

First, Slack App needs to be configured and set up with Slash Command endpoint:

Slack app slash command setup

Also the app needs Interactivity & Shortcuts endpoint:

Slack app interactivity setup

The app needs bot scopes as follows:

Slack app scopes

The above URLs have been setup fot the DEV testing and the endpoints URL main domain is generated by Ngrok. Later it could be changed to what we get from Heroku by deploying to Staging/Production environment.

After that the app needs to be added to Slack workspace and the emojis listed in awards images need to be added (as an example, could be really anything else, even gif emojis) to Slack as custom emojis (with the same name as file names).

To setup the backend MongoDB an account needs to be created at MongoDB. The DB needs to be created with the following collections: ScoreCards, Awards, MessageTemplates. In Awards collection insert the following data (as an example, could be really anything according to the desired setup). Similarly, to the MessageTemplates we need to add the following data. The Awards data is tied to the custom Slack emojis added earlier by the emoji name, as in :karrotawards_emoji:.

An account needs to be created to be able to upload and host images on uDrop.

To go from DEV testing to Staging/Prodiuction the application can be deployed to Heroku platform. Staging environment can be any personally created Slack workspace, while Production would be considered an organization's workspace. Note: when setting the project in Heroku the following buildpacks need to be installed:

Heroku buildpacks

Also for optimal experience Heroku should be setup with Hobby dyno type at minimum (free dyno goes to sleep which breaks the app, because Slack gives only 3 seconds to generate the modal on received command, and Heroku dynos cannot restart that quick).

All required ENV variables are listed in this file and here is the short explanation as to what they are:

  • PORT -> port on which app will listen, for DEV doesn't really matter, for Heroku has to be 8000
  • SLACK_SIGNING_SECRET -> signing secret that you get when setting up Slack app
  • SLACK_BOT_TOKEN -> Slack app bot token that you get by adding app to the workspace, typically should have format of xoxb-...
  • MONGODB_USER_NAME -> user name for MongoDB
  • MONGODB_USER_PASSWORD -> user password for MongoDB
  • MONGODB_CLUSTER_URL -> MongoDB cluster URL
  • MONGODB_NAME -> name of your MongoDB where you have Awards, MessageTemplates and ScoreCards collections
  • MAX_NUMBER_OF_SELECTED_USERS -> controls how many users can be selected in the app modal for awards
  • MAX_NUMBER_OF_SELECTED_AWARDS -> controls how many different awards can be given at once
  • AWARD_MESSAGE_MAX_CHARACTER_NUMBER -> controls max length of the award message that user is allowed to type in the modal
  • LEADERBOARD_DEFAULT_NUMBER_OF_USERS -> default number of users to show in the /karrotawards leaderboard command
  • LEADERBOARD_MAX_NUMBER_OF_USERS -> maximum allowed number of users to be shown in the /karrotawards leaderboard x command
  • UDROP_KEY1 -> uDrop requires two keys to authenticate API, so this is one of them
  • UDROP_KEY2 -> uDrop requires two keys to authenticate API, so this is one of them
  • CONTRIBUTE_EMAIL_ADDR -> in /karrotawards help command there is a message at the bottom with contact email. This is different between different environments, so I made it configurable
  • WORK_NOTIFICATION_TIMEOUT_INTERVAL_MILLISECONDS -> controls how long each command should execute before sending generic "work in progress" to the user. This is needed to show user that something is happening for long running operations (such as image generation and upload), but do not show it for typically fast operations (such as modal opening), which sometimes can stil ltake long enough time, so that in this case the "work in progress" will be shown as well

Code structure

The main code file is app.js in which most of the work happens. The main user entry points are:

  • app.command('/karrotawards', async ({ ack, body, respond, client }) => { ... -> listener for any /karrotawards command payload
  • app.view({ callback_id: 'karrotawards_modal_callback_id', type: 'view_submission' }, async ({ ack, body, view }) => { ... -> listener for awards modals submissions
  • app.view({ callback_id: 'karrotawards_modal_callback_id', type: 'view_closed' }, async ({ ack, body, view }) => { ... -> listener for awards modals closing, needed mostly for user interaction and behaviour analysis and logging

Everything else is separate block functions that support the above entry points. Additionally, there are helpers related to HTML (generation) functionality and modal (generation, validation, data extraction) functionality.

Observations and lessons learned

After I released the application to my organization Slack, 25 users safely and happily switched to KarrotAwards and ditched their Word doc, moreover, 32 new Users started using the app in the first week of the release! 😆 I even did a presentation about this project in a monthly digital Townhall!

As for lessons learned - this whole project was a really amazing experience for me, since everything that has been done here I did for the first time! Slack API, Bolt SDK, NodeJS, MongoDB, uDrop, Ngrok, Heroku, Got, NodeHTMLToImage, OpenAI GPT-3 Beta API - all these things I've done research on and put together as I was learning about them - was a one big exciting journey that helped to bring my vision to life and share it with others while having quite a lot of fun! 😊

Future improvements

  1. One improvement that I would really like to explore with this project is actual production use of OpenAI API and their GPT-3 engine to fully generate the award announcement messages on the fly. This could also be used for leaderboard announcements. For that I would need to experiment more with the API and GPT-3 engine to make sure it produces the results that are adequate for my use case. After that I would present my project to OpenAI team for approval.
  2. Explore usability, availability and speed of some of the blockchain file hosting platforms, and integrate the use of those into this application. One of potential platforms could be Sia.

About

Slack app for giving emoji awards.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published