Rafael Almeida

@rafaelcpalmeida

Automate Your Slack Interactions

Photography by Ales Nesetril on Unsplash

I’m a big fan of automating repetitive tasks and I always try to automate everything I can. Remember the guy that automated part of his job? I try to do some similar stuff too! Imagine the following scenario: everytime that you close your MacBook Pro lid it sends a message, telling your team that you’re gone for the day. In this article, I’m going to show how to do this!

In order to send messages on Slack, you’ll need a Slack Access Token. To get one you need to create a new Slack app, install in your workspace, go to OAuth & Permissions and copy your generated OAuth Access Token.

To be able to execute scripts when your Mac goes to sleep or wakes up we’ll use Bernhard Baehr’s SleepWatcher 2.2. After you download the file, unpack it and open a new Terminal window on its directory and type the following:

$ sudo mkdir -p /usr/local/sbin /usr/local/share/man/man8
$ sudo cp sleepwatcher /usr/local/sbin
$ sudo cp sleepwatcher.8 /usr/local/share/man/man8

In this article I’m just going to write about the sleep event trigger. If you want to know about more events or read the documentation just type:

$ man sleepwatcher

Now that SleepWatcher is in the correct place you can try the script that’s going to be executed with the following command:

$ /usr/local/sbin/sleepwatcher --verbose --sleep /path/to/your/sleepscript

After you’re finished with the tests and everything behaves as expected is time to setup SleepWatcher to run as a daemon. To do this you can type the following commands:

$ sudo cp config/de.bernhard-baehr.sleepwatcher-20compatibility.plist /Library/LaunchDaemons/de.bernhard-baehr.sleepwatcher.plist
$ sudo cp config/rc.* /usr/local/bin

After that just execute to start your daemon.

$ sudo launchctl load /Library/LaunchDaemons/de.bernhard-baehr.sleepwatcher.plist

Now that everything is ready you need to write the script that’s going to be executed everytime your computer goes to sleep. We’re calling it .sleep and make it executable:

$ touch ~/.sleep
$ chmod +x ~/.sleep

In this file, we’re going to place the code that’s going to be used to post our messages to Slack. Mine looks like:

#!/bin/bash
STARTING_TIME="17:00"
ENDING_TIME="19:00"
CURRENT_TIME=$(date +%H:%M)
CURRENT_DATE=$(date "+%d/%m/%Y")
READ_DATE=$(cat ~/.say_message.lock)
if [[ "$CURRENT_TIME" > "$STARTING_TIME" ]] && [[ "$CURRENT_TIME" < "$ENDING_TIME" ]] && [[ "$READ_DATE" < "$CURRENT_DATE" ]]; then
    TOKEN=xoxp-2…
    CHANNEL=#channel_name
    declare -a EXPRESSIONS=("Write" "Your" "Expressions" "Here")
    SELECTED_EXPRESSION=${EXPRESSIONS[$RANDOM % ${#EXPRESSIONS[@]} ]}
    curl -X POST \
        --connect-timeout 10 \
        --max-time 10 \
        --retry 10 \
        --retry-delay 0 \
        --retry-max-time 60 \
        --'content-type: multipart/form-data' \
        -F token=$TOKEN \
        -F "channel=$CHANNEL" \
        -F text="$SELECTED_EXPRESSION" \
        -F as_user=true \
        https://slack.com/api/chat.postMessage
        echo $CURRENT_DATE > ~/.say_message.lock
fi

Let me explain the script line by line.

Script explanation

I’m using the following variables to specify that the message is meant to be sent only between 17:00 and 19:00

STARTING_TIME="17:00"
ENDING_TIME="19:00"

These are used to ensure that the message is only sent once per day, to prevent sending it multiple every time that you lock your computer, for instance.

CURRENT_TIME=$(date +%H:%M)
CURRENT_DATE=$(date "+%d/%m/%Y")
READ_DATE=$(cat ~/.say_message.lock)

The if condition bellow allows me to ensure that the conditions I’ve specified above are met. Which are: the message is only sent between 17:00 and 19:00 and only executes once per day.

if [[ "$CURRENT_TIME" > "$STARTING_TIME" ]] && [[ "$CURRENT_TIME" < "$ENDING_TIME" ]] && [[ "$READ_DATE" < "$CURRENT_DATE" ]]; then
fi

In order to send the message to the desired channel you have to specify the token you got from Slack and the channel to post the message. I also have an array of expressions to be randomized later. This is meant to send a different message. To achieve this I have the following lines:

TOKEN=xoxp-2[…]
CHANNEL=#channel_name
declare -a EXPRESSIONS=("Write" "Your" "Expressions" "Here")
SELECTED_EXPRESSION=${EXPRESSIONS[$RANDOM % ${#EXPRESSIONS[@]} ]}

When everything is set we need to send our message to Slack API. This is done using cURL. These are my configs:

curl -X POST \
--connect-timeout 10 \
--max-time 10 \
--retry 10 \
--retry-delay 0 \
--retry-max-time 60 \
--'content-type: multipart/form-data' \
-F token=$TOKEN \
-F "channel=$CHANNEL" \
-F text="$SELECTED_EXPRESSION" \
-F as_user=true \
https://slack.com/api/chat.postMessage

I’m telling cURL to:

  • Each attempt last 10 seconds with --max-time 10
  • Retry 10 times using --retry 10
  • Disable cURL sleep between retries using --retry-delay 0
  • Wait 60 seconds max using --retry-max-time 60

The code above will send a POST request to https://slack.com/api/chat.postMessage with the specified payload. You can check more about postMessage endpoint reading Slack documentation.

After the execution of the request I’m updating the “lock” file with the new date with the line:

echo $CURRENT_DATE > ~/.say_message.lock

This is meant to ensure that only one message per day is sent.

This is how I automated my interactions with Slack. Let me know your thoughts on this using the comments bellow.

More by Rafael Almeida

Topics of interest

More Related Stories