ticket_article_communicate_email_job.rb 5.2 KB

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