123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- class TicketArticleCommunicateEmailJob < ApplicationJob
- retry_on StandardError, attempts: 4, wait: lambda { |executions|
- executions * 25.seconds
- }
- def perform(article_id)
- record = Ticket::Article.find(article_id)
- # build subject
- ticket = Ticket.lookup(id: record.ticket_id)
- subject_prefix_mode = record.preferences[:subtype]
- subject = ticket.subject_build(record.subject, subject_prefix_mode)
- # set retry count
- record.preferences['delivery_retry'] ||= 0
- record.preferences['delivery_retry'] += 1
- # send email
- email_address = nil
- if record.preferences['email_address_id'].present?
- email_address = EmailAddress.find_by(id: record.preferences['email_address_id'])
- end
- # fallback for articles without email_address_id
- if !email_address
- if !ticket.group.email_address_id
- log_error(record, "No email address defined for group id '#{ticket.group.id}'!")
- elsif !ticket.group.email_address.channel_id
- log_error(record, "No channel defined for email_address id '#{ticket.group.email_address_id}'!")
- end
- email_address = ticket.group.email_address
- end
- # log if ref objects are missing
- if !email_address
- log_error(record, "No email address defined for group id '#{ticket.group_id}'!")
- end
- if !email_address.channel_id
- log_error(record, "No channel defined for email_address id '#{email_address.id}'!")
- end
- channel = email_address.channel
- notification = false
- sender = Ticket::Article::Sender.lookup(id: record.sender_id)
- if sender['name'] == 'System'
- notification = true
- end
- # get linked channel and send
- begin
- message = channel.deliver(
- {
- message_id: record.message_id,
- in_reply_to: record.in_reply_to,
- references: ticket.get_references([record.message_id]),
- from: record.from,
- to: record.to,
- cc: record.cc,
- subject: subject,
- content_type: record.content_type,
- body: record.body,
- attachments: record.attachments,
- security: record.preferences[:security],
- },
- notification,
- )
- rescue => e
- log_error(record, e.message, channel)
- return
- end
- if !message
- log_error(record, 'Unable to get sent email', channel)
- return
- end
- # set delivery status
- record.preferences['delivery_channel_id'] = channel.id
- record.preferences['delivery_status_message'] = nil
- record.preferences['delivery_status'] = 'success'
- record.preferences['delivery_status_date'] = Time.zone.now
- record.save!
- # store mail plain
- record.save_as_raw(message.to_s)
- # add history record
- recipient_list = ''
- %i[to cc].each do |key|
- next if !record[key]
- next if record[key] == ''
- if recipient_list != ''
- recipient_list += ','
- end
- recipient_list += record[key]
- end
- Rails.logger.info "Send email to: '#{recipient_list}' (from #{record.from})"
- return if recipient_list == ''
- History.add(
- o_id: record.id,
- history_type: 'email',
- history_object: 'Ticket::Article',
- related_o_id: ticket.id,
- related_history_object: 'Ticket',
- value_from: record.subject,
- value_to: recipient_list,
- created_by_id: record.created_by_id,
- )
- end
- def log_error(local_record, message, channel = nil)
- if channel
- local_record.preferences['delivery_channel_id'] = channel.id
- end
- local_record.preferences['delivery_status'] = 'fail'
- local_record.preferences['delivery_status_message'] = message.encode!('UTF-8', 'UTF-8', invalid: :replace, replace: '?')
- local_record.preferences['delivery_status_date'] = Time.zone.now
- local_record.save!
- Rails.logger.error message
- if local_record.preferences['delivery_retry'] > 3
- recipient_list = ''
- %i[to cc].each do |key|
- next if !local_record[key]
- next if local_record[key] == ''
- if recipient_list != ''
- recipient_list += ','
- end
- recipient_list += local_record[key]
- end
- # reopen ticket and notify agent
- TransactionDispatcher.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}",
- internal: true,
- sender: Ticket::Article::Sender.find_by(name: 'System'),
- type: Ticket::Article::Type.find_by(name: 'note'),
- preferences: {
- delivery_article_id_related: local_record.id,
- delivery_message: true,
- notification: true,
- },
- )
- ticket = Ticket.find(local_record.ticket_id)
- ticket.state = Ticket::State.find_by(default_follow_up: true)
- ticket.save!
- TransactionDispatcher.commit
- UserInfo.current_user_id = nil
- end
- raise message
- end
- end
|