Skip to content

Commit

Permalink
Notify agent if mail delivery failed. Enhancement to issue #1198.
Browse files Browse the repository at this point in the history
  • Loading branch information
martini committed Jul 26, 2017
1 parent 78a8e90 commit 4ba2744
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 26 deletions.
6 changes: 0 additions & 6 deletions app/models/channel.rb
Expand Up @@ -223,12 +223,6 @@ def self.stream

def deliver(mail_params, notification = false)

# ignore notifications in developer mode
if notification == true && Setting.get('developer_mode') == true
logger.info "Do not send notification #{mail_params.inspect} because of enabled developer_mode"
return
end

adapter = options[:adapter]
adapter_options = options
if options[:outbound] && options[:outbound][:adapter]
Expand Down
Expand Up @@ -124,7 +124,7 @@ def log_error(local_record, message, channel = nil)
local_record.preferences['delivery_status'] = 'fail'
local_record.preferences['delivery_status_message'] = message
local_record.preferences['delivery_status_date'] = Time.zone.now
local_record.save
local_record.save!
Rails.logger.error message

if local_record.preferences['delivery_retry'] > 3
Expand All @@ -141,7 +141,10 @@ def log_error(local_record, message, channel = nil)
recipient_list += local_record[key]
}

Ticket::Article.create(
# reopen ticket and notify agent
Observer::Transaction.reset
UserInfo.current_user_id = 1
Ticket::Article.create!(
ticket_id: local_record.ticket_id,
content_type: 'text/plain',
body: "Unable to send email to '#{recipient_list}': #{message}",
Expand All @@ -151,14 +154,14 @@ def log_error(local_record, message, channel = nil)
preferences: {
delivery_article_id_related: local_record.id,
delivery_message: true,
notification: true,
},
updated_by_id: 1,
created_by_id: 1,
)

ticket = Ticket.find(local_record.ticket_id)
ticket.state = Ticket::State.find_by(default_follow_up: true)
ticket.save!
Observer::Transaction.commit
UserInfo.current_user_id = nil
end

raise message
Expand All @@ -170,7 +173,7 @@ def max_attempts

def reschedule_at(current_time, attempts)
if Rails.env.production?
return current_time + attempts * 20.seconds
return current_time + attempts * 25.seconds
end
current_time + 5.seconds
end
Expand Down
7 changes: 3 additions & 4 deletions app/models/observer/ticket/online_notification_seen.rb
Expand Up @@ -16,12 +16,11 @@ def after_update(record)
def _check(record)

# return if we run import mode
return if Setting.get('import_mode')
return false if Setting.get('import_mode')

# set seen only if state has changes
return if !record.changes
return if record.changes.empty?
return if !record.changes['state_id']
return false if record.changes.blank?
return false if record.changes['state_id'].blank?

# check if existing online notifications for this ticket should be set to seen
return true if !record.online_notification_seen_state
Expand Down
Expand Up @@ -16,7 +16,7 @@ def perform
next if seen == notification.seen
notification.seen = true
notification.updated_by_id = @user_id
notification.save
notification.save!
}
end
end
Expand Down
4 changes: 4 additions & 0 deletions app/models/observer/transaction.rb
Expand Up @@ -3,6 +3,10 @@
class Observer::Transaction < ActiveRecord::Observer
observe :ticket, 'ticket::_article', :user, :organization, :tag

def self.reset
EventBuffer.reset('transaction')
end

def self.commit(params = {})

# add attribute of interface handle (e. g. to send (no) notifications if a agent
Expand Down
2 changes: 1 addition & 1 deletion app/models/ticket.rb
Expand Up @@ -335,7 +335,7 @@ def online_notification_seen_state(user_id_check = nil)
state = Ticket::State.lookup(id: state_id)
state_type = Ticket::StateType.lookup(id: state.state_type_id)

# always to set unseen for ticket owner
# always to set unseen for ticket owner and users which did not the update
if state_type.name != 'merged'
if user_id_check
return false if user_id_check == owner_id && user_id_check != updated_by_id
Expand Down
10 changes: 6 additions & 4 deletions app/models/transaction/notification.rb
Expand Up @@ -38,8 +38,10 @@ def perform
# ignore notifications
sender = Ticket::Article::Sender.lookup(id: article.sender_id)
if sender && sender.name == 'System'
return if @item[:changes].empty?
article = nil
return if @item[:changes].blank? && article.preferences[:notification] != true
if article.preferences[:notification] != true
article = nil
end
end
end

Expand Down Expand Up @@ -78,7 +80,7 @@ def perform

# ignore if no changes has been done
changes = human_changes(user, ticket)
next if @item[:type] == 'update' && !article && (!changes || changes.empty?)
next if @item[:type] == 'update' && !article && changes.blank?

