ticket_article_communicate_email_job.rb 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. class TicketArticleCommunicateEmailJob < ApplicationJob
  2. retry_on StandardError, attempts: 4, wait: lambda { |executions|
  3. executions * 25.seconds
  4. }
  5. def perform(article_id)
  6. record = Ticket::Article.find(article_id)
  7. # build subject
  8. ticket = Ticket.lookup(id: record.ticket_id)
  9. subject_prefix_mode = record.preferences[:subtype]
  10. subject = ticket.subject_build(record.subject, subject_prefix_mode)
  11. # set retry count
  12. record.preferences['delivery_retry'] ||= 0
  13. record.preferences['delivery_retry'] += 1
  14. # send email
  15. email_address = nil
  16. if record.preferences['email_address_id'].present?
  17. email_address = EmailAddress.find_by(id: record.preferences['email_address_id'])
  18. end
  19. # fallback for articles without email_address_id
  20. if !email_address
  21. if !ticket.group.email_address_id
  22. log_error(record, "No email address defined for group id '#{ticket.group.id}'!")
  23. elsif !ticket.group.email_address.channel_id
  24. log_error(record, "No channel defined for email_address id '#{ticket.group.email_address_id}'!")
  25. end
  26. email_address = ticket.group.email_address
  27. end
  28. # log if ref objects are missing
  29. if !email_address
  30. log_error(record, "No email address defined for group id '#{ticket.group_id}'!")
  31. end
  32. if !email_address.channel_id
  33. log_error(record, "No channel defined for email_address id '#{email_address.id}'!")
  34. end
  35. channel = email_address.channel
  36. notification = false
  37. sender = Ticket::Article::Sender.lookup(id: record.sender_id)
  38. if sender['name'] == 'System'
  39. notification = true
  40. end
  41. # get linked channel and send
  42. begin
  43. message = channel.deliver(
  44. {
  45. message_id: record.message_id,
  46. in_reply_to: record.in_reply_to,
  47. references: ticket.get_references([record.message_id]),
  48. from: record.from,
  49. to: record.to,
  50. cc: record.cc,
  51. subject: subject,
  52. content_type: record.content_type,
  53. body: record.body,
  54. attachments: record.attachments
  55. },
  56. notification
  57. )
  58. rescue => e
  59. log_error(record, e.message, channel)
  60. return
  61. end
  62. if !message
  63. log_error(record, 'Unable to get sent email', channel)
  64. return
  65. end
  66. # set delivery status
  67. record.preferences['delivery_channel_id'] = channel.id
  68. record.preferences['delivery_status_message'] = nil
  69. record.preferences['delivery_status'] = 'success'
  70. record.preferences['delivery_status_date'] = Time.zone.now
  71. record.save!
  72. # store mail plain
  73. record.save_as_raw(message.to_s)
  74. # add history record
  75. recipient_list = ''
  76. %i[to cc].each do |key|
  77. next if !record[key]
  78. next if record[key] == ''
  79. if recipient_list != ''
  80. recipient_list += ','
  81. end
  82. recipient_list += record[key]
  83. end
  84. Rails.logger.info "Send email to: '#{recipient_list}' (from #{record.from})"
  85. return if recipient_list == ''
  86. History.add(
  87. o_id: record.id,
  88. history_type: 'email',
  89. history_object: 'Ticket::Article',
  90. related_o_id: ticket.id,
  91. related_history_object: 'Ticket',
  92. value_from: record.subject,
  93. value_to: recipient_list,
  94. created_by_id: record.created_by_id,
  95. )
  96. end
  97. def log_error(local_record, message, channel = nil)
  98. if channel
  99. local_record.preferences['delivery_channel_id'] = channel.id
  100. end
  101. local_record.preferences['delivery_status'] = 'fail'
  102. local_record.preferences['delivery_status_message'] = message.encode!('UTF-8', 'UTF-8', invalid: :replace, replace: '?')
  103. local_record.preferences['delivery_status_date'] = Time.zone.now
  104. local_record.save!
  105. Rails.logger.error message
  106. if local_record.preferences['delivery_retry'] > 3
  107. recipient_list = ''
  108. %i[to cc].each do |key|
  109. next if !local_record[key]
  110. next if local_record[key] == ''
  111. if recipient_list != ''
  112. recipient_list += ','
  113. end
  114. recipient_list += local_record[key]
  115. end
  116. # reopen ticket and notify agent
  117. Observer::Transaction.reset
  118. UserInfo.current_user_id = 1
  119. Ticket::Article.create!(
  120. ticket_id: local_record.ticket_id,
  121. content_type: 'text/plain',
  122. body: "Unable to send email to '#{recipient_list}': #{message}",
  123. internal: true,
  124. sender: Ticket::Article::Sender.find_by(name: 'System'),
  125. type: Ticket::Article::Type.find_by(name: 'note'),
  126. preferences: {
  127. delivery_article_id_related: local_record.id,
  128. delivery_message: true,
  129. notification: true,
  130. },
  131. )
  132. ticket = Ticket.find(local_record.ticket_id)
  133. ticket.state = Ticket::State.find_by(default_follow_up: true)
  134. ticket.save!
  135. Observer::Transaction.commit
  136. UserInfo.current_user_id = nil
  137. end
  138. raise message
  139. end
  140. end