Files
leadchat/app/mailboxes/support_mailbox.rb
Sojan Jose aaf4fee9a6 chore: Fix sentry errors in email processing for bounce notifications (#8677)
This case occurs for bounce notification emails where the from address is From: "" (Mail Delivery System) . We will be discarding these emails for now.

Fixes: https://linear.app/chatwoot/issue/CW-2793/activerecordrecordinvalid-validation-failed-email-invalid-email
2024-01-10 14:30:23 -08:00

101 lines
3.6 KiB
Ruby

class SupportMailbox < ApplicationMailbox
attr_accessor :channel, :account, :inbox, :conversation, :processed_mail
before_processing :find_channel,
:load_account,
:load_inbox,
:decorate_mail
def process
Rails.logger.info "Processing email #{mail.message_id} from #{original_sender_email} to #{mail.to} with subject #{mail.subject}"
# to turn off spam conversation creation
return unless @account.active?
# prevent loop from chatwoot notification emails
return if notification_email_from_chatwoot?
# return if email doesn't have a valid sender
# This can happen in cases like bounce emails for invalid contact email address
# TODO: Handle the bounce seperately and mark the contact as invalid
# we are checking for @ since the returned value could be "\"\"" for some email clients
return unless original_sender_email.include?('@')
ActiveRecord::Base.transaction do
find_or_create_contact
find_or_create_conversation
create_message
add_attachments_to_message
end
end
private
def find_channel
find_channel_with_to_mail if @channel.blank?
raise 'Email channel/inbox not found' if @channel.nil?
@channel
end
def find_channel_with_to_mail
@channel = EmailChannelFinder.new(mail).perform
end
def load_account
@account = @channel.account
end
def load_inbox
@inbox = @channel.inbox
end
def decorate_mail
@processed_mail = MailPresenter.new(mail, @account)
end
def find_conversation_by_in_reply_to
return if in_reply_to.blank?
@account.conversations.where("additional_attributes->>'in_reply_to' = ?", in_reply_to).first
end
def in_reply_to
mail['In-Reply-To'].try(:value)
end
def original_sender_email
@processed_mail.original_sender&.downcase
end
def find_or_create_conversation
@conversation = find_conversation_by_in_reply_to || ::Conversation.create!({
account_id: @account.id,
inbox_id: @inbox.id,
contact_id: @contact.id,
contact_inbox_id: @contact_inbox.id,
additional_attributes: {
in_reply_to: in_reply_to,
source: 'email',
mail_subject: @processed_mail.subject,
initiated_at: {
timestamp: Time.now.utc
}
}
})
end
def find_or_create_contact
@contact = @inbox.contacts.find_by(email: original_sender_email)
if @contact.present?
@contact_inbox = ContactInbox.find_by(inbox: @inbox, contact: @contact)
else
create_contact
end
end
def identify_contact_name
processed_mail.sender_name || processed_mail.from.first.split('@').first
end
end