How to post a message to your Slack channel with cURL (from bash)

I’ll get straight to it. Here’s the code:


VERSION="$(hg log -r . -T'{node}')"
OVERLAY="${1:-staging}"
SLACK_CHANNEL=$([[ "$OVERLAY" == 'production' ]] && echo '#prod' || echo '#staging')
CHANGELOG=$(hg log -r "::$VERSION - ::tag('$OVERLAY') - user('$HG_USER') - merge()" -T '[{node|short}] {date|date}: {desc}\n' | tee /dev/tty)

IFS='' read -r -d '' SLACK_PAYLOAD <<'JSON'
{
    "channel": $channel,
    "blocks": [
        {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": $message
            }
        },
        {
            "type": "section",
            "text": {
                "type": "plain_text",
                "text": $changelog
            }
        }
    ]
}
JSON

SLACK_PAYLOAD=$(jq -nc \
    --arg channel "$SLACK_CHANNEL" \
    --arg message "Deployed \`$VERSION\` to $OVERLAY" \
    --arg changelog "${CHANGELOG:-No changes.}" \
    "$SLACK_PAYLOAD") || exit 4

curl -H "Content-type: application/json; charset=utf-8" \
    -sS \
    --data "$SLACK_PAYLOAD" \
    -H "Authorization: Bearer $SLACK_API_TOKEN" \
    -X POST 'https://slack.com/api/chat.postMessage' | jq -c

We’re using jq to properly format a JSON message here. Without it, there’s a high probability that the $changelog would break due to having line breaks and quotes in it; jq will take care of the escaping for us.

I’m using Mercurial (hg) here but you can swap our the commands for git if you prefer.

This sends a message like this to my Slack channel when ran:

I have this in my deploy script so everyone can see when something is deployed.

To get an API key, you can follow the first half of this tutorial: https://api.slack.com/tutorials/tracks/posting-messages-with-curl