@@ -64,6 +64,8 @@ type Organization struct {
6464 Name string `json:"name"`
6565}
6666
67+ var lastPollTime = time .Now ().Add (- 5 * time .Minute ) // Start 5 minutes before now
68+
6769// NewZendeskClient initializes a new ZendeskClient using configuration from the database.
6870func NewZendeskClient (db db.Database ) (* ZendeskClient , error ) {
6971 subdomain , err := models .GetConfiguration (db , "zendesk_subdomain" )
@@ -97,7 +99,7 @@ func NewZendeskClient(db db.Database) (*ZendeskClient, error) {
9799
98100// StartZendeskPolling handles periodic polling of tickets from Zendesk.
99101func StartZendeskPolling (ctx context.Context , db db.Database , sseServer * middlewares.SSEServer , slackService * SlackService ) {
100- var lastPollTime = time . Now (). Add ( - 5 * time . Minute ) // Start 5 minutes before now
102+
101103 broadcastStatusUpdates (sseServer , "zendesk" , "connected" , "" )
102104
103105 for {
@@ -133,15 +135,15 @@ func StartZendeskPolling(ctx context.Context, db db.Database, sseServer *middlew
133135 if len (allTickets ) == 0 {
134136 log .Println ("No tickets to process" )
135137 } else {
136- processTickets (ctx , db , allTickets , slaData , sseServer , slackService )
138+ processTickets (ctx , db , allTickets , slaData , sseServer , slackService , zendeskClient )
137139 }
138140
139141 lastPollTime = time .Now ()
140142 time .Sleep (5 * time .Minute )
141143 }
142144}
143145
144- func processTickets (ctx context.Context , db db.Database , tickets []zendesk.Ticket , slaData map [int64 ]SLAInfo , sseServer * middlewares.SSEServer , slackService * SlackService ) {
146+ func processTickets (ctx context.Context , db db.Database , tickets []zendesk.Ticket , slaData map [int64 ]SLAInfo , sseServer * middlewares.SSEServer , slackService * SlackService , zc * ZendeskClient ) {
145147
146148 userAlerts , err := models .GetAllTagAlerts (db )
147149 log .Printf ("Processing %d tickets...\n " , len (tickets ))
@@ -163,7 +165,18 @@ func processTickets(ctx context.Context, db db.Database, tickets []zendesk.Ticke
163165 case AlertTypeNewTicket :
164166 sendAlert = isNewTicket (ticket )
165167 case AlertTypeTicketUpdate :
166- sendAlert = isUpdatedTicket (ticket )
168+ if isUpdatedTicket (ticket ) {
169+ lastPublicCommentTime , err := zc .GetLastPublicCommentTime (ticket .ID )
170+ if err != nil {
171+ log .Printf ("Skipping ticket %d: %v" , ticket .ID , err )
172+ continue
173+ }
174+
175+ if lastPublicCommentTime .After (lastPollTime ) {
176+ sendAlert = true
177+ }
178+ }
179+
167180 case AlertTypeSLABreach :
168181
169182 if slaInfo , ok := slaData [ticket .ID ]; ok {
@@ -335,6 +348,44 @@ func (zc *ZendeskClient) GetOrganizationByID(organizationID int64) (*Organizatio
335348 return & result .Organization , nil
336349}
337350
351+ // GetLastPublicCommentTime retrieves the timestamp of the last public comment on a ticket.
352+ // GetLastPublicCommentTime retrieves the timestamp of the last public comment on a ticket.
353+ func (zc * ZendeskClient ) GetLastPublicCommentTime (ticketID int64 ) (time.Time , error ) {
354+ var lastPublicCommentTime time.Time
355+ ops := zendesk .NewPaginationOptions ()
356+ ops .PageSize = 10
357+ ops .Id = ticketID
358+ it := zc .client .GetTicketCommentsIterator (context .Background (), ops )
359+
360+ for it .HasMore () {
361+ comments , err := it .GetNext ()
362+ if err != nil {
363+ return time.Time {}, fmt .Errorf ("failed to retrieve comments for ticket %d: %v" , ticketID , err )
364+ }
365+
366+ // Ensure we have comments before accessing the last element
367+ if len (comments ) == 0 {
368+ continue
369+ }
370+
371+ lastComment := comments [len (comments )- 1 ] // Get the last comment
372+
373+ // Check if the comment is public by safely dereferencing the *bool
374+ if lastComment .Public != nil && * lastComment .Public {
375+ commentTime := lastComment .CreatedAt
376+ if commentTime .After (lastPublicCommentTime ) {
377+ lastPublicCommentTime = commentTime
378+ }
379+ }
380+ }
381+
382+ if lastPublicCommentTime .IsZero () {
383+ return time.Time {}, fmt .Errorf ("no public comments found for ticket %d" , ticketID )
384+ }
385+
386+ return lastPublicCommentTime , nil
387+ }
388+
338389func getSLALabel (ticket zendesk.Ticket , slaData map [int64 ]SLAInfo ) string {
339390 slaInfo , exists := slaData [ticket .ID ]
340391 if ! exists || len (slaInfo .PolicyMetrics ) == 0 {
0 commit comments