Post messages to slack from Bash

19-03-2016
source code

Introduction

This bash script will post a message to Slack. It can be easily changed to fit your needs but it can be used as it is as well. This script is very useful to send notifications for background tasks for example.

The script

This bash script is utelising curl to post a message to a given slack channel. The script expects 4 arguments:

  1. title of the message
  2. message body
  3. Slack channel name
  4. Slack hook url

Having said that there is nothing preventing you from adding extra parameters, for example you can add an emoji as an argument for further customising your messages look and feel.

Usage block

The script starts with a function which returns the usage block. Usage function acts as documentation for the program. This function is called if the user doesn't pass any of the parameters or as a default response if the user just trid to execute the script without passing anything. Listing 1.1 shows the usage function

function usage {
    programName=$0
    echo "description: use this program to post messages to Slack channel"
    echo "usage: $programName [-t \"sample title\"] [-b \"message body\"] [-c \"mychannel\"] [-u \"slack url\"]"
    echo "    -t    the title of the message you are posting"
    echo "    -b    The message body"
    echo "    -c    The channel you are posting to"
    echo "    -u    The slack hook url to post to"
    exit 1
}

Listing 1: usage function

Extracting arguments

Listing 2 shows how I am extracting and validating arguments for this script

while getopts ":t:b:c:u:h" opt; do
  case ${opt} in
    t) msgTitle="$OPTARG"
    ;;
    u) slackUrl="$OPTARG"
    ;;
    b) msgBody="$OPTARG"
    ;;
    c) channelName="$OPTARG"
    ;;
    h) usage
    ;;
    \?) echo "Invalid option -$OPTARG" >&2
    ;;
  esac
done

if [[ ! "${msgTitle}" ||  ! "${slackUrl}" || ! "${msgBody}" || ! "${channelName}" ]]; then
    echo "all arguments are required"
    usage
fi

Listing 2: extracting and validating arguments

Minimal validating for arguments is happening here however you can add whatever extra validation that you want. For example you may want to restrict the channel name to be of certain values

Posting the message

The rest of the script is using curl to post the message to Slack.

Note how I am utilising the read command to format the json payload. This technique offers maximum readability and customisation for your message payload. This program output the status code returned from curl. So anything but 200 means failure

read -d '' payLoad << EOF
{
        "channel": "#${channelName}",
        "username": "$(hostname)",
        "icon_emoji": ":sunglasses:",
        "attachments": [
            {
                "fallback": "${msgTitle}",
                "color": "good",
                "title": "${msgTitle}",
                "fields": [{
                    "title": "message",
                    "value": "${msgBody}",
                    "short": false
                }]
            }
        ]
    }
EOF


statusCode=$(curl \
        --write-out %{http_code} \
        --silent \
        --output /dev/null \
        -X POST \
        -H 'Content-type: application/json' \
        --data "${payLoad}" ${slackUrl})

echo ${statusCode}

Listing 3: posting message to Slack and return status code

Installing

If you don't have a bin folder under your home folder then create one and place this script in it. Alternatively you can place this script in /usr/local/bin/code so that it is available for all users

Next you need to make this script executable

chmod +x postToSlack.sh

Create symbolic link - optional

You can create a symlink for this script so you can name it whatever you want or use it without the .sh extension. If you do this then there is no need to place the script in the bin folder mentioned before

# Available for current user only
ln -s /path/to/postToSlack.sh ~/bin/postToSlack

# Available for all users
sudo ln -s /path/to/postToSlack.sh /usr/local/bin/postToSlack

Now you can use the script from command line like this

postToSlack -t "this is a title" -b "this is a message body" -c "sulhome" -u "<slack hook url>"

Calling from other scripts

you can call this program from other bash scripts like this for example

#!/usr/bin/env bash

statusCode=$(postToSlack -t "this is a title" -b "this is another a message body" -c "sulhome" -u "<slack hook url>")

if [[ ${statusCode} == "200" ]]; then
    echo "posted successfully"
else
    echo "error"
fi