Organize Lunch teams at Work (2)

How to interact with Slack using AWS Lambda function

Yun Sangho
4 min readJul 7, 2019

Following the previous article, In this article, I will talk to how I developed the bot to interact with Slack in more detail.

The bot has four features:

  • Post a message to a Slack channel on a specific time.
  • Get events from a channel and record it in the database.
  • Take the records in the DB, organize them and send the result to a channel.
  • Initialize the database after creating teams.

I thought that these features would be pretty simple and it would not spend much time to implement, but there were several problems that I did not expect.

Let’s go into detail about each of the features

Post a message to a channel

The first feature that I implemented is the one that posts a message to a channel in our Slack workspace and those of us who want to eat lunch together add an emoji on it.

I used Slack Incoming Webhook to get an URL to post messages to the channel and AWS Cloud Watch Events to trigger a messaging event in a specific time before lunch.

The feature works:

  1. Every weekday at 11:40 AM Cloud Watch Events triggers the Lambda function.
  2. The function sends a POST request with a message in the body to Slack webhook.
  3. The webhook posts the message to #cafeteria channel.

Get events from a channel and record it in the database

Next feature is parsing a user data that added or removed emoji on the message that the bot sent right before, records it into the database to organize teams for lunch later.

To get the information from Slack, I used Slack Events API.

Slack Events API

Through Slack Events API, I subscribed reaction_added and reaction_removed events, so Slack sends me a JSON object when these events occur in our workspace.

The structure of the JSON is:

{
"token": "z26uFbvR1xHJEdHE1OQiO6t8",
"team_id": "T061EG9RZ",
"api_app_id": "A0FFV41KK",
"event": {
"type": "reaction_added",
"user": "U061F1EUR",
"item": {
"type": "message",
"chanenel": "C061EG9SL",
"ts": "1464196127.000002"
},
"reaction": "slightly_smiling_face",
"item_user": "U0M4RL1NY",
"event_ts": "1465244570.336841"
},
"type": "event_callback",
"authed_users": [
"U061F7AUR"
],
"event_id": "Ev9UQ52YNA",
"event_time": 1234567890
}
  • type — The specific name of the event.
  • item— The message, file or others that event coming from.
  • item_user — The id of the user that created the event.
  • event_ts — The timestamp of the event.

Note: If you want to more detailed information about Slack Events API, click the link Slack Events API.

The Problem

As I tried to handle the event object, I just realized there is a problem that Slack posts all the events triggered in the entire workspace to a Lambda function so it needs to deal with every event even though it did not occur on the message that bot sent. It feels really inefficient to me so I started to think about to solve this problem.

Finally, I found out that a message post by the bot does not have item_user key in an event object otherwise it would be an id of a user. and Using this fact, I started to implement the Lambda function.

Event Handler function

If an event is triggered in the workspace, it is sent to a Lambda function and eventHandler function is called. First, to figure out the event is related to our happy lunchtime, it checks:

  1. The event object has item_user key.
  2. The event came from #cafeteria channel.
  3. The event occurred between 11:40 AM to 1:00 PM.

If the event achieves all conditions above, the function eventHanldler calls another handler which manages that event type. Otherwise, it returns HTTP request with status 500 and quits.

Create a new record on the database

One of us adds an emoji on the message means that she/he wants to go have lunch together. addEmojiHandler catches the event and insert user_id into the database.

Delete a record on the database

Someone removes an emoji means that he/she changes his/her mind and does not go to eat lunch together. so reaction_removed event occurs removeEmojiHandler finds his/her record in the database and delete it.

Organize teams and post them to Slack channel

The third feature is that organizing teams and sending the result to #cafeteria .

At 11:59 AM, a Lambda function is triggered which gets records from the database, organizes teams by data and send a result to Slack channel.

Initialize database after creating teams

I stored user ids into the database, but I wondered whether I keep storing it or not.

There will be some chances to use them after, but as it is just a side project, I do not really want to make it complex, if the database is initialized everyday, I do not have to care about the date of record and make the logic more simple.

So, I just decided to delete all data in the database and refresh it after our lunch break finishes, at 2:00 PM the Lambda function which initializes the database runs.

Conclusion

At 11:40 AM, a message is posted on Slack and we add emojis on it wondering who are going to be my lunch mates.

At 11:59 AM, today’s teams appear on Slack and we just go eat lunch!

We do not waste times to decide who eat lunch with whom anymore and enjoy our lunch.

Organize Lunch Team!

--

--