Automate Your Slack Interactions
Tags: tutorial, bash, productivity
Published: 2019-07-29 11:26:13

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](https://www.businessinsider.com/programmer-automates-his-job-2015-11)? I try to do some similar stuff too! Imagine the following scenario: every time 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!

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](https://www.bernhard-baehr.de/)’s [SleepWatcher 2.2](https://www.bernhard-baehr.de/sleepwatcher_2.2.tgz). After you download the file, unpack it and open a new Terminal window on its directory and type the following:

```bash
$ 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:

```bash
$ 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:

```bash
$ /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:

```bash
$ 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.

```bash
$ 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 every time your computer goes to sleep. We’re calling it .sleep and make it executable:

```bash
$ 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:

```bash
#!/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

```bash
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 every time that you lock your computer, for instance.

```bash
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.
```bash
if [[ "$CURRENT_TIME" > "$STARTING_TIME" ]] && [[ "$CURRENT_TIME" < "$ENDING_TIME" ]] && [[ "$READ_DATE" < "$CURRENT_DATE" ]]; then

fi
```

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:

```bash
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:

```bash
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](https://api.slack.com/methods/chat.postMessage).

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

```bash
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 below.