Skip to content
Permalink
main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
@iay
Latest commit e16cf06 Jul 29, 2016 History
1 contributor

Users who have contributed to this file

executable file 608 lines (550 sloc) 16.1 KB
#!/usr/bin/env bash
# ----------
# Default Configuration
# ----------
webhook_url="" # Incoming Webhooks integration URL
upload_token="" # The user's API authentication token, only used for file uploads
channel="general" # Default channel to post messages. '#' is prepended, if it doesn't start with '#' or '@'.
tmp_dir="/tmp" # Temporary file is created in this directory.
username="slacktee" # Default username to post messages.
icon="ghost" # Default emoji to post messages. Don't wrap it with ':'. See http://www.emoji-cheat-sheet.com; can be a url too.
attachment="" # Default color of the attachments. If an empty string is specified, the attachments are not used.
# ----------
# Initialization
# ----------
me=$(basename "$0")
title=""
mode="buffering"
link=""
textWrapper="\`\`\`"
parseMode=""
fields=()
# Since bash 3 doesn't support the associative array, we store colors and patterns separately
cond_color_colors=()
cond_color_patterns=()
found_pattern_color=""
# This color is used when 'attachment' is used without color specification
internal_default_color="#C0C0C0"
# Since bash 3 doesn't support the associative array, we store prefixes and patterns separately
cond_prefix_prefixes=()
cond_prefix_patterns=()
found_title_prefix=""
function show_help()
{
echo "usage: $me [options]"
echo " options:"
echo " -h, --help Show this help."
echo " -n, --no-buffering Post input values without buffering."
echo " -f, --file Post input values as a file."
echo " -l, --link Add a URL link to the message."
echo " -c, --channel channel_name Post input values to specified channel or user."
echo " -u, --username user_name This username is used for posting."
echo " -i, --icon emoji_name|url This icon is used for posting. You can use a word"
echo " from http://www.emoji-cheat-sheet.com or a direct url to an image."
echo " -t, --title title_string This title is added to posts."
echo " -m, --message-formatting format Switch message formatting (none|link_names|full)."
echo " See https://api.slack.com/docs/formatting for more details."
echo " -p, --plain-text Don't surround the post with triple backticks."
echo " -a, --attachment [color] Use attachment (richly-formatted message)"
echo " Color can be 'good','warning','danger' or any hex color code (eg. #439FE0)"
echo " See https://api.slack.com/docs/attachments for more details."
echo " -e, --field title value Add a field to the attachment. You can specify this multiple times."
echo " -s, --short-field title value Add a short field to the attachment. You can specify this multiple times."
echo " -o, --cond-color color pattern Change the attachment color if the specified Regex pattern matches the input."
echo " You can specify this multile times."
echo " If more than one pattern matches, the latest matched pattern is used."
echo " -d, --cond-prefix prefix pattern This prefix is added to the message, if the specified Regex pattern matches the input."
echo " You can specify this multile times."
echo " If more than one pattern matches, the latest matched pattern is used."
echo " --config config_file Specify the location of the config file."
echo " --setup Setup slacktee interactively."
}
function send_message()
{
message="$1"
# Prepend the prefix to the message, if it's set
if [[ -z $attachment && -n $found_pattern_prefix ]]; then
message="$found_pattern_prefix$message"
# Clear conditional prefix for the nest send
found_pattern_prefix=""
fi
escaped_message=$(echo "$textWrapper\n$message\n$textWrapper" | sed 's/"/\\"/g' | sed "s/'/\\'/g" )
message_attr=""
if [[ $message != "" ]]; then
if [[ -n $attachment ]]; then
# Set message color
message_color="$attachment"
if [[ -n $found_pattern_color ]]; then
message_color="$found_pattern_color"
# Reset with the default color for the next send
found_pattern_color="$attachment"
fi
message_attr="\"attachments\": [{ \"color\": \"$message_color\", \"mrkdwn_in\": [\"text\", \"fields\"], \"text\": \"$escaped_message\" "
if [[ -n $found_pattern_prefix ]]; then
orig_title=$title
title="$found_pattern_prefix $title"
# Clear conditional prefix for the nest send
found_pattern_prefix=""
fi
if [[ -n $title ]]; then
message_attr="$message_attr, \"title\": \"$title\" "
# Clear conditional prefix from title
title=$orig_title
fi
if [[ -n $link ]]; then
message_attr="$message_attr, \"title_link\": \"$link\" "
fi
if [[ $mode == "file" ]]; then
fields+=("{\"title\": \"Access URL\", \"value\": \"$access_url\" }")
fields+=("{\"title\": \"Download URL\", \"value\": \"$download_url\"}")
fi
if [[ ${#fields[@]} != 0 ]]; then
message_attr="$message_attr, \"fields\": ["
for field in "${fields[@]}"; do
message_attr="$message_attr $field,"
done
message_attr=${message_attr%?} # Remove last comma
message_attr="$message_attr ]"
fi
# Close attachment
message_attr="$message_attr }], "
else
message_attr="\"text\": \"$escaped_message\","
fi
icon_url="$icon"
#icon_emoji=""
#if echo "$icon" | grep -q "^https\?://.*"; then
# icon_url="$icon"
#else
# icon_emoji=":$icon:"
#fi
json="{\"channel\": \"$channel\", \"username\": \"$username\", $message_attr \"icon_emoji\": \"$icon_emoji\", \"icon_url\": \"$icon_url\" $parseMode}"
post_result=$(curl -X POST --data-urlencode "payload=$json" "$webhook_url" 2> /dev/null)
exit_code=1
if [[ $post_result == "ok" ]]; then
exit_code=0
fi
fi
}
function process_line()
{
echo "$1"
line="$(echo "$1" | sed $'s/\t/ /g')"
# Check the patterns of the conditional colors
# If more than one pattern matches, the latest pattern is used
if [[ ${#cond_color_patterns[@]} != 0 ]]; then
for i in "${!cond_color_patterns[@]}"; do
if [[ $line =~ ${cond_color_patterns[$i]} ]]; then
found_pattern_color=${cond_color_colors[$i]}
fi
done
fi
# Check the patterns of the conditional titles
# If more than one pattern matches, the latest pattern is used
if [[ ${#cond_prefix_patterns[@]} != 0 ]]; then
for i in "${!cond_prefix_patterns[@]}"; do
if [[ $line =~ ${cond_prefix_patterns[$i]} ]]; then
found_pattern_prefix=${cond_prefix_prefixes[$i]}
if [[ -n $attachment || $mode != "no-buffering" ]]; then
# Append a line break to the prefix for better formatting
found_pattern_prefix="$found_pattern_prefix\n"
else
# Append a space to the prefix for better formatting
found_pattern_prefix="$found_pattern_prefix "
fi
fi
done
fi
if [[ $mode == "no-buffering" ]]; then
prefix=''
if [[ -z $attachment ]]; then
prefix=$title
fi
send_message "$prefix$line"
elif [[ $mode == "file" ]]; then
echo "$line" >> "$filename"
else
if [[ -z "$text" ]]; then
text="$line"
else
text="$text\n$line"
fi
fi
}
function setup()
{
if [[ -z "$HOME" ]]; then
echo "\$HOME is not defined. Please set it first."
exit 1
fi
local_conf="$HOME/.slacktee"
if [[ -e "$local_conf" ]]; then
echo ".slacktee is found in your home directory."
read -p "Are you sure to overwrite it? [y/n] :" choice
case "$choice" in
y|Y )
# Continue
;;
* )
exit 0 # Abort
;;
esac
fi
# Load current local config
. $local_conf
# Start setup
read -p "Incoming Webhook URL [$webhook_url]: " input_webhook_url
if [[ -z "$input_webhook_url" ]]; then
input_webhook_url=$webhook_url
fi
read -p "Upload Token [$upload_token]: " input_upload_token
if [[ -z "$input_upload_token" ]]; then
input_upload_token=$upload_token
fi
read -p "Temporary Directory [$tmp_dir]: " input_tmp_dir
if [[ -z "$input_tmp_dir" ]]; then
input_tmp_dir=$tmp_dir
fi
read -p "Default Channel [$channel]: " input_channel
if [[ -z "$input_channel" ]]; then
input_channel=$channel
fi
read -p "Default Username [$username]: " input_username
if [[ -z "$input_username" ]]; then
input_username=$username
fi
read -p "Default Icon: [$icon]: " input_icon
if [[ -z "$input_icon" ]]; then
input_icon=$icon
fi
read -p "Default color of the attachment. (empty string disables attachment) [$attachment]: " input_attachment
if [[ -z "$input_attachment" ]]; then
input_attachment=$attachment
elif [[ $input_attachment == '""' || $input_attachment == "''" ]]; then
input_attachment=""
fi
cat <<- EOF | sed 's/^[[:space:]]*//' > "$local_conf"
webhook_url="$input_webhook_url"
upload_token="$input_upload_token"
tmp_dir="$input_tmp_dir"
channel="$input_channel"
username="$input_username"
icon="$input_icon"
attachment="$input_attachment"
EOF
}
# ----------
# Parse command line options
# ----------
OPTIND=1
while [[ $# -gt 0 ]]; do
opt="$1"
shift
case "$opt" in
-h|\?|--help)
show_help
exit 0
;;
-n|--no-buffering)
mode="no-buffering"
;;
-f|--file)
mode="file"
;;
-l|--link)
link="$1"
shift
;;
-c|--channel)
opt_channel="$1"
shift
;;
-u|--username)
opt_username="$1"
shift
;;
-i|--icon)
opt_icon="$1"
shift
;;
-t|--title)
title="$1"
shift
;;
-d|--cond-prefix)
case "$1" in
-*|'')
# Found next command line option or empty. Error.
echo "a prefix of the conditional title was not specified"
show_help
exit 1
;;
*)
# Prefix should be found
case "$2" in
-*|'')
# Found next command line option or empty. Error.
echo "a pattern of the conditional title was not specified"
show_help
exit 1
;;
*)
# Set the prefix and the pattern to arrays
cond_prefix_prefixes+=("$1")
cond_prefix_patterns+=("$2")
shift
shift
;;
esac
;;
esac
;;
-m|--message-formatting)
case "$1" in
none)
parseMode=', "parse": "none"'
;;
link_names)
parseMode=', "link_names": "1"'
;;
full)
parseMode=', "parse": "full"'
;;
*)
echo "unknown message formatting option"
show_help
exit 1
;;
esac
shift
;;
-p|--plain-text)
textWrapper=""
;;
-a|--attachment)
case "$1" in
-*|'')
# Found next command line option
opt_attachment="$internal_default_color" # Use default color
;;
\#*|good|warning|danger)
# Found hex color code or predefined colors
opt_attachment="$1"
shift
;;
*)
echo "unknown attachment color"
show_help
exit 1
;;
esac
;;
-o|--cond-color)
case "$1" in
-*|'')
# Found next command line option or empty. Error.
echo "a color of the conditional color was not specified"
show_help
exit 1
;;
\#*|good|warning|danger)
# Found hex color code or predefined colors
case "$2" in
-*|'')
# Found next command line option or empty. Error.
echo "a pattern of the conditional color was not specified"
show_help
exit 1
;;
*)
# Set the color and the pattern to arrays
cond_color_colors+=("$1")
cond_color_patterns+=("$2")
shift
shift
;;
esac
;;
*)
echo "unknown attachment color $1"
show_help
exit 1
;;
esac
;;
-e|-s|--field|--short-field)
case "$1" in
-*|'')
# Found next command line option or empty. Error.
echo "field title was not specified"
show_help
exit 1
;;
*)
case "$2" in
-*|'')
# Found next command line option or empty. Error.
echo "field value was not specified"
show_help
exit 1
;;
*)
if [[ $opt == "-s" || $opt == "--short-field" ]]; then
fields+=("{\"title\": \"$1\", \"value\": \"$2\", \"short\": true}")
else
fields+=("{\"title\": \"$1\", \"value\": \"$2\"}")
fi
shift
shift
;;
esac
esac
;;
--config)
CUSTOM_CONFIG=$1
shift
;;
--setup)
setup
exit 1
;;
*)
echo "illegal option $opt"
show_help
exit 1
;;
esac
done
# ---------
# Read in our configurations
# ---------
if [[ -e "/etc/slacktee.conf" ]]; then
. /etc/slacktee.conf
fi
if [[ -n "$HOME" && -e "$HOME/.slacktee" ]]; then
. "$HOME/.slacktee"
fi
if [[ -e "$CUSTOM_CONFIG" ]]; then
. $CUSTOM_CONFIG
fi
# Overwrite webhook_url if the environment variable SLACKTEE_WEBHOOK is set
if [[ "$SLACKTEE_WEBHOOK" != "" ]]; then
webhook_url="$SLACKTEE_WEBHOOK"
fi
# Overwrite upload_token if the environment variable SLACKTEE_TOKEN is set
if [[ "$SLACKTEE_TOKEN" != "" ]]; then
upload_token="$SLACKTEE_TOKEN"
fi
# Overwrite channel if it's specified in the command line option
if [[ "$opt_channel" != "" ]]; then
channel="$opt_channel"
fi
# Overwrite username if it's specified in the command line option
if [[ "$opt_username" != "" ]]; then
username="$opt_username"
fi
# Overwrite icon if it's specified in the command line option
if [[ "$opt_icon" != "" ]]; then
icon="$opt_icon"
fi
# Overwrite attachment if it's specified in the command line option
if [[ "$opt_attachment" != "" ]]; then
attachment="$opt_attachment"
fi
# Set the default color to attachment if it's still empty and the length of the cond_color_patterns is not 0
if [[ -z $attachment ]] && [[ ${#cond_color_patterns[@]} != 0 ]]; then
attachment="$internal_default_color"
fi
# ----------
# Validate configurations
# ----------
if [[ $webhook_url == "" ]]; then
echo "Please setup the webhook url of this incoming webhook integration."
exit 1
fi
if [[ $upload_token == "" && $mode == "file" ]]; then
echo "Please provide the authentication token for file uploads."
exit 1
fi
if [[ $channel == "" ]]; then
echo "Please specify a channel."
exit 1
elif [[ ( "$channel" != "#"* ) && ( "$channel" != "@"* ) ]]; then
channel="#$channel"
fi
if [[ -n "$icon" ]]; then
icon=${icon#:} # remove leading ':'
icon=${icon%:} # remove trailing ':'
fi
# ----------
# Start script
# ----------
text=""
if [[ -n "$title" || -n "$link" ]]; then
# Use link as title, if title is not specified
if [[ -z "$title" ]]; then
title="$link"
fi
# Add title to filename in the file mode
if [[ "$mode" == "file" ]]; then
filetitle=$(echo "$title"|sed 's/[ /:.]//g')
filetitle="$filetitle-"
fi
if [[ -z "$attachment" ]]; then
if [[ "$mode" == "no-buffering" ]]; then
if [[ -n "$link" ]]; then
title="<$link|$title>: "
else
title="$title: "
fi
elif [[ "$mode" == "file" ]]; then
if [[ -n "$link" ]]; then
title="<$link|$title>"
fi
else
if [[ -n "$link" ]]; then
text="-- <$link|$title> --\n"
else
text="-- $title --\n"
fi
fi
fi
fi
timestamp="$(date +'%m%d%Y-%H%M%S')"
filename="$tmp_dir/$filetitle$$-$timestamp.log"
if [[ "$mode" == "file" ]]; then
touch $filename
fi
exit_code=0
while IFS='' read line; do
process_line "$line"
done
if [[ -n $line ]]; then
process_line "$line"
fi
if [[ "$mode" == "buffering" ]]; then
send_message "$text"
elif [[ "$mode" == "file" ]]; then
if [[ -s "$filename" ]]; then
channels_param=""
if [[ ( "$channel" == "#"* ) ]]; then
# Set channels for making the file public
channels_param="-F channels=$channel"
fi
result="$(curl -F file=@"$filename" -F token="$upload_token" $channels_param https://slack.com/api/files.upload 2> /dev/null)"
access_url="$(echo "$result" | awk 'match($0, /url_private":"([^"]*)"/) {print substr($0, RSTART+14, RLENGTH-15)}'|sed 's/\\//g')"
download_url="$(echo "$result" | awk 'match($0, /url_private_download":"([^"]*)"/) {print substr($0, RSTART+23, RLENGTH-24)}'|sed 's/\\//g')"
if [[ -n "$attachment" ]]; then
text="Input file has been uploaded"
else
if [[ "$title" != "" ]]; then
title=" of $title"
fi
text="Input file$title has been uploaded.\n$access_url\n\nYou can download it from the link below.\n$download_url"
fi
send_message "$text"
fi
# Clean up the temp file
rm "$filename"
fi
exit $exit_code