summaryrefslogtreecommitdiffstats
path: root/bin/email2irc.sh
blob: d0fbe2ed7e16561517d3d218e52001849f3aeb24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/bash

# Copyright 2012-2017 Holger Levsen <holger@layer-acht.org>
# released under the GPLv=2

# from IRC:
#<h01ger> i think email2irc.sh should be thrown away and replaced
#	  with a proper python or perl script. parsing email headers
#	  with shell is insane.
#<h01ger> but it really should just be rewritten from scratch
#<h01ger> using something which has libraries to parse emails…


#
# called by ~jenkins/.procmailrc
# to turn jenkins email notifications into irc announcements with kgb
# see http://kgb.alioth.debian.org/
#
LOGFILE=/var/log/jenkins/email.log

debug123() {
	if $DEBUG ; then
		echo "Debug: $1 $2 $3" >> $LOGFILE
	fi
}

#
# parse email headers to check if they come from jenkins
#
DEBUG=false
HEADER=true
VALID_MAIL=false
MY_LINE=""
MY_2ND_LINE=""
while read -r line ; do
	if [ "$HEADER" = "true" ] ; then
		# check if email header ends
		if [[ $line =~ ^$ ]] ; then
			HEADER=false
		fi
		# valid From: line?
		if [[ $line =~ ^(From: jenkins@jenkins.debian.net) ]] ; then
			VALID_MAIL=true
		fi
		# catch Subject (to send to IRC later)
		if [[ $line =~ ^(Subject: .*) ]] ; then
			SUBJECT=${line:9}
			# the email-ext plugin sometimes sends multi line subjects..
			read -r NEXT
			if [ "${NEXT:0:1}" = " " ] || [ "${NEXT:0:1}" = $'\t' ]; then
				SUBJECT="${SUBJECT}${NEXT:1}"
			fi
		fi
		# determine the channel to send notifications to
		# by parsing the To: line
		if [[ $line =~ ^(To: .*) ]] ; then
			echo $line >> $LOGFILE
			CHANNEL=$(echo $line | cut -d "+" -f2| cut -d "@" -f1)
			echo "CHANNEL = $CHANNEL" >> $LOGFILE
		fi
		# check if it's a valid jenkins job
		if [[ $line =~ ^(X-Jenkins-Job: .*) ]] ; then
			JENKINS_JOB=${line:15}
		fi
	fi
	# catch first line of email body (to send to IRC later)
	if [ "$HEADER" = "false" ] && [ -z "$MY_LINE" ] ; then
		MY_LINE=$line
		debug123 "#1" MY_LINE $MY_LINE
		if [ -z "$MY_2ND_LINE" ] ; then
			# if this is a multipart email it comes from the email extension plugin
			if [ "${line:0:7}" = "------=" ] || [ "${line:0:9}" = "Content-T" ] ; then
				debug123 "#2" line $line
				MY_LINE=""
			else
				debug123 "#3" line $line
				MY_LINE=$(echo $line | tr -d \< | tr -d \> | cut -d " " -f1-2)
				debug123 "#4" MY_LINE $MY_LINE
			fi
			# deal with quoted-printable continuation lines: 1st line/time
			# if $MY_LINE ends with '=', then append the next line to $MY_LINE,
			# changing the '=' to a single space.
			if [[ $MY_LINE =~ ^(.*)=$ ]] ; then
				MY_2ND_LINE="$MY_LINE"
				MY_LINE=""
			fi
		else
			# deal with quoted-printable continuation lines: 2nd line/time
			# if $MY_LINE ends with '=', then append the next line to $MY_LINE,
			# changing the '=' to a single space.
			MY_2ND_LINE=$(echo $MY_2ND_LINE | sed -s 's#=$##')
			MY_LINE="${MY_2ND_LINE}$MY_LINE"
			debug123 "#5" MY_LINE $MY_LINE
			debug123 "#6" MY_2ND_LINE $MY_2ND_LINE
		fi
	fi
done
# check that it's a valid job
if [ -z $JENKINS_JOB ] ; then
	VALID_MAIL=false
fi	
debug123 "#7" MY_LINE $MY_LINE
# remove bogus noise
MY_LINE=$(echo $MY_LINE | sed -s "s#------------------------------------------##g")
debug123 "#8" MY_LINE $MY_LINE

# only send notifications for valid emails
if [ "$VALID_MAIL" = "true" ] ; then
	echo -e "----------\nvalid email\n-----------" >> $LOGFILE
	date >> $LOGFILE
	echo "Job:     $JENKINS_JOB" >> $LOGFILE
	echo "Subject: $SUBJECT" >> $LOGFILE
	echo "My line: $MY_LINE" >> $LOGFILE
	# only notify if there is a channel to notify
	if [ ! -z $CHANNEL ] ; then
		# format message
		MESSAGE="$(echo $SUBJECT | cut -d ':' -f1) $MY_LINE"
		MESSAGE="$(echo $MESSAGE | sed -s 's#^Failure#Failed #') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#^Build failed in Jenkins#Failed #') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#^Jenkins build is back to normal#Fixed #') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#^Jenkins build is back to stable#Fixed #') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#^Jenkins build became#Became#') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#^Jenkins build is unstable#Unstable#') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#^Jenkins build is still unstable#Still unstable#') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#^Still Failing#Still failing#') "
		MESSAGE="$(echo $MESSAGE | sed -s 's# See # #') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#Changes:##') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#\?page=changes$##') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#/console$##') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#/changes$##') "
		MESSAGE="$(echo $MESSAGE | sed -s 's#display/redirec.*\>$##') "
		# log message
		echo "Notified #$CHANNEL with $MESSAGE" >> $LOGFILE
		# notify kgb
		kgb-client --conf /srv/jenkins/kgb/$CHANNEL.conf --relay-msg "$MESSAGE" && echo "kgb informed successfully." >> $LOGFILE
		echo >> $LOGFILE
	else
		echo "But no irc channel detected." >> $LOGFILE
	fi
else
	echo -e "----------\nbad luck\n-----------" >> $LOGFILE
fi