Creating a Slack Reaction Bot

Brian Bernberg

Here at GameChanger, we periodically send out surveys to our customers as a way of gauging how we’re doing and to calculate our Net Promoter Score (NPS). At the end of the day, our number one goal is to please our customers and measuring our NPS is a useful metric to ensure we’re working toward that goal. We use Delighted to orchestrate our NPS surveys. Many companies send these surveys out to their customers:

After assigning a numeric grade, the user also has the opportunity to add comments to their survey response:

Of course, comments only benefit us if we actually see them and they aren’t sent off to a deep, dark database that no one checks! Thankfully, Delighted provides a useful service that automatically posts NPS feedback to a Slack channel. We have configured Delighted to automatically post a Slack message to a channel whenever an NPS survey is received with comments:


When we send a survey through Delighted, we add user properties (sport, team adminisrator/fan, free/premium, etc.) so that we can determine how we’re doing with different segments of our user base. Delighted can easily calculate an NPS result for only users with specific properties.

We started to realize that seeing NPS comments in Slack was great but understanding context around the user who commented would be even more useful. Undertanding that Delighted already had this information in the form of user properties, I spent a hack day creating a service to automatically show user properties in Slack using reactions.

Feedback Reaction

Reactions are the perfect way to accomplish this because they are able to communicate a lot of information in a small space.

Slack and Delighted both have API’s to enable this. The first step was to set-up a small Python/Django app on Heroku to make and process all of the various API calls. The next step was figuring out how to know when Delighted posted an NPS message to our Slack channel. Slack offers an Outgoing Webhook service which performs a POST to a URL whenever a new message is posted in a specified channel – exactly what I needed!

The next step was to figure out if the Slack message was from Delighted (since any Slack user can post to the channel) and if so, the e-mail of the user who sent the comment. The user e-mail is sent in a message attachment from Delighted but unfortunately (though understandably), Slack does not include message attachments in the webhook POST. Slack messages are uniquely identified by channel name and timestamp (both of which are included in the webhook POST). I was unable to find a Slack endpoint to retrieve a specific message but I was able to work around this using the channels.history method, which does return message attachments:

def get_message(channel, timestamp):
    results =, data={
        'token': SLACK_TOKEN,
        'channel': channel,
        'latest': timestamp,
        'oldest': timestamp,
        'inclusive': 1}).json()
    messages = results.get('messages')
    if len(messages) > 0:
        return messages[0]

The next step was parsing the message attachment for the user’s e-mail (using a regular expression). If one existed, this e-mail was then used to retrieve the user properties from Delighted using the survey responses endpoint. The final step was translating these user properties to reactions and adding the appropriate reactions to the Delighted message via the reactions.add method. I added a new emoji for each user property so that hovering over the reaction indicates which user property the reaction represents:

All of this was accomplished in less than 150 lines of Python code thanks to the useful API’s Slack and Delighted provide. We are gaining valuable insight about our customers and hopefully we’ll improve our Net Promoter Scores as a result.