Skip to content

Instantly share code, notes, and snippets.

@lucaswilric
Last active May 29, 2020 04:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucaswilric/3f655aa1af166dbb82595fd721a4180c to your computer and use it in GitHub Desktop.
Save lucaswilric/3f655aa1af166dbb82595fd721a4180c to your computer and use it in GitHub Desktop.
slackme: Wraps your Bash command, and sends you a Slack message when it's done.
#!/bin/bash
## The 'slackme' script
#
# This is a wrapper for arbitrary commands, which invokes the command,
# waits until the command has finished executing, then sends a message
# to you on Slack to report on the command's success or failure.
#
# Usage:
#
# slackme [command]
#
# If invoked without a command, 'slackme' will send you a default
# message right away.
#
# Examples:
#
# Wait 5 seconds, then send a message:
#
# slackme sleep 5
#
# Or, if you don't care about the result of the command:
#
# sleep 5; slackme
#
# Send me a failure message:
#
# slackme false
#
## Off we go!
#
# First, we check for the environment variables required to make all
# this work.
#
# I chose to warn and continue if they're not present, because this
# thing isn't important enough (IMO) to stop somebody in their tracks.
#
# First, set the canPost variable to a truthy value - we'll set it
# false-y if we need to.
canPost=0
# SLACKME_SLACK_URL is the webhook URL we're going to POST to in order
# to send our "done" message.
#
if [ -z "${SLACKME_SLACK_URL}" ]; then
echo "WARNING: The SLACKME_SLACK_URL environment variable isn't set, so I can't post to Slack." 1>&2
echo "To get the value you need for this env var, you'll need to create a Slack Webhook. Read Slack's documentation for that process at https://api.slack.com/messaging/webhooks" 1>&2
echo "Your webhook URL contains a secret, so don't commit it to GitHub!" 1>&2
canPost=1
fi
# Set a default username, because that's better than crashing, or
# even warning.
#
botUserName="${SLACKME_BOT_USERNAME:-Slackme Script}"
# Grab the command that we'll be executing today, and give it an
# exciting name.
#
cmd="$@"
# Set some parameters for the message that we'll send when the command
# finishes.
#
color="good"
msgTitle="Your thing (${cmd}) is done"
msgBody="That thing you were waiting for (${cmd}) is finished!"
# If we have been given a command to run, it's time to run it and
# store the exit code in a variable for later (so we can be transparent
# by quitting with the same code, which will mean that && and || work
# the same as if we weren't here).
#
# If we don't have a command, then let's not refer to it ;)
#
if [ -n "$1" ]; then
$SHELL -ic "${cmd}"
exit_code=$?
else
msgTitle="Your thing is done"
msgBody="That thing you were waiting for is finished!"
fi
# Time to send the message, if we're able to post it.
#
if [ 0 -eq "${canPost}" ]; then
# First, we build our payload.
#
read -d '' payLoad << EOS
{
"username": "${botUserName:-$(hostname)}",
"icon_emoji": ":panda_face:",
"attachments": [
{
"fallback": "${msgTitle}",
"color": "${color}",
"title": "${msgTitle}",
"text": "${msgBody}",
"mrkdwn_in": ["text"]
}
]
}
EOS
# Then we send the payload in a request to the configured webhook,
# storing the status code that comes back so that we can exit with
# an error if (a) there was no command, and (b) the request didn't
# work.
#
# (If there's no command, then there's nothing to be transparent
# about, so producing our own exit code makes sense.)
#
statusCode=$(curl \
--write-out %{http_code} \
--silent \
--output /dev/null \
-X POST \
-H 'Content-type: application/json' \
--data "${payLoad}" ${SLACKME_SLACK_URL})
fi
# Finally, we need to work out what code to exit with.
#
# The exit code from the user's command takes precedence, even if
# the Slack webhook request failed.
#
if [ -z "${exit_code}" ]; then
exit ${exit_code}
fi
# If there was no command, and we got a status code (which we might
# not if the SLACKME_SLACK_URL env var is unset), and that status code
# is not '200' for OK, then we exit with an error.
#
if [ -n "${statusCode}" -a "${statusCode}" != "200" ]; then
echo "${statusCode}"
exit 1
fi
# And that's that. Happy notifying!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment