3 # Discord hook using discord's 'slack compatible' endpoint
5 # Based on: https://github.com/joemiller/git-hooks Campfire notification post-receive hook. Author: Joe Miller
6 # (http://joemiller.me)
8 # Based on post-receive.irc by Mikael Fridh <frimik@gmail.com> https://gist.github.com/1821358
11 function help_discord () {
12 echo "Required config settings:"
13 echo " git config hooks.discord.webhook-url 'https://discord.com/api/webhooks/...'"
14 echo " git config hooks.discord.show-only-last-commit 'true' #optional"
15 echo " git config hooks.discord.username 'git' #optional"
16 echo " git config hooks.discord.repo-nice-name 'MyRepo' #optional"
18 echo " The webhook url shoud be that returned by the create step - the notifier"
19 echo " will add the required parameters to hit the slack-compatible endpoint"
23 function notify_discord() {
24 oldrev=$(git rev-parse $1)
25 newrev=$(git rev-parse $2)
32 if expr "$oldrev" : '0*$' >/dev/null
36 if expr "$newrev" : '0*$' >/dev/null
44 # --- Get the revision types
45 newrev_type=$(git cat-file -t $newrev 2> /dev/null)
46 oldrev_type=$(git cat-file -t "$oldrev" 2> /dev/null)
47 case "$change_type" in
50 rev_type="$newrev_type"
54 rev_type="$oldrev_type"
58 # The revision type tells us what type the commit is, combined with
59 # the location of the ref we can decide between
64 case "$refname","$rev_type" in
68 short_refname=${refname##refs/tags/}
72 refname_type="annotated tag"
73 short_refname=${refname##refs/tags/}
75 if [ -n "$announcerecipients" ]; then
76 recipients="$announcerecipients"
82 short_refname=${refname##refs/heads/}
84 refs/remotes/*,commit)
86 refname_type="tracking branch"
87 short_refname=${refname##refs/remotes/}
88 echo >&2 "*** Push-update of tracking branch, $refname"
89 echo >&2 "*** - no notification generated."
93 # Anything else (is there anything else?)
94 echo >&2 "*** Unknown type of update to $refname ($rev_type)"
95 echo >&2 "*** - no notification generated"
99 # plural suffix, default "", changed to "s" if commits > 1
102 # Repo name, either Gitolite or normal repo.
103 if [ -n "$GL_REPO" ]; then
104 # it's a gitolite repo
105 repodir=$(basename `pwd`)
108 repodir=$(basename `pwd`)
109 if [ "$repodir" == ".git" ]; then
110 repodir=`dirname $PWD`
111 repodir=`basename $repodir`
116 repoprefix=$(git config hooks.discord.repo-nice-name || git config hooks.irc.prefix || git config hooks.emailprefix || echo "$repo")
117 onlylast=`git config --get hooks.discord.show-only-last-commit`
118 onlylast=$onlylast && [ -n "$onlylast" ]
120 # Get the user information
121 # If $GL_USER is set we're running under gitolite.
122 if [ -n "$GL_USER" ]; then
128 case ${change_type} in
130 header="New ${refname_type} *${short_refname}* has been created in ${repoprefix}"
131 single_commit_suffix="commit"
134 header="$(tr '[:lower:]' '[:upper:]' <<< ${refname_type:0:1})${refname_type:1} *$short_refname* has been deleted from ${repoprefix}"
135 single_commit_suffix="commit"
138 num=$(git log --pretty=oneline ${1}..${2}|wc -l|tr -d ' ')
139 branch=${3/refs\/heads\//}
141 if [ ${num} -gt 1 ]; then
142 header="${num} new commits *pushed* to *${short_refname}* in ${repoprefix}"
143 single_commit_suffix="one"
146 header="A new commit has been *pushed* to *${short_refname}* in ${repoprefix}"
147 single_commit_suffix="one"
152 # most weird ... this should never happen
153 echo >&2 "*** Unknown type of update to $refname ($rev_type)"
154 echo >&2 "*** - notifications will probably screw up."
157 if $onlylast && [[ "${change_type}" != "delete" ]]; then
158 header="$header, showing last $single_commit_suffix:"
162 if [[ "${change_type}" != "delete" && "${refname_type}" == "branch" ]]; then
163 reporoot=`git config --get hooks.discord.repos-root`
168 if [ -n "$urlformat" ]; then
169 formattedurl="<${urlformat}|%h> "
175 if [[ "${change_type}" == "update" ]]; then
183 # merge `git log` output with $header
190 # Process the log and escape double quotes; assuming for now that committer names don't have five semicolons in them
191 log_out=$( git log --pretty=format:"%cN;;;;;${formattedurl}%s" $countarg ${start}..${end} \
192 | sed -e 's/\\/\\\\/g' \
193 | sed -e 's/"/\\"/g' \
194 | sed -e 's/\(.*\);;;;;\(.*\)/{"title":"\1","value":"\2","short":false},/' )
198 attachments="[{ \"fallback\" : \"${header}\", \"color\" : \"good\", \"fields\" : [${fields}]}]"
201 if [ -n "${attachments}" ] && [[ "${attachments}" != "" ]]; then
202 msg=$(echo -e "\"text\":\"${header}\", \"attachments\" : $attachments")
204 msg=$(echo -e "\"text\":\"${header}\"")
207 # slack API uses \n substitution for newlines
208 # msg=$(echo "${msg}" | perl -p -e 's/\+/+/mg')
210 webhook_url=$(git config --get hooks.discord.webhook-url)
211 username=$(git config --get hooks.discord.username)
213 if [ -z "$webhook_url" ]; then
214 echo "ERROR: config settings not found"
219 webhook_url="$webook_url/slack"
223 if [ -n "$username" ]; then
224 payload="$payload, \"username\": \"$username\""
229 if [ -n "$DEBUG" ]; then
230 echo "POST $webhook_url"
231 echo "payload=$payload"
236 -d "payload=$payload" \