diff --git a/app/assets/javascripts/app/controllers/_integration/slack.coffee b/app/assets/javascripts/app/controllers/_integration/slack.coffee index 8ecfd085d..a579aa548 100644 --- a/app/assets/javascripts/app/controllers/_integration/slack.coffee +++ b/app/assets/javascripts/app/controllers/_integration/slack.coffee @@ -27,7 +27,7 @@ class Index extends App.ControllerIntegrationBase { name: 'webhook', display: 'Webhook', tag: 'input', type: 'url', limit: 200, 'null': false, placeholder: 'https://hooks.slack.com/services/...' }, { name: 'username', display: 'Username', tag: 'input', type: 'text', limit: 100, 'null': false, placeholder: 'username' }, { name: 'channel', display: 'Channel', tag: 'input', type: 'text', limit: 100, 'null': true, placeholder: '#channel' }, - { name: 'icon_url', display: 'Icon Url', tag: 'input', type: 'url', limit: 200, 'null': true, placeholder: 'http://example.com/logo.png' }, + { name: 'icon_url', display: 'Icon Url', tag: 'input', type: 'url', limit: 200, 'null': true, placeholder: 'https://example.com/logo.png' }, ] settings = [] diff --git a/app/models/transaction/slack.rb b/app/models/transaction/slack.rb index 7a6bb9752..7cf0d29fd 100644 --- a/app/models/transaction/slack.rb +++ b/app/models/transaction/slack.rb @@ -46,16 +46,20 @@ backend.perform # get user based notification template # if create, send create message / block update messages template = nil + sent_value = nil if @item[:type] == 'create' template = 'ticket_create' elsif @item[:type] == 'update' template = 'ticket_update' elsif @item[:type] == 'reminder_reached' template = 'ticket_reminder_reached' + sent_value = ticket.pending_time elsif @item[:type] == 'escalation' template = 'ticket_escalation' + sent_value = ticket.escalation_time elsif @item[:type] == 'escalation_warning' template = 'ticket_escalation_warning' + sent_value = ticket.escalation_time else raise "unknown type for notification #{@item[:type]}" end @@ -88,6 +92,24 @@ backend.perform config['items'].each {|item| + # check if reminder_reached/escalation/escalation_warning is already sent today + md5_webhook = Digest::MD5.hexdigest(@item['webhook']) + cache_key = "slack::backend::#{@item[:type]}::#{md5_webhook}" + if sent_value + value = Cache.get(cache_key) + if value == sent_value + Rails.logger.debug "did not send webhook, already sent (#{@item[:type]}/#{ticket.id}/#{@item['webhook']})" + next + end + Cache.write( + cache_key, + sent_value, + { + expires_in: 24.hours + }, + ) + end + # check action if item['types'].class == Array hit = false @@ -119,7 +141,7 @@ backend.perform logo_url = item['logo_url'] end - Rails.logger.debug "sent webhook (#{@item[:type]}/#{ticket.id}/#{item['webhook']})" + Rails.logger.debug "sent webhook (#{@item[:type]}/#{ticket.id}/#{@item['webhook']})" notifier = Slack::Notifier.new( item['webhook'], @@ -142,10 +164,13 @@ backend.perform attachments: [attachment] end if !result.success? - Rails.logger.error "Unable to post webhook: #{item['webhook']}: #{result.inspect}" + if sent_value + Cache.delete(cache_key) + end + Rails.logger.error "Unable to post webhook: #{@item['webhook']}: #{result.inspect}" next end - Rails.logger.debug "sent webhook (#{@item[:type]}/#{ticket.id}/#{item['webhook']})" + Rails.logger.debug "sent webhook (#{@item[:type]}/#{ticket.id}/#{@item['webhook']})" } end diff --git a/test/integration/slack_test.rb b/test/integration/slack_test.rb index ac000bd96..a9fd98ba2 100644 --- a/test/integration/slack_test.rb +++ b/test/integration/slack_test.rb @@ -34,7 +34,7 @@ class SlackTest < ActiveSupport::TestCase items = [ { group_ids: [slack_group.id], - types: %w(create update), + types: %w(create update reminder_reached), webhook: webhook, channel: channel, username: 'zammad bot', @@ -72,7 +72,7 @@ class SlackTest < ActiveSupport::TestCase Delayed::Worker.new.work_off # check if message exists - assert_not(slack_check(channel, hash)) + assert_equal(0, slack_check(channel, hash)) ticket1.state = Ticket::State.find_by(name: 'open') ticket1.save @@ -81,7 +81,7 @@ class SlackTest < ActiveSupport::TestCase Delayed::Worker.new.work_off # check if message exists - assert_not(slack_check(channel, hash)) + assert_equal(0, slack_check(channel, hash)) # case 2 hash = hash_gen @@ -110,7 +110,7 @@ class SlackTest < ActiveSupport::TestCase Delayed::Worker.new.work_off # check if message exists - assert(slack_check(channel, hash)) + assert_equal(1, slack_check(channel, hash)) hash = hash_gen text = "#{rand_word}... #{hash}" @@ -122,7 +122,33 @@ class SlackTest < ActiveSupport::TestCase Delayed::Worker.new.work_off # check if message exists - assert(slack_check(channel, hash)) + assert_equal(1, slack_check(channel, hash)) + + ticket2.state = Ticket::State.find_by(name: 'pending reminder') + ticket2.pending_time = Time.zone.now - 2.days + ticket2.save + + Observer::Transaction.commit + Delayed::Worker.new.work_off + + # check if message exists + assert_equal(2, slack_check(channel, hash)) + + Ticket.process_pending + + Observer::Transaction.commit + Delayed::Worker.new.work_off + + # check if message exists + assert_equal(3, slack_check(channel, hash)) + + Ticket.process_pending + + Observer::Transaction.commit + Delayed::Worker.new.work_off + + # check if message exists + assert_equal(3, slack_check(channel, hash)) items = [ { @@ -165,7 +191,7 @@ class SlackTest < ActiveSupport::TestCase Delayed::Worker.new.work_off # check if message exists - assert_not(slack_check(channel, hash)) + assert_equal(0, slack_check(channel, hash)) ticket3.state = Ticket::State.find_by(name: 'open') ticket3.save @@ -174,7 +200,7 @@ class SlackTest < ActiveSupport::TestCase Delayed::Worker.new.work_off # check if message exists - assert_not(slack_check(channel, hash)) + assert_equal(0, slack_check(channel, hash)) # case 4 hash = hash_gen @@ -203,7 +229,7 @@ class SlackTest < ActiveSupport::TestCase Delayed::Worker.new.work_off # check if message exists - assert(slack_check(channel, hash)) + assert_equal(1, slack_check(channel, hash)) hash = hash_gen text = "#{rand_word}... #{hash}" @@ -215,7 +241,7 @@ class SlackTest < ActiveSupport::TestCase Delayed::Worker.new.work_off # check if message exists - assert_not(slack_check(channel, hash)) + assert_equal(0, slack_check(channel, hash)) end @@ -271,15 +297,15 @@ class SlackTest < ActiveSupport::TestCase if !channel_history['messages'] raise "ERROR: No history messages for channel #{channel_name}/#{channel_id}" end + message_count = 0 channel_history['messages'].each {|message| next if !message['text'] if message['text'] =~ /#{search_for}/i - p "SUCCESS: message with #{search_for} found!" - return true + message_count += 1 + p "SUCCESS: message with #{search_for} found #{message_count} time(s)!" end } - #raise "ERROR: No such message containing #{search_for} in history of channel #{channel_name}/#{channel_id}" - false + message_count end end