6
6
"github.com/emersion/go-imap"
7
7
"github.com/emersion/go-imap/client"
8
8
"github.com/emersion/go-message/mail"
9
- strip "github.com/grokify/html-strip-tags-go"
10
9
"github.com/microcosm-cc/bluemonday"
11
10
"github.com/robfig/cron/v3"
12
11
"io"
@@ -15,6 +14,7 @@ import (
15
14
"net/http"
16
15
"os"
17
16
"os/signal"
17
+ "regexp"
18
18
"strings"
19
19
)
20
20
@@ -31,6 +31,76 @@ func main() {
31
31
32
32
}
33
33
34
+ func printErrorFromApi (resp * http.Response ) {
35
+ bodyBytes , err := ioutil .ReadAll (resp .Body )
36
+ if err != nil {
37
+ log .Fatal (err )
38
+ }
39
+ bodyString := string (bodyBytes )
40
+ err = errors .New (bodyString )
41
+ log .Print (err )
42
+ }
43
+
44
+ func getMailBody (p * mail.Part ) string {
45
+ sanitizePolicy := bluemonday .UGCPolicy ()
46
+ body , _ := ioutil .ReadAll (p .Body )
47
+ plainTextBody := strings .Replace (string (body ), "\n " , "\\ n" , - 1 )
48
+ plainTextBody = strings .Replace (plainTextBody , "\r " , "\\ r" , - 1 )
49
+ return sanitizePolicy .Sanitize (plainTextBody )
50
+ }
51
+
52
+ func makePostRequest (endpoint string , body string ) * http.Response {
53
+ jiraUrl := os .Getenv ("JIRA_URL" )
54
+ jiraUser := os .Getenv ("JIRA_USER" )
55
+ jiraPassword := os .Getenv ("JIRA_PASSWORD" )
56
+
57
+ clt := & http.Client {}
58
+ req , err := http .NewRequest ("POST" , jiraUrl + endpoint , strings .NewReader (body ))
59
+ req .Header .Add ("Content-Type" , "application/json" )
60
+ req .Header .Add ("Authorization" , "Basic " + base64 .StdEncoding .EncodeToString ([]byte (jiraUser + ":" + jiraPassword )))
61
+ resp , err := clt .Do (req )
62
+ if err != nil {
63
+ log .Fatal (err )
64
+ }
65
+ defer resp .Body .Close ()
66
+
67
+ return resp
68
+ }
69
+
70
+ func makeGetRequest (endpoint string ) * http.Response {
71
+ jiraUrl := os .Getenv ("JIRA_URL" )
72
+ jiraUser := os .Getenv ("JIRA_USER" )
73
+ jiraPassword := os .Getenv ("JIRA_PASSWORD" )
74
+
75
+ clt := & http.Client {}
76
+ req , err := http .NewRequest ("GET" , jiraUrl + endpoint , strings .NewReader ("" ))
77
+ req .Header .Add ("Content-Type" , "application/json" )
78
+ req .Header .Add ("Authorization" , "Basic " + base64 .StdEncoding .EncodeToString ([]byte (jiraUser + ":" + jiraPassword )))
79
+ resp , err := clt .Do (req )
80
+ if err != nil {
81
+ log .Fatal (err )
82
+ }
83
+ defer resp .Body .Close ()
84
+
85
+ return resp
86
+ }
87
+
88
+ func setMailAsUnseen (c * client.Client , currentMail uint32 ) {
89
+ seqSet := new (imap.SeqSet )
90
+ seqSet .AddRange (currentMail , currentMail )
91
+
92
+ if err := c .Store (seqSet , imap .RemoveFlags , []interface {}{imap .SeenFlag }, nil ); err != nil {
93
+ log .Println ("IMAP Message Flag Update Failed" )
94
+ log .Println (err )
95
+ os .Exit (1 )
96
+ }
97
+
98
+ if err := c .Expunge (nil ); err != nil {
99
+ log .Println ("IMAP Message mark as unseen Failed" )
100
+ os .Exit (1 )
101
+ }
102
+ }
103
+
34
104
func run () {
35
105
36
106
// ============================================================
@@ -42,10 +112,6 @@ func run() {
42
112
imapUser := os .Getenv ("IMAP_USER" )
43
113
imapPassword := os .Getenv ("IMAP_PASSWORD" )
44
114
45
- jiraUrl := os .Getenv ("JIRA_URL" )
46
- jiraUser := os .Getenv ("JIRA_USER" )
47
- jiraPassword := os .Getenv ("JIRA_PASSWORD" )
48
-
49
115
// Connect to server
50
116
c , err := client .DialTLS (imapServer + ":" + imapServerPort , nil )
51
117
if err != nil {
@@ -63,7 +129,7 @@ func run() {
63
129
log .Println ("Logged in" )
64
130
65
131
// Select INBOX
66
- mbox , err : = c .Select ("INBOX" , false )
132
+ _ , err = c .Select ("INBOX" , false )
67
133
if err != nil {
68
134
log .Fatal (err )
69
135
}
@@ -81,19 +147,34 @@ func run() {
81
147
82
148
var section imap.BodySectionName
83
149
items := []imap.FetchItem {section .FetchItem (), imap .FetchEnvelope }
84
- sanitizePolicy := bluemonday .UGCPolicy ()
85
150
86
- messages := make (chan * imap.Message , 1 )
87
- _ = c .Fetch (messageSet , items , messages )
151
+ messages := make (chan * imap.Message , len (uids ))
152
+ err = c .Fetch (messageSet , items , messages )
153
+
154
+ currentMessage := - 1
88
155
89
156
for message := range messages {
157
+ currentMessage = currentMessage + 1
158
+ currentUid := uids [currentMessage ]
159
+
90
160
r := message .GetBody (& section )
161
+ subject := message .Envelope .Subject
162
+
163
+ isMessageWithIssueNumber , _ := regexp .MatchString ("^.*\\ [.*-\\ d+]$" , subject )
91
164
92
165
mr , err := mail .CreateReader (r )
93
166
if err != nil {
94
167
log .Fatal (err )
95
168
}
96
169
170
+ header := mr .Header
171
+ senderArray , err := header .AddressList ("From" )
172
+ if err != nil {
173
+ log .Fatal (err )
174
+ }
175
+
176
+ sender := senderArray [0 ]
177
+
97
178
for {
98
179
p , err := mr .NextPart ()
99
180
if err == io .EOF {
@@ -104,61 +185,55 @@ func run() {
104
185
105
186
switch p .Header .(type ) {
106
187
case * mail.InlineHeader :
107
- // This is the message's text (can be plain-text or HTML)
108
- body , _ := ioutil .ReadAll (p .Body )
109
- plainTextBody := strip .StripTags (string (body ))
110
- plainTextBody = strings .Replace (plainTextBody , "\n " , "\\ n" , - 1 )
111
- plainTextBody = strings .Replace (plainTextBody , "\r " , "\\ r" , - 1 )
112
- sanitizedBody := sanitizePolicy .Sanitize (plainTextBody )
113
-
114
- content , err := ioutil .ReadFile ("structure.json" )
115
- if err != nil {
116
- log .Fatal (err )
117
- }
118
-
119
- // Convert []byte to string and print to screen
120
- jsonString := string (content )
121
- jsonString = strings .Replace (jsonString , "%SUMMARY%" , message .Envelope .Subject , 1 )
122
- jsonString = strings .Replace (jsonString , "%DESCRIPTION%" , strings .TrimSpace (sanitizedBody ), 1 )
123
-
124
- log .Println (jsonString )
125
-
126
- clt := & http.Client {}
127
-
128
- req , err := http .NewRequest ("POST" , jiraUrl + "/rest/api/latest/issue" , strings .NewReader (jsonString ))
129
- req .Header .Add ("Content-Type" , "application/json" )
130
- req .Header .Add ("Authorization" , "Basic " + base64 .StdEncoding .EncodeToString ([]byte (jiraUser + ":" + jiraPassword )))
131
- resp , err := clt .Do (req )
132
- if err != nil {
133
- log .Fatal (err )
134
- }
135
- defer resp .Body .Close ()
188
+ sanitizedBody := getMailBody (p )
136
189
137
- if resp . StatusCode != 201 {
138
- bodyBytes , err := ioutil .ReadAll ( resp . Body )
190
+ if isMessageWithIssueNumber {
191
+ content , err := ioutil .ReadFile ( "structure_add_comment.json" )
139
192
if err != nil {
140
193
log .Fatal (err )
141
194
}
142
- bodyString := string (bodyBytes )
143
- err = errors .New (bodyString )
144
- log .Print (err )
145
- } else {
146
- delSeqset := new (imap.SeqSet )
147
- delSeqset .AddRange (mbox .Messages , mbox .Messages )
148
-
149
- flags := []interface {}{imap .SeenFlag }
150
- if err := c .Store (delSeqset , imap .FormatFlagsOp (imap .AddFlags , true ), flags , nil ); err != nil {
151
- log .Println ("IMAP Message Flag Update Failed" )
152
- log .Println (err )
153
- os .Exit (1 )
195
+ // Convert []byte to string and print to screen
196
+ jsonString := string (content )
197
+ jsonString = strings .Replace (jsonString , "%SUMMARY%" , subject + " (" + sender .Name + " <" + sender .Address + ">)" , 1 )
198
+ jsonString = strings .Replace (jsonString , "%DESCRIPTION%" , strings .TrimSpace (sanitizedBody ), 1 )
199
+
200
+ issueNumber := subject [strings .LastIndex (subject , "[" )+ 1 : strings .LastIndex (subject , "]" )]
201
+
202
+ resp := makeGetRequest ("/rest/api/3/issue/" + issueNumber )
203
+
204
+ if resp .StatusCode != 200 {
205
+ setMailAsUnseen (c , currentUid )
206
+ printErrorFromApi (resp )
207
+ } else {
208
+ resp := makePostRequest ("/rest/api/3/issue/" + issueNumber + "/comment" , jsonString )
209
+
210
+ if resp .StatusCode != 201 {
211
+ setMailAsUnseen (c , currentUid )
212
+ printErrorFromApi (resp )
213
+ } else {
214
+ log .Println ("Success add comment" )
215
+ }
154
216
}
155
217
156
- if err := c .Expunge (nil ); err != nil {
157
- log .Println ("IMAP Message mark as Seen Failed" )
158
- os .Exit (1 )
218
+ } else {
219
+ content , err := ioutil .ReadFile ("structure_new_issue.json" )
220
+ if err != nil {
221
+ log .Fatal (err )
159
222
}
160
223
161
- log .Println ("Success" )
224
+ // Convert []byte to string and print to screen
225
+ jsonString := string (content )
226
+ jsonString = strings .Replace (jsonString , "%SUMMARY%" , subject , 1 )
227
+ jsonString = strings .Replace (jsonString , "%DESCRIPTION%" , strings .TrimSpace (sanitizedBody ), 1 )
228
+
229
+ resp := makePostRequest ("/rest/api/3/issue" , jsonString )
230
+
231
+ if resp .StatusCode != 201 {
232
+ setMailAsUnseen (c , currentUid )
233
+ printErrorFromApi (resp )
234
+ } else {
235
+ log .Println ("Success add issue" )
236
+ }
162
237
}
163
238
}
164
239
break
0 commit comments