/
process.go
213 lines (185 loc) · 6.28 KB
/
process.go
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
package main
import (
"fmt"
"strings"
"time"
sl "github.com/nlopes/slack"
plugins "github.com/tylerconlee/slab/_plugins"
"github.com/tylerconlee/slab/config"
"github.com/tylerconlee/slab/datastore"
"github.com/tylerconlee/slab/slack"
"github.com/tylerconlee/slab/zendesk"
)
// RunTimer takes the interval from the config, and at each loop iteration,
// grabs the latest tickets, checks for upcoming SLAs and send notifications if
// appropriate
func RunTimer(interval time.Duration) {
log.Info("Starting timer", map[string]interface{}{
"module": "main",
"interval": interval,
})
t := time.NewTicker(interval)
for {
iteration(t, interval)
<-t.C
}
}
func iteration(t *time.Ticker, interval time.Duration) {
// reload the config on each pass to allow for changes to the config to
// be recognized
// TODO: Update this to only update when the file is modified, rather
// than every pass
c := config.LoadConfig()
p := plugins.LoadPlugins()
if c.Slack.ChannelID != "" {
/*channel := slack.GetChannel(c.Slack.ChannelID)
if channel == 0 {
slack.AddChannel(c.Slack.ChannelID, 2)
}*/
log.Info("Loaded plugins.", map[string]interface{}{
"module": "main",
"plugins": p,
})
if c.Zendesk.URL != "" && c.Zendesk.APIKey != "" {
tick := zendesk.GetAllTickets()
// Grab tags
tags := datastore.LoadTags()
log.Info("Grabbed and parsed tickets from Zendesk", map[string]interface{}{
"module": "main",
})
log.Info("Checking ticket notifications...", map[string]interface{}{
"module": "main",
})
processSLAAlerts(tick, tags, p)
processUpdateAlerts(tick, tags, p, interval)
processNewAlerts(tick, tags, p, interval)
slack.Sent = zendesk.Sent
slack.NumTickets = zendesk.NumTickets
slack.LastProcessed = zendesk.LastProcessed
log.Info("Ticket notifications sent. Returning to idle state.", map[string]interface{}{
"module": "main",
})
} else {
log.Info("Zendesk authorization required. Please run @slab start config to begin.", map[string]interface{}{
"module": "main",
})
}
<-t.C
}
}
func getOrgName(id int) (o string) {
org := zendesk.GetOrganization(id)
if len(org) > 0 {
orglink := fmt.Sprintf("%s/agent/organizations/%d", c.Zendesk.URL, org[0].ID)
o = "<" + orglink + "| " + org[0].Name + "> "
}
return o
}
func contains(a []string, x string) bool {
for _, n := range a {
if x == n {
return true
}
}
return false
}
func processSLAAlerts(tick zendesk.ZenOutput, tags []map[string]interface{}, p plugins.Plugins) {
// Returns a list of all upcoming SLA breaches
active := zendesk.CheckSLA(tick)
// Loop through all active SLA tickets and prepare SLA notification
// for each.
for _, ticket := range active {
// Loop through all available tags
for _, tag := range tags {
if contains(ticket.Tags, tag["tag"].(string)) && tag["notify_type"].(string) == "sla" {
if ticket.Priority != nil {
send, notify := zendesk.UpdateCache(ticket, tag["channel"].(string))
if send {
log.Info("Preparing SLA notification for ticket", map[string]interface{}{
"module": "main",
"ticket": ticket.ID,
"channel": tag["channel"].(string),
})
m := slack.Ticket(ticket)
n, c := slack.PrepSLANotification(m, notify, tag["tag"].(string), tag["group"].(string))
p.SendDispatcher(n)
user := zendesk.GetTicketRequester(int(ticket.Requester))
org := getOrgName(ticket.ID)
attach := slack.SLAMessage(m, c, user.Name, user.ID, org)
attachments := []sl.Attachment{attach}
if strings.HasPrefix(tag["channel"].(string), "U") {
slack.SendDirectMessage(n, attachments, tag["channel"].(string))
} else {
slack.SendMessage(n, tag["channel"].(string), attachments)
}
}
}
}
}
}
}
func processUpdateAlerts(tick zendesk.ZenOutput, tags []map[string]interface{}, p plugins.Plugins, interval time.Duration) {
updated := zendesk.CheckUpdatedTicket(interval)
for _, ticket := range updated {
for _, tag := range tags {
if contains(ticket.Tags, tag["tag"].(string)) && tag["notify_type"].(string) == "updates" {
log.Info("Preparing update notification for ticket", map[string]interface{}{
"module": "main",
"ticket": ticket.ID,
})
n := fmt.Sprintf("Ticket #%d updated. Priority: %s, Tag: %s", ticket.ID, ticket.Priority, tag["tag"])
m := slack.Ticket(ticket)
user := zendesk.GetTicketRequester(int(ticket.Requester))
p.SendDispatcher(n)
attach := slack.UpdateMessage(m, user.Name, user.ID)
attachments := []sl.Attachment{attach}
if strings.HasPrefix(tag["channel"].(string), "U") {
slack.SendDirectMessage(n, attachments, tag["channel"].(string))
} else {
slack.SendMessage(n, tag["channel"].(string), attachments)
}
}
}
}
}
func processNewAlerts(tick zendesk.ZenOutput, tags []map[string]interface{}, p plugins.Plugins, interval time.Duration) {
// Returns a list of all new tickets within the last loop
new := zendesk.CheckNewTicket(tick, interval)
log.Debug("New tickets processed", map[string]interface{}{
"module": "main",
"new_tickets": new,
})
if new != nil {
var newTickets []slack.Ticket
// Loop through all tickets and add to Slack package friendly slice
for _, ticket := range new {
for _, tag := range tags {
if contains(ticket.Tags, tag["tag"].(string)) && tag["notify_type"].(string) == "new" {
m := slack.Ticket(ticket)
log.Info("Adding new ticket to notification", map[string]interface{}{
"module": "main",
"ticket": m.ID,
})
log.Debug("Ticket information", map[string]interface{}{
"module": "main",
"ticket": m,
})
newTickets = append(newTickets, m)
attachments, message := slack.NewTicketMessage(newTickets, tag["tag"].(string))
if strings.HasPrefix(tag["channel"].(string), "U") {
slack.SendDirectMessage(message, attachments, tag["channel"].(string))
} else {
if tag["channel"].(string) == c.Slack.ChannelID {
if slack.Triager != "None" {
message = fmt.Sprintf("<@%s> The following tickets were received since the last loop:", slack.Triager)
} else {
message = fmt.Sprintf("The following tickets were received since the last loop:")
}
}
slack.SendMessage(message, tag["channel"].(string), attachments)
}
}
}
}
}
}