├── .gitignore ├── icons └── png │ ├── beer.png │ ├── code.png │ ├── disk.png │ ├── stop.png │ ├── aws-rds.png │ ├── bug-ok.png │ ├── cpu-ok.png │ ├── cron-ok.png │ ├── dunkin.png │ ├── mem-ok.png │ ├── net-ok.png │ ├── slack.png │ ├── stop2.png │ ├── sync-ok.png │ ├── time-ok.png │ ├── aws-cache.png │ ├── bug-error.gif │ ├── bug-error.png │ ├── bug-info.png │ ├── bug-warn.png │ ├── cpu-error.png │ ├── cpu-info.png │ ├── cpu-warn.png │ ├── cron-warn.png │ ├── maint-ok.png │ ├── mem-error.png │ ├── mem-info.png │ ├── mem-warn.png │ ├── monit-ok.png │ ├── net-error.png │ ├── net-info.png │ ├── net-warn.png │ ├── skull-ok.png │ ├── starbucks.png │ ├── sync-info.png │ ├── sync-warn.png │ ├── time-info.png │ ├── time-warn.png │ ├── aws-redshift.png │ ├── cron-error.png │ ├── integration.png │ ├── maint-error.png │ ├── maint-info.png │ ├── maint-warn.png │ ├── monit-error.png │ ├── monit-info.png │ ├── monit-warn.png │ ├── skull-error.png │ ├── sync-error.png │ ├── time-error.png │ ├── xbones-error.png │ ├── control-panel.png │ ├── database-check.png │ ├── monit-message.png │ ├── starbucks-logo.png │ └── generic-message.png ├── Dockerfile ├── LICENSE ├── etc └── slack.d │ └── monit ├── slack.sh └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /icons/png/beer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/beer.png -------------------------------------------------------------------------------- /icons/png/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/code.png -------------------------------------------------------------------------------- /icons/png/disk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/disk.png -------------------------------------------------------------------------------- /icons/png/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/stop.png -------------------------------------------------------------------------------- /icons/png/aws-rds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/aws-rds.png -------------------------------------------------------------------------------- /icons/png/bug-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/bug-ok.png -------------------------------------------------------------------------------- /icons/png/cpu-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/cpu-ok.png -------------------------------------------------------------------------------- /icons/png/cron-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/cron-ok.png -------------------------------------------------------------------------------- /icons/png/dunkin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/dunkin.png -------------------------------------------------------------------------------- /icons/png/mem-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/mem-ok.png -------------------------------------------------------------------------------- /icons/png/net-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/net-ok.png -------------------------------------------------------------------------------- /icons/png/slack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/slack.png -------------------------------------------------------------------------------- /icons/png/stop2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/stop2.png -------------------------------------------------------------------------------- /icons/png/sync-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/sync-ok.png -------------------------------------------------------------------------------- /icons/png/time-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/time-ok.png -------------------------------------------------------------------------------- /icons/png/aws-cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/aws-cache.png -------------------------------------------------------------------------------- /icons/png/bug-error.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/bug-error.gif -------------------------------------------------------------------------------- /icons/png/bug-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/bug-error.png -------------------------------------------------------------------------------- /icons/png/bug-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/bug-info.png -------------------------------------------------------------------------------- /icons/png/bug-warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/bug-warn.png -------------------------------------------------------------------------------- /icons/png/cpu-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/cpu-error.png -------------------------------------------------------------------------------- /icons/png/cpu-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/cpu-info.png -------------------------------------------------------------------------------- /icons/png/cpu-warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/cpu-warn.png -------------------------------------------------------------------------------- /icons/png/cron-warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/cron-warn.png -------------------------------------------------------------------------------- /icons/png/maint-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/maint-ok.png -------------------------------------------------------------------------------- /icons/png/mem-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/mem-error.png -------------------------------------------------------------------------------- /icons/png/mem-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/mem-info.png -------------------------------------------------------------------------------- /icons/png/mem-warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/mem-warn.png -------------------------------------------------------------------------------- /icons/png/monit-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/monit-ok.png -------------------------------------------------------------------------------- /icons/png/net-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/net-error.png -------------------------------------------------------------------------------- /icons/png/net-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/net-info.png -------------------------------------------------------------------------------- /icons/png/net-warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/net-warn.png -------------------------------------------------------------------------------- /icons/png/skull-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/skull-ok.png -------------------------------------------------------------------------------- /icons/png/starbucks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/starbucks.png -------------------------------------------------------------------------------- /icons/png/sync-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/sync-info.png -------------------------------------------------------------------------------- /icons/png/sync-warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/sync-warn.png -------------------------------------------------------------------------------- /icons/png/time-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/time-info.png -------------------------------------------------------------------------------- /icons/png/time-warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/time-warn.png -------------------------------------------------------------------------------- /icons/png/aws-redshift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/aws-redshift.png -------------------------------------------------------------------------------- /icons/png/cron-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/cron-error.png -------------------------------------------------------------------------------- /icons/png/integration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/integration.png -------------------------------------------------------------------------------- /icons/png/maint-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/maint-error.png -------------------------------------------------------------------------------- /icons/png/maint-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/maint-info.png -------------------------------------------------------------------------------- /icons/png/maint-warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/maint-warn.png -------------------------------------------------------------------------------- /icons/png/monit-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/monit-error.png -------------------------------------------------------------------------------- /icons/png/monit-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/monit-info.png -------------------------------------------------------------------------------- /icons/png/monit-warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/monit-warn.png -------------------------------------------------------------------------------- /icons/png/skull-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/skull-error.png -------------------------------------------------------------------------------- /icons/png/sync-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/sync-error.png -------------------------------------------------------------------------------- /icons/png/time-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/time-error.png -------------------------------------------------------------------------------- /icons/png/xbones-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/xbones-error.png -------------------------------------------------------------------------------- /icons/png/control-panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/control-panel.png -------------------------------------------------------------------------------- /icons/png/database-check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/database-check.png -------------------------------------------------------------------------------- /icons/png/monit-message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/monit-message.png -------------------------------------------------------------------------------- /icons/png/starbucks-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/starbucks-logo.png -------------------------------------------------------------------------------- /icons/png/generic-message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbridge/ob_hacky_slack/HEAD/icons/png/generic-message.png -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | RUN apk add --update \ 3 | bash \ 4 | curl \ 5 | && rm /var/cache/apk/* 6 | COPY slack.sh /usr/bin/slack 7 | RUN chmod +x /usr/bin/slack \ 8 | && mkdir -p /tmp \ 9 | && touch /tmp/ip.txt 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /etc/slack.d/monit: -------------------------------------------------------------------------------- 1 | USERNAME="monit @ ${IP}" 2 | TITLE="${MONIT_SERVICE}" 3 | TEXT="${MONIT_DESCRIPTION}" 4 | PRETEXT="${MONIT_DATE} | ${MONIT_HOST}: ${MONIT_EVENT}" 5 | FALLBACK="${MONIT_DATE} | ${MONIT_HOST}: ${MONIT_EVENT}" 6 | 7 | if test "${PRIORITY}" = "OK"; then echo "INFO: STATUS (-s) is OK. Setting a default STATUS to OK..." && ICON=${ICON:-'monit-ok'} && COLOR=${COLOR:-'#36a64f'}; fi 8 | if test "${PRIORITY}" = "INFO"; then echo "INFO: STATUS (-s) is INFO. Setting a default STATUS to INFO..." && ICON=${ICON:-'monit-info'} && COLOR=${COLOR:-'#439FE0'}; fi 9 | if test "${PRIORITY}" = "WARN"; then echo "INFO: STATUS (-s) is WARN. Setting a default STATUS to WARN..." && ICON=${ICON:-'monit-warn'} && COLOR=${COLOR:-'#ed7d21'}; fi 10 | if test "${PRIORITY}" = "ERROR"; then echo "INFO: STATUS (-s) is ERROR. Setting a default STATUS to ERROR..." && ICON=${ICON:-'monit-error'} && COLOR=${COLOR:-'#E21B6C'}; fi 11 | 12 | 13 | # Save for later 14 | # if grep -Fq 'Action done' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 15 | # if grep -Fq 'Checksum' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 16 | # if grep -Fq 'Download bytes' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 17 | # if grep -Fq 'Upload bytes' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 18 | # if grep -Fq 'Connection' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 19 | # if grep -Fq 'Data access' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 20 | # if grep -Fq 'Execution' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 21 | # if grep -Fq 'GID' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 22 | # if grep -Fq 'Ping' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 23 | # if grep -Fq 'Monit instance' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 24 | # if grep -Fq 'type' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 25 | # if grep -Fq 'Link' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 26 | # if grep -Fq 'Download packets' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 27 | # if grep -Fq 'Upload packets' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 28 | # if grep -Fq 'Permission' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 29 | # if grep -Fq 'PID' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 30 | # if grep -Fq 'PPID' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 31 | # if grep -Fq 'Resource limit' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 32 | # if grep -Fq 'Saturation' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 33 | # if grep -Fq 'Size' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 34 | # if grep -Fq 'Speed' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 35 | # if grep -Fq 'Status' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 36 | # if grep -Fq 'Timeout' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 37 | # if grep -Fq 'Timestamp' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 38 | # if grep -Fq 'UID' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 39 | # if grep -Fq 'Uptime' ${MONIT_DESCRIPTION}; then ICON=${ICON-':cpu:'}; fi 40 | -------------------------------------------------------------------------------- /slack.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ---------- 4 | # API Endpoint 5 | # ---------- 6 | # Default WEBHOOK to post messages 7 | if [[ -n ${WEBHOOK} ]]; then 8 | echo "INFO: The Slack API WEBHOOK was passed via the command line (-w)" 9 | elif [[ -n ${SLACK_WEBHOOK} ]]; then 10 | echo "INFO: The Slack API TOKEN was set as a system variable" 11 | WEBHOOK=${SLACK_WEBHOOK} 12 | else 13 | echo "INFO: Using default Slack API endpoint to POST messages..." 14 | WEBHOOK=${WEBHOOK-'https://hooks.slack.com/services/'} 15 | fi 16 | 17 | # ---------- 18 | # Environment 19 | # ---------- 20 | HOSTNAME=${hostname-$(hostname -s)} 21 | EPOCH=$(date +%s) 22 | CONFIG="/etc/slack.d" 23 | IPCONFIG="/tmp/ip.txt" 24 | 25 | # ---------- 26 | # IP 27 | # --------- 28 | # Check for the IP address every 2 hours. Use cache for anything < 2 hours 29 | if [[ ! -f "${IPCONFIG}" ]]; then 30 | echo "INFO: ${IPCONFIG} does not exist. Creating..." 31 | IP=$(curl -s checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//') 32 | touch ${IPCONFIG} 33 | echo "IP=${IP}" > ${IPCONFIG} 34 | else 35 | if test "find '${IPCONFIG}' -mmin +120"; then 36 | echo "INFO: ${IPCONFIG} is less than 2 hours old. We will use the cached IP in ${IPCONFIG}..." 37 | else 38 | IP=$(curl -s checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//') 39 | echo "WARNING: ${IPCONFIG} is more than 2 hours old. Updating the IP in ${IPCONFIG}..." 40 | echo "IP=${IP}" > ${IPCONFIG} 41 | fi 42 | fi 43 | 44 | source ${IPCONFIG} 45 | 46 | # ---------- 47 | # Commands 48 | # ---------- 49 | function GET_HELP() { 50 | echo "Usage: [options]" 51 | echo " options:" 52 | echo "-a, Attachment Sends a messages as an attachment." 53 | echo "-A, Author Small text used to display the author's name." 54 | echo "-b, Author Link A URL that will hyperlink the author_name text mentioned above. (Author name is required)." 55 | echo "-B, Author Icon A URL that displays a small image to the left of the author_name text.(Author name is required)." 56 | echo "-c, Channel The location the messages should be delivered." 57 | echo "-C, Color This value is used to color the border along the left side of the message attachment." 58 | echo "-e, Environment This value is used to provide the message with an environment identifier." 59 | echo "-h, Help Show the command options for Slack." 60 | echo "-f, Footer Add a footer label." 61 | echo "-F, Footer Image Add a footer image." 62 | echo "-i, Icon A URL to an image file that will be displayed inside a message attachment." 63 | echo "-I, Image Small text used to display the author's name." 64 | echo "-m, Mode Mode toggles application specific behaviors (e.g., preconfigured Monit settings)." 65 | echo "-N, Thumbnail A URL to an image file that will be displayed as a thumbnail on the right side of a message attachment." 66 | echo "-p, Pretext This is optional text that appears above the message attachment block." 67 | echo "-s, Status An optional value that can either be one of ok, info, warn or error." 68 | echo "-Z, Text This is the main text in a message attachment, and can contain standard message markup." 69 | echo "-T, Title The title is displayed as larger, bold text near the top of a message attachmen." 70 | echo "-L, Title Link A valid URL in the will ensure the title text will be hyperlinked." 71 | echo "-k, Token Authenticates the POST to Slack." 72 | echo "-u, Username User that posts the message." 73 | echo "-w, Webhook The Slack API service endpoint to POST messages." 74 | exit 1 75 | } 76 | 77 | # Check if any arguments were passed 78 | if [[ $# -eq 0 ]]; then 79 | GET_HELP 80 | exit 1 81 | else 82 | while getopts ":a:A:b:B:c:C:e:h:i:I:m:N:p:s:Z:T:L:k:u:w" opt; do 83 | case ${opt} in 84 | a) ATTACHMENT="true" ;; 85 | A) AUTHOR="${OPTARG}" ;; 86 | b) AUTHORICON="${OPTARG}" ;; 87 | B) AUTHORLINK="${OPTARG}" ;; 88 | c) CHANNEL="${OPTARG}" ;; 89 | C) COLOR="${OPTARG}" ;; 90 | e) ENV="${OPTARG}" ;; 91 | h) GET_HELP ;; 92 | F) FOOTER="${OPTARG}" ;; 93 | f) FOOTERICON="${OPTARG}" ;; 94 | i) ICON="${OPTARG}" ;; 95 | I) IMAGE="${OPTARG}" ;; 96 | m) MODE="${OPTARG}" ;; 97 | N) THUMBNAIL="${OPTARG}" ;; 98 | p) PRETEXT="${OPTARG}" ;; 99 | s) 100 | if test "${OPTARG}" = "ok"; then PRIORITY="OK"; fi 101 | if test "${OPTARG}" = "info"; then PRIORITY='INFO'; fi 102 | if test "${OPTARG}" = "warn"; then PRIORITY='WARN'; fi 103 | if test "${OPTARG}" = "error"; then PRIORITY='ERROR'; fi 104 | ;; 105 | Z) TEXT="${OPTARG}" ;; 106 | T) TITLE="${OPTARG}" ;; 107 | L) TITLELINK="${OPTARG}" ;; 108 | k) TOKEN="${OPTARG}" ;; 109 | u) USERNAME="${OPTARG}" ;; 110 | w) WEBHOOK="${OPTARG}" ;; 111 | esac 112 | done 113 | fi 114 | 115 | # ---------- 116 | # Check for Token 117 | # ---------- 118 | echo "${SLACK_TOKEN}" 119 | # Default TOKEN to post messages 120 | if [[ -n ${TOKEN} ]]; then 121 | echo "INFO: The Slack API TOKEN was passed via the command line (-k)" 122 | elif [[ -n ${SLACK_TOKEN} ]]; then 123 | echo "INFO: The Slack API TOKEN was set as a system variable" 124 | TOKEN=${SLACK_TOKEN} 125 | else 126 | echo "ERROR: No Slack API TOKEN was found. Can not proceed with posting messages to the API without one." 127 | exit 1 128 | fi 129 | 130 | # ---------- 131 | # Service Specific Configurations 132 | # ---------- 133 | # Service specific configurations are passed using -m 134 | # For example, the include monit config (/etc/slack.d/monit) will leverage mMonit specific environment variables to set message attributes. 135 | 136 | # We look for this first, if no config exists we use defaults 137 | 138 | if [[ -n "${MODE}" ]]; then 139 | test -d "${CONFIG}" && echo "INFO: The ${CONFIG} direcotry exists" || echo "WARNING: The ${CONFIG} direcotry does not exist. Creating..."; mkdir -p ${CONFIG} 140 | curl -o "${CONFIG}/${MODE}" -z "${CONFIG}/${MODE}" "https://raw.githubusercontent.com/gonace/ob_hacky_slack/develop/etc/slack.d/${MODE}" --verbose 141 | if [[ -z "${MODE}" ]]; then 142 | echo "INFO: No Monit variables are present" 143 | else 144 | source "${CONFIG}/${MODE}" 145 | fi 146 | else 147 | 148 | # ---------- 149 | # Style Setting 150 | # ---------- 151 | # Certain elements should be part of a message. Rather than simply exit, we post placeholders to highlight the fact the information is missing 152 | # Set stauts attributes 153 | if test "${PRIORITY}" = "OK"; then echo "INFO: STATUS (-s) was set to OK..."; ICON=${ICON:-'good'} && COLOR=${COLOR:-'#36a64f'}; fi 154 | if test "${PRIORITY}" = "INFO"; then echo "INFO: STATUS (-s) was set to INFO..."; ICON=${ICON:-'info'} && COLOR=${COLOR:-'#439FE0'}; fi 155 | if test "${PRIORITY}" = "WARN"; then echo "INFO: STATUS (-s) was set to WARN..."; ICON=${ICON:-'warn'} && COLOR=${COLOR:-'#ed7d21'}; fi 156 | if test "${PRIORITY}" = "ERROR"; then echo "INFO: STATUS (-s) was set to ERROR..."; ICON=${ICON:-'error'} && COLOR=${COLOR:-'#E21B6C'}; fi 157 | if test -z "${USERNAME}"; then echo "INFO: A USERNAME (-u) was not specified for this POST to the Slack API. Setting a default username..."; USERNAME="${IP}"; fi 158 | fi 159 | 160 | # ---------- 161 | # Test Message 162 | # ---------- 163 | # We will test for key parts of the message as they should be present 164 | if [[ -z "${TEXT+x}" ]]; then echo "WARNING: You do not have any TEXT (-t) specified in the message."; TEXT="${TEXT:-'This message is missing TEXT'}"; else echo "INFO: TEXT is set to '${TEXT}'"; fi 165 | if [[ -z "${TITLE+x}" ]]; then echo "WARNING: You do not have a TITLE (-T) specified for the message."; TITLE=${TITLE:-'This message is missing a TITLE'}; else echo "INFO: TITLE is set to '${TITLE}'"; fi 166 | if [[ -z "${PRETEXT+x}" ]]; then echo "WARNING: You do not have a PRETEXT (-p) specified for the message."; PRETEXT=${PRETEXT:-'This message is missing a PRETEXT'}; else echo "INFO: PRETEXT is set to '${PRETEXT}'"; fi 167 | if [[ -z "${CHANNEL+x}" ]]; then echo "WARNING: A CHANNEL (-c) was not set. Using the default CHANNEL..."; CHANNEL=${CHANNEL:-'general'}; else echo "INFO: CHANNEL is set to '${CHANNEL}'"; fi 168 | if [[ -z "${PRIORITY+x}" ]]; then echo echo "INFO: STATUS (-s) was not set. Setting a default STATUS to INFO..."; PRIORITY=${PRIORITY:-'INFO'} && ICON=${ICON:-'info'} && COLOR=${COLOR:-'#439FE0'}; else echo "INFO: PRIORITY is set to '${PRIORITY}'"; fi 169 | if [[ -z "${ENV+x}" ]]; then echo "INFO: A ENV (-e) was not set. Using the default ENV..."; ENV=${ENV:-'Development'}; else echo "INFO: ENV is set to '${ENV}'"; fi 170 | if [[ -z "${FOOTERICON+x}" ]]; then echo "INFO: A FOOTERICON (-f) was not set. Using the default FOOTERICON..."; FOOTERICON=${FOOTERICON:-'https://platform.slack-edge.com/img/default_application_icon.png'}; else echo "INFO: FOOTERICON is set to '${FOOTERICON}'"; fi 171 | if [[ -z "${FOOTER+x}" ]]; then echo "INFO: A FOOTER (-F) was not set. Using the default FOOTER..."; FOOTER=${AUTHOR}; else echo "INFO: FOOTER is set to '${FOOTER}'"; fi 172 | 173 | # ---------- 174 | # Send Message 175 | # ---------- 176 | function SEND() { 177 | # The complete Slack API payload, including attachments# 178 | if [[ ${ATTACHMENT} = "true" ]]; then 179 | PAYLOAD="payload={ \ 180 | \"channel\": \"${CHANNEL}\", \ 181 | \"username\": \"${USERNAME}\", \ 182 | \"pretext\": \"${PRETEXT}\", \ 183 | \"color\": \"${COLOR}\", \ 184 | \"icon_emoji\": \":${ICON}:\", \ 185 | \"text\": \"${TEXT}\", \ 186 | \"mrkdwn\": \"true\", \ 187 | \"attachments\": [{ 188 | \"fallback\": \"${FALLBACK}\", \ 189 | \"color\": \"${COLOR}\", \ 190 | \"pretext\": \"${PRETEXT}\", \ 191 | \"author_name\": \"${AUTHOR}\", \ 192 | \"author_link\": \"${AUTHORLINK}\", \ 193 | \"author_icon\": \"${AUTHORICON}\", \ 194 | \"title\": \"${TITLE}\", \ 195 | \"title_link\": \"${TITLELINK}\", \ 196 | \"text\": \"${TEXT}\", \ 197 | \"mrkdwn_in\": [\"text\",\"pretext\",\"fields\"], \ 198 | \"fields\": [{\"title\": \"Status\",\"value\": \"${PRIORITY}\",\"short\": \"true\"}, {\"title\": \"Host\",\"value\": \"${IP}\",\"short\": \"true\"}, {\"title\": \"Environment\",\"value\": \"${ENV}\",\"short\": \"true\"} ], \ 199 | \"image_url\": \"${IMAGE}\", \ 200 | \"footer\": \"${FOOTER}\", \ 201 | \"footer_icon\": \"${FOOTERICON}\", \ 202 | \"ts\": \"${EPOCH}\" \ 203 | 204 | }]}" 205 | else 206 | PAYLOAD="payload={ \ 207 | \"channel\": \"${CHANNEL}\", \ 208 | \"username\": \"${USERNAME}\", \ 209 | \"pretext\": \"${PRETEXT}\", \ 210 | \"color\": \"${COLOR}\", \ 211 | \"icon_emoji\": \":${ICON}:\", \ 212 | \"text\": \"${TEXT}\", \ 213 | \"mrkdwn\": \"true\" \ 214 | }" 215 | fi 216 | 217 | # Send the payload to the Slack API 218 | echo "OK: All tests passed, sending message to Slack API..." 219 | POST=$(curl -s -S -X POST --data-urlencode "${PAYLOAD}" "${WEBHOOK}${TOKEN}"); 220 | 221 | # Check if the message posted to the Slack API. A successful POST should return "ok". Anything other than "ok" indicates an issue 222 | if test "${POST}" != ok; then echo "ERROR: The POST to the Slack API failed (${POST})" && return 1; else echo "OK: Message successfully sent to the channel ${CHANNEL} via the Slack API"; fi 223 | } 224 | 225 | SEND 226 | exit 0 227 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![Hack Slack](https://github.com/openbridge/ob_hacky_slack/blob/master/icons/png/slack.png "Optional title") 3 | # Hacky Slack: A Bash Slack API Client 4 | 5 | Hacky Slack is a bash script that will post messages to a Slack webhook API endpoint. 6 | 7 | From Slack: 8 | 9 | _Incoming Webhooks are a simple way to post messages from external sources into Slack. They make use of normal HTTP requests with a JSON payload, which includes the message and a few other optional details described later. Message Attachments () can also be used in Incoming Webhooks to display richly-formatted messages that stand out from regular chat messages._ 10 | 11 | Why is it called Hacky Slack? First, this reflects my "hacking" something together that accomplished my goals. Second, I played a ton of Hacky Sack () when I was a teenager. 12 | 13 | # Overview 14 | 15 | There are two goal of Hacky Slack. The first was to was to create a generic Slack bash script for the messaging API. The second was to take advantage of the Slack messaging interface to allow applications, like Monit, to style its events. In support of both goals Hacky Slack offers customizations for external applications, like Monit, via external config files (See the Monit example). 16 | 17 | Also, in support of having more compelling Slack messages, a small collection of icons were created. The icons are meant to provide visual cues to the user so they can more easily identify the context of a message they received in Slack. 18 | 19 | # Requirements 20 | 21 | First, you need to get yourself a Slack account. Go to the Slack webite: 22 | 23 | Second, you need create an incoming webhook. Go here to learn how: 24 | 25 | As a result going through those two steps, you should get the following: 26 | 27 | ## Slack API Tokens 28 | 29 | You need to make sure that your Slack token is set as a system variable `${SLACK_TOKEN}` or you can pass it to Hacky Slack via `-k "whatever-you-get-from-slack"`. You can also hard code it into `slack.sh` as `TOKEN="whatever-you-get-from-slack"` 30 | 31 | ## Slack API Webhook Endpoint 32 | 33 | Hacky Slack will default to the Slack API endpoint URL ``. However, if you want to use a different one simply pass it via `-w ""` 34 | 35 | ## Environment 36 | 37 | Hacky Slack should run in most modern Linux environments. It has been tested in a CentOS 7 Docker container and Mac OS X. However, you will need to make sure a few things are setup in your environment: 38 | 39 | ### cURL 40 | 41 | Hacky Slack requires cURL (). Most systems have it installed. However, if you are running Hacky Slack in Docker cURL may not be installed. 42 | 43 | # Installation 44 | 45 | ## Slack API Bash Script 46 | 47 | Installation is pretty simple. Just copy the `slack.sh` to `/usr/bin`. 48 | 49 | ```bash 50 | cp slack.sh usr/bin/slack.sh 51 | ``` 52 | 53 | Then `chmod +x /usr/bin/slack.sh` 54 | 55 | You can also copy `slack.sh` to `/usr/bin` as: 56 | 57 | ```bash 58 | cp slack.sh usr/bin/slack 59 | ``` 60 | 61 | This assumes no conflicts exist in `/usr/bin`. Then `chmod +x /usr/bin/slack` 62 | 63 | If you want to include Hacky Slack directly from Github you can use wget: 64 | 65 | ```bash 66 | wget --no-check-certificate --directory-prefix=/usr/bin https://raw.githubusercontent.com/openbridge/ob_hacky_slack/master/slack.sh 67 | ``` 68 | 69 | Then `chmod +x /usr/bin/slack` 70 | 71 | If you decide to copy Hacky Slack to a different APP directory change the settings accordingly. 72 | 73 | # Using Hacky Slack 74 | 75 | Hacky Slack allowed you to pass a variety attributes as defined by the Slack messaging specs: 76 | 77 | ``` 78 | -a, Attachment: Sends a messages as an attachment. 79 | -A, Author: Small text used to display the author's name. 80 | -b, Author Link: A URL that will hyperlink the author_name text mentioned above. (Author name is required). 81 | -B, Author Icon: A URL that displays a small image to the left of the author_name text.(Author name is required). 82 | -c, Channel: The location the messages should be delivered. 83 | -C, Color: This value is used to color the border along the left side of the message attachment. 84 | -e, Environment: This value is used to provide the message with an environment identifier. 85 | -h, Help: Show the command options for Slack. 86 | -f, Footer: Add a footer label. 87 | -F, Footer Image: Add a footer image. 88 | -i, Icon: A URL to an image file that will be displayed inside a message attachment. 89 | -I, Image: Small text used to display the author's name. 90 | -m, Mode: Mode toggles application specific behaviors (e.g., preconfigured Monit settings). 91 | -N, Thumbnail: A URL to an image file that will be displayed as a thumbnail on the right side of a message attachment. 92 | -p, Pretext: This is optional text that appears above the message attachment block. 93 | -s, Status: An optional value that can either be one of ok, info, warn or error. 94 | -Z, Text: This is the main text in a message attachment, and can contain standard message markup. 95 | -T, Title: The title is displayed as larger, bold text near the top of a message attachmen. 96 | -L, Title Link: A valid URL in the will ensure the title text will be hyperlinked. 97 | -k, Token: Authenticates the POST to Slack. 98 | -u, Username: User that posts the message. 99 | -w, Webhook: The Slack API service endpoint to POST messages. 100 | ``` 101 | 102 | For more information on the above parameters, please check out the Slack docs: 103 | 104 | - 105 | - 106 | 107 | # Send A Message Via Hacky Slack 108 | 109 | The channel is "general" with username "hacky-slack". The icon is "apple" and the author is "apple". The author name is linked to "apple.com" and the text sent in the message is "Where are the new 2016 Macbook models?" 110 | 111 | ```bash 112 | slack -c "#general" -u "hacky-slack" -i "apple" -a "Macbook" -b "http://www.apple.com/" -t "Where are the new 2016 Macbook models?" 113 | ``` 114 | 115 | Here is a sample message and a screenshot of the message with various flags set. 116 | 117 | ```bash 118 | slack -c "#general" -i ":slack:" -a "Hello World" -Z "Hello World" -T "Titles are awesome" -p "Pretext is so helpful to include" -s "info" 119 | ``` 120 | 121 | ```bash 122 | slack -c "#general" -u "steve" -i "dog" -a "Macbook Pro" -B "http://www.apple.com/" -p "Almost" -Z "Where are the new 2016 Macbook models" -s "ok" -T "Wow" -L "https://www.apple.com" -k "213912391-2093-10293ASSJASLKA" 123 | ``` 124 | 125 | Here is the command represented in Slack: 126 | 127 | ![Generic Message Examples](icons/png/generic-message.png?raw=true "Generic INFO") 128 | 129 | Note: These examples assume you have set your token and webhook endpoint. 130 | 131 | # Hacky Slack Docker Style 132 | 133 | There is a `Dockerfile` included which may simplify running the Hacky Slack. This assumes you have Docker installed. Simply build your image by running `docker build -t openbridge/hacky-slack .` 134 | 135 | Here is an example of running with Docker: 136 | 137 | ```bash 138 | docker run -it openbridge/hacky-slack slack -c "#general" -u "steve" -i "dog" -a "Macbook Pro" -B "http://www.apple.com/" -p "Almost" -Z "Where are the new 2016 Macbook models" -s "ok" -T "Wow" -L "https://www.apple.com" -k "213912391-2093-10293ASSJASLKA" 139 | ``` 140 | 141 | This is approach consumes a lot more space that the file alone. The total image is < 10MB. However, it might provide more flexibility in some use cases. Your mileage may vary. 142 | 143 | # Hacky Slack + Monit 144 | 145 | Monit is a system monitoring and recovery tool. More on Monit here: 146 | 147 | Hacky Slack was initially conceived to provide better support for Monit within Slack, especially customizing the Slack message UI to reflect smarter Monit events. Also, using Monit event variables in a Slack message allowed Hacky Slack the ability to trigger messages with minimal user input. This also means greater consistency for Monit messages as it ensures a common messaging approach across teams and systems. 148 | 149 | ## Monit Hack Slack Example Message 150 | 151 | Here is an example error message from Monit: 152 | 153 | ![Monit Examples](icons/png/monit-message.png?raw=true "Monit OK") 154 | 155 | Notice the icon and matching message color highlight. Also, the content of each message, when triggered by Monit, is automatically populated. 156 | 157 | This is accomplished by using Monit variables to populate specific parts of the Slack message: 158 | 159 | ``` 160 | USERNAME="monit @ ${IP}" 161 | TITLE="${MONIT_SERVICE}" 162 | TEXT="${MONIT_DESCRIPTION}" 163 | PRETEXT="${MONIT_DATE} | ${MONIT_HOST}: ${MONIT_EVENT}" 164 | FALLBACK="${MONIT_DATE} | ${MONIT_HOST}: ${MONIT_EVENT}" 165 | ``` 166 | 167 | ## Example Monit Status Icons 168 | 169 | The message will visually change based on the use of the status flag `-s`. Based on the `-s` passed to Hacky Slack, one of 4 treatments will be applied to the message: 170 | 171 | Icon: : : | Name 172 | ---------------------------------------------------------------- | ------------------------ 173 | ![Monit Ok](icons/png/monit-ok.png?raw=true "Monit OK") | Monit OK `-s "ok"` 174 | ![Monit info](icons/png/monit-info.png?raw=true "Monit INFO") | Monit INFO `-s "info"` 175 | ![Monit Warn](icons/png/monit-warn.png?raw=true "Monit WARN") | Monit WARN `-s "warn"` 176 | ![Monit Error](icons/png/monit-error.png?raw=true "Monit ERROR") | Monit ERROR `-s "error"` 177 | 178 | In a future release, the look and feel can be tailored to the specific Monit event. For example, if there is a network event, then Hack Slack would customize the message to reflect that event type by using a specific set of icons and colors. At the moment, the 4 events above are the only customizations that are active. 179 | 180 | ## Using Hacky Slack in Your Monit Configs 181 | 182 | Below is a Monit statement triggers an alert if the memory exceeds 15MB for 2 cycles. It will repeat the alert every 3 cycles. Once the condition that triggered the alert returns to normal, Monit will issue an all clear message to Slack. 183 | 184 | ``` 185 | if memory > 15 MB for 2 cycles then exec /usr/bin/bash -c "sh /usr/local/bin/slack.sh -a -c #testing -s error -M monit >> /ebs/logs/foo.log 2<&1" repeat every 3 cycles else if succeeded then exec /usr/bin/bash -c "sh /usr/local/bin/slack.sh -a -c #testing -s ok -M monit >> /ebs/logs/foo.log 2<&1" 186 | ``` 187 | 188 | The `-a` flag sets the attachment flag. This is the expanded message format seen above. The `-c` flag sets the channel to deliver the message to. In this case the channel is "#testing". The `-s` flag sets the status the message should inherit. The example above uses "error" and ok". Lastly, the `-M` flag is set to "monit". This tells Hacky Slack to use the Monit config. 189 | 190 | Here is an example for monitoring crond: 191 | 192 | ``` 193 | check process crond with pidfile "/var/run/crond.pid" 194 | start program = "/etc/init.d/crond start" with timeout 60 seconds 195 | stop program = "/etc/init.d/crond stop" 196 | if 2 restarts within 3 cycles then exec /usr/bin/bash -c "sh /usr/local/bin/slack.sh -a -c #testing -s error -M monit" repeat every 3 cycles else if succeeded then exec /usr/bin/bash -c "sh /usr/local/bin/slack.sh -a -c #testing -s ok -M monit" 197 | if 5 restarts within 5 cycles then timeout 198 | ``` 199 | 200 | ### Using Hacky Slack in with other apps. 201 | 202 | Hacky Slack can be extended to support other applications besides Monit. For example, Nagios monitoring or Cron. Really, any application can send messages via Hacky Slack. 203 | 204 | Since no user (`- u`) was specified it will default to using the host system IP address 205 | 206 | # Icons 207 | 208 | Included are various Slack themed icons ( 209 | 210 | ). The icons are sized at (128x128) to meet Slack requirements. To use these icons they need to be added via the Slack application UI and referenced in the command line flag -i. More icons will be added over time. 211 | 212 | ## AWS 213 | 214 | Icon: : | Name 215 | ----------------------------------------------------------- | --------------- 216 | ![bug Ok](icons/png/aws-cache.png?raw=true "bug OK") | AWS ElastiCache 217 | ![bug info](icons/png/aws-rds.png?raw=true "bug INFO") | AWS RDS 218 | ![bug Warn](icons/png/aws-redshift.png?raw=true "bug WARN") | AWS Redshift 219 | 220 | ## BUG 221 | 222 | Icon: : | Name 223 | ---------------------------------------------------------- | --------- 224 | ![bug Ok](icons/png/bug-ok.png?raw=true "bug OK") | bug OK 225 | ![bug info](icons/png/bug-info.png?raw=true "bug INFO") | bug INFO 226 | ![bug Warn](icons/png/bug-warn.png?raw=true "bug WARN") | bug WARN 227 | ![bug Error](icons/png/bug-error.gif?raw=true "bug ERROR") | bug ERROR 228 | 229 | ## CODE 230 | 231 | Icon: : | Name 232 | ----------------------------------------------- | ---- 233 | ![bug Ok](icons/png/code.png?raw=true "bug OK") | Code 234 | 235 | ## CPU 236 | 237 | Icon: : : | Name 238 | ------------------------------------------------------------ | --------- 239 | ![cpu Ok](icons/png/cpu-ok.png?raw=true "Monit OK") | CPU OK 240 | ![cpu info](icons/png/cpu-info.png?raw=true "Monit INFO") | CPU INFO 241 | ![cpu Warn](icons/png/cpu-warn.png?raw=true "Monit WARN") | CPU WARN 242 | ![cpu Error](icons/png/cpu-error.png?raw=true "Monit ERROR") | CPI ERROR 243 | 244 | ## CRON 245 | 246 | Icon: : | Name 247 | ---------------------------------------------------------- | ---------- 248 | ![Cron Ok](icons/png/cron-ok.png?raw=true "Cron OK") | Cron OK 249 | ![Cron Ok](icons/png/cron-warn.png?raw=true "Cron WARN") | Cron WARN 250 | ![Cron Ok](icons/png/cron-error.png?raw=true "Cron ERROR") | Cron ERROR 251 | 252 | ## DISK 253 | 254 | Icon: : | Name 255 | ----------------------------------------------- | ---- 256 | ![bug Ok](icons/png/disk.png?raw=true "bug OK") | Disk 257 | 258 | ## MEMORY 259 | 260 | Icon: : | Name 261 | ---------------------------------------------------------- | --------- 262 | ![mem Ok](icons/png/mem-ok.png?raw=true "mem OK") | MEM OK 263 | ![mem info](icons/png/mem-info.png?raw=true "mem INFO") | MEM INFO 264 | ![mem Warn](icons/png/mem-warn.png?raw=true "mem WARN") | MEM WARN 265 | ![mem Error](icons/png/mem-error.png?raw=true "mem ERROR") | MEM ERROR 266 | 267 | ## MISC 268 | 269 | Icon: : : | Name 270 | ------------------------------------------------------------------------- | -------------- 271 | ![Database Check](icons/png/database-check.png?raw=true "Database Check") | Database Check 272 | ![Integration](icons/png/integration.png?raw=true "mem INFO") | Integration 273 | ![Stop](icons/png/stop.png?raw=true "Stop"): | Stop 274 | ![Stop 2](icons/png/stop2.png?raw=true "mem ERROR"): | Stop 2 275 | 276 | # Reference 277 | 278 | Hacky Slack was inspired by the following resources: 279 | 280 | - 281 | - 282 | - 283 | - 284 | - 285 | - Icons courtesy of and AWS 286 | 287 | # License 288 | 289 | The MIT License (MIT) Copyright (c) 290 | 291 | 292 | 293 | 294 | 295 | 296 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 297 | 298 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 299 | 300 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 301 | --------------------------------------------------------------------------------