# check if today already notified
if @item[:type] == 'reminder_reached' || @item[:type] == 'escalation' || @item[:type] == 'escalation_warning'
Expand Down Expand Up @@ -117,7 +119,7 @@ def perform
OnlineNotification.remove_by_type('Ticket', ticket.id, 'escalation_warning', user)

# on updates without state changes create unseen messages
elsif @item[:type] != 'create' && (!@item[:changes] || @item[:changes].empty? || !@item[:changes]['state_id'])
elsif @item[:type] != 'create' && (@item[:changes].blank? || @item[:changes]['state_id'].blank?)
seen = false
else
seen = ticket.online_notification_seen_state(user.id)
Expand Down
6 changes: 3 additions & 3 deletions lib/sessions.rb
Expand Up @@ -5,7 +5,7 @@ module Sessions

# get application root directory
@root = Dir.pwd.to_s
if !@root || @root.empty? || @root == '/'
if @root.blank? || @root == '/'
@root = Rails.root
end

Expand Down Expand Up @@ -379,8 +379,8 @@ def self.broadcast(data, recipient = 'authenticated', sender_user_id = nil)
next if !session

if recipient != 'public'
next if !session[:user]
next if !session[:user]['id']
next if session[:user].blank?
next if session[:user]['id'].blank?
end

if sender_user_id
Expand Down
19 changes: 18 additions & 1 deletion test/integration/email_deliver_test.rb
Expand Up @@ -202,9 +202,13 @@ class EmailDeliverTest < ActiveSupport::TestCase
created_by_id: 1,
)

ticket1.state = Ticket::State.find_by(name: 'closed')
ticket1.save

assert_raises(RuntimeError) {
Scheduler.worker(true)
}
ticket1.reload

article2_lookup = Ticket::Article.find(article2.id)
assert_equal(2, ticket1.articles.count)
Expand All @@ -214,49 +218,61 @@ class EmailDeliverTest < ActiveSupport::TestCase
assert(article2_lookup.preferences['delivery_status_message'])

Scheduler.worker(true)
ticket1.reload

article2_lookup = Ticket::Article.find(article2.id)
assert_equal(2, ticket1.articles.count)
assert_equal(1, article2_lookup.preferences['delivery_retry'])
assert_equal('fail', article2_lookup.preferences['delivery_status'])
assert(article2_lookup.preferences['delivery_status_date'])
assert(article2_lookup.preferences['delivery_status_message'])
assert_equal('closed', ticket1.state.name)

sleep 6
assert_raises(RuntimeError) {
Scheduler.worker(true)
}
ticket1.reload

article2_lookup = Ticket::Article.find(article2.id)
assert_equal(2, ticket1.articles.count)
assert_equal(2, article2_lookup.preferences['delivery_retry'])
assert_equal('fail', article2_lookup.preferences['delivery_status'])
assert(article2_lookup.preferences['delivery_status_date'])
assert(article2_lookup.preferences['delivery_status_message'])
assert_equal('closed', ticket1.state.name)

Scheduler.worker(true)
ticket1.reload

article2_lookup = Ticket::Article.find(article2.id)
assert_equal(2, ticket1.articles.count)
assert_equal(2, article2_lookup.preferences['delivery_retry'])
assert_equal('fail', article2_lookup.preferences['delivery_status'])
assert(article2_lookup.preferences['delivery_status_date'])
assert(article2_lookup.preferences['delivery_status_message'])
assert_equal('closed', ticket1.state.name)

sleep 11
assert_raises(RuntimeError) {
Scheduler.worker(true)
}
ticket1.reload

article2_lookup = Ticket::Article.find(article2.id)
assert_equal(2, ticket1.articles.count)
assert_equal(3, article2_lookup.preferences['delivery_retry'])
assert_equal('fail', article2_lookup.preferences['delivery_status'])
assert(article2_lookup.preferences['delivery_status_date'])
assert(article2_lookup.preferences['delivery_status_message'])
assert_equal('closed', ticket1.state.name)

sleep 16
assert_raises(RuntimeError) {
Scheduler.worker(true)
}
ticket1.reload

article2_lookup = Ticket::Article.find(article2.id)
article_delivery_system = ticket1.articles.last
assert_equal(3, ticket1.articles.count)
Expand All @@ -267,7 +283,8 @@ class EmailDeliverTest < ActiveSupport::TestCase
assert_equal('System', article_delivery_system.sender.name)
assert_equal(true, article_delivery_system.preferences['delivery_message'])
assert_equal(article2.id, article_delivery_system.preferences['delivery_article_id_related'])

assert_equal(true, article_delivery_system.preferences['notification'])
assert_equal(Ticket::State.find_by(default_follow_up: true).name, ticket1.state.name)
end

end

0 comments on commit 4ba2744

Please sign in to comment.