Good Morning Slack Bot 🤖

danielbellmas

Daniel Bellmas

Posted on July 11, 2022

Good Morning Slack Bot 🤖

TL;DR
I made a slack app that says Good Morning with a random emoji and gif at a random time after 8 AM.

For the code and detailed step by step on how to install the bot, click on the repo below 👨‍💻👩‍💻👇

Good Morning Bot

A slack app that sends a 'Good Morning' with a random emoji and gif, every workday in the morning.

Good Morning

Installation

Clone the repo:

git clone https://github.com/danielbellmas/good-morning-bot.git
Enter fullscreen mode Exit fullscreen mode

Install dependencies with npm:

cd good-morning-bot
npm install 
Enter fullscreen mode Exit fullscreen mode

💡 Before you can run the project you'll need some environment variables 👇

Environment Variables

In order to run this project, you will need to add the following environment variables to your .env file.

Follow these instructions to get Slack's environment variables.

By signing in to Giphy, you can obtain the GIPHY API KEY.

Here are the env variables you'll be needing: (you can also view them here)

#Slack
SLACK_BOT_TOKEN=xoxb-...
SLACK_USER_TOKEN=xoxp-...
SLACK_SIGNING_SECRET=00...
SLACK_APP_TOKEN=xapp-...

#Giphy API
GIPHY_API_KEY=X...
Enter fullscreen mode Exit fullscreen mode

Run project:

npm start
Enter fullscreen mode Exit fullscreen mode

Resources




After coming up with the idea, I started with a simple app: An app that squares up a number it gets from the user.
I started small to give myself time to get acquainted with slack's framework: @slack/bolt

Seeing everything worked gave me the OK to start thinking about how to achieve the goal: Send a good morning message every workday (as myself).

Here are the objectives:

  1. Get a random emoji from the emoji list.
  2. Fetch a random gif from the Giphy API.
  3. Send every workday - not including holidays.
  4. Send the massage in the morning.
  5. Send the message as myself.
  6. Deploy the bot

Let’s start 🦾

1. The random emoji

Emoji list

You might be wondering why there are several instances of the sun emoji ☀️.
Well… that’s for giving this emoji a higher chance to be picked.
After all, it’s the most appropriate emoji IMO.

For picking a random item from a list I use the pick function:

pick function

2. The random gif

For that, I used Giphy’s API.
I also considered a set list of gifs, stored in a JSON file, but fetching on the fly is more fun. 👾

https://api.giphy.com/v1/gifs/search?api_key=${process.env.GIPHY_API_KEY}&q=good morning
Enter fullscreen mode Exit fullscreen mode

In order to get the GIPHY_API_KEY you need to sign into Giphy.

3. Send the message on every workday

Sometimes I think there’s a package for every need… so naturally, I looked for one…and found a package called hebcal! 🤯
With a little research, I saw that they expose an API for dates of holidays, among other things.
With this API I could expose a function that tells me if it’s a day off (don't send the message) or a workday (do send the message).

That was the hard part, the easy part is to check if it’s a weekend or not:

function isWeekend(date = new Date()): boolean {
  return date.getDay() === 5 || date.getDay() === 6;
}
Enter fullscreen mode Exit fullscreen mode

4. Send the message in the morning

Ok. A quick recap: We've managed to pick a random emoji and gif, and avoid sending the message on the weekend and on days off.

Now we can get to the juicy part: actually sending the message and timing it so that it will happen at a random time each workday.

Why random you ask? because we can't have them know it's a bot.👻

Schedule the massage - code snippet

Code Breakdown

  • In order to send every day we need to check if we need to send or not, every period of time (I chose every half an or so), and we can achieve that with the setTimeout function.
  • If the current hour is 8 am, we check that:
  • We didn't already send a message today.
  • It's not the weekend.
  • It's not a day off.

Only then do we send the massage and set isSentToday to true, That way, we'll only send once a day. ⚡️

5. Send the message as myself

So this one was a tricky one for me.
At first, I didn't really find out what was missing to make it work.
I saw the as_user option but setting it to true was not enough. We also need to pass in the user's token (in our case it's our own token).

Send massage function

With the help of slacks API we can call postMessage and see our bot come to life 🤖 🦾 🦿

6. Deploy the bot

Deploying will allow us to run the bot independently from our machine.
I deployed mine on heroku.
If you already looked at the code, you may have seen the Procfile - the file that says to heroku what command to execute in order to run the app.

worker: npm start
Enter fullscreen mode Exit fullscreen mode

If you're familiar with heroku than you probably saw web: npm start.
Here we are using the worker option because we want it to always run in the background:

worker dynos (non-web) do not sleep (as they don't receive web requests), so they will run 24/7.

Heroku has a limitation for the number of dyno hours per month. But the good news is that a free user has 1000 free dyno hours per month, which means more than 730 hours (The number of hours in a month).

Disclaimer: This is just the way I implemented the idea.
If you have a different idea, write a comment 🙂

Good Morning message

🔥 Bonus 🔥

Minimizing API calls by fetching for the holiday JSON only once at the beginning of each month.

To fetch only once every month we need to introduce cron, or more specifically node-schedule

Cron syntax gif

If you want to play with the cron syntax, use cron.guru.

Cron is a scheduler or timer that automatically starts a job.

Schedule job - code snippet
You can find this code in the utils folder under dayOff.ts

Every 1st of the month we'll fetch - getHolidays() and save the result in a JSON file.
And every time we'll want to check if today is a holiday, we'll just read the file instead of making an API call 🦅

💖 💪 🙅 🚩
danielbellmas
Daniel Bellmas

Posted on July 11, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related