From 57359be37e88b7230b079a01a20f69bc1c89f31c Mon Sep 17 00:00:00 2001 From: Tejaswini Chile Date: Fri, 8 Apr 2022 11:20:19 +0530 Subject: [PATCH] Fix: Find mailbox with cc email (#4372) --- app/finders/email_channel_finder.rb | 15 +++++++++++ app/mailboxes/application_mailbox.rb | 17 +++++++----- app/mailboxes/mailbox_helper.rb | 2 ++ app/mailboxes/support_mailbox.rb | 10 +++++--- spec/finders/email_channel_finder_spec.rb | 29 +++++++++++++++++++++ spec/fixtures/files/in_reply_to.eml | 2 +- spec/fixtures/files/reply_cc.eml | 30 ++++++++++++++++++++++ spec/mailboxes/application_mailbox_spec.rb | 9 +++++++ spec/mailboxes/support_mailbox_spec.rb | 1 + 9 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 app/finders/email_channel_finder.rb create mode 100644 spec/finders/email_channel_finder_spec.rb create mode 100644 spec/fixtures/files/reply_cc.eml diff --git a/app/finders/email_channel_finder.rb b/app/finders/email_channel_finder.rb new file mode 100644 index 000000000..1c8eaeaf2 --- /dev/null +++ b/app/finders/email_channel_finder.rb @@ -0,0 +1,15 @@ +class EmailChannelFinder + def initialize(email_object) + @email_object = email_object + end + + def perform + channel = nil + recipient_mails = @email_object.to.to_a + @email_object.cc.to_a + recipient_mails.each do |email| + channel = Channel::Email.find_by('lower(email) = ? OR lower(forward_to_email) = ?', email.downcase, email.downcase) + break if channel.present? + end + channel + end +end diff --git a/app/mailboxes/application_mailbox.rb b/app/mailboxes/application_mailbox.rb index f27db5a49..f5e9abe1b 100644 --- a/app/mailboxes/application_mailbox.rb +++ b/app/mailboxes/application_mailbox.rb @@ -21,17 +21,20 @@ class ApplicationMailbox < ActionMailbox::Base def self.support_mail? proc do |inbound_mail_obj| is_a_support_email = false - inbound_mail_obj.mail.to&.each do |email| - channel = Channel::Email.find_by('lower(email) = ? OR lower(forward_to_email) = ?', email.downcase, email.downcase) - if channel.present? - is_a_support_email = true - break - end - end + + is_a_support_email = true if reply_to_mail?(inbound_mail_obj, is_a_support_email) + is_a_support_email end end + def self.reply_to_mail?(inbound_mail_obj, is_a_support_email) + return if is_a_support_email + + channel = EmailChannelFinder.new(inbound_mail_obj.mail).perform + channel.present? + end + def self.catch_all_mail? proc { |_mail| true } end diff --git a/app/mailboxes/mailbox_helper.rb b/app/mailboxes/mailbox_helper.rb index 831baa91a..927ab5eb5 100644 --- a/app/mailboxes/mailbox_helper.rb +++ b/app/mailboxes/mailbox_helper.rb @@ -2,6 +2,8 @@ module MailboxHelper private def create_message + return if @conversation.messages.find_by(source_id: processed_mail.message_id).present? + @message = @conversation.messages.create( account_id: @conversation.account_id, sender: @conversation.contact, diff --git a/app/mailboxes/support_mailbox.rb b/app/mailboxes/support_mailbox.rb index d215310e0..b0a1a68df 100644 --- a/app/mailboxes/support_mailbox.rb +++ b/app/mailboxes/support_mailbox.rb @@ -21,15 +21,17 @@ class SupportMailbox < ApplicationMailbox private def find_channel - mail.to.each do |email| - @channel = Channel::Email.find_by('lower(email) = ? OR lower(forward_to_email) = ?', email.downcase, email.downcase) - break if @channel.present? - end + 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 diff --git a/spec/finders/email_channel_finder_spec.rb b/spec/finders/email_channel_finder_spec.rb new file mode 100644 index 000000000..75cae37a9 --- /dev/null +++ b/spec/finders/email_channel_finder_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' + +describe ::EmailChannelFinder do + include ActionMailbox::TestHelper + let!(:channel_email) { create(:channel_email) } + + describe '#perform' do + context 'with cc mail' do + let(:reply_cc_mail) { create_inbound_email_from_fixture('reply_cc.eml') } + + it 'return channel with cc email' do + channel_email.update(email: 'test@example.com') + channel = described_class.new(reply_cc_mail.mail).perform + expect(channel).to eq(channel_email) + end + end + + context 'with to mail' do + let(:reply_mail) { create_inbound_email_from_fixture('reply.eml') } + + it 'return channel with to email' do + channel_email.update(email: 'test@example.com') + reply_mail.mail['to'] = 'test@example.com' + channel = described_class.new(reply_mail.mail).perform + expect(channel).to eq(channel_email) + end + end + end +end diff --git a/spec/fixtures/files/in_reply_to.eml b/spec/fixtures/files/in_reply_to.eml index eda6eac86..3a565ea9e 100644 --- a/spec/fixtures/files/in_reply_to.eml +++ b/spec/fixtures/files/in_reply_to.eml @@ -5,7 +5,7 @@ Subject: Discussion: Let's debate these attachments Date: Tue, 20 Apr 2020 04:20:20 -0400 In-Reply-To: <0CB459E0-0336-41DA-BC88-E6E28C697DDB@chatwoot.com> References: <4e6e35f5a38b4_479f13bb90078178@small-app-01.mail> -Message-Id: <0CB459E0-0336-41DA-BC88-E6E28C697DDB@chatwoot.com> +Message-Id: <0CB459E0-0336-41DA-BC88-E6E28C697DDBF@chatwoot.com> X-Mailer: Apple Mail (2.1244.3) --Apple-Mail=_33A037C7-4BB3-4772-AE52-FCF2D7535F74 diff --git a/spec/fixtures/files/reply_cc.eml b/spec/fixtures/files/reply_cc.eml new file mode 100644 index 000000000..6fd2e8e3b --- /dev/null +++ b/spec/fixtures/files/reply_cc.eml @@ -0,0 +1,30 @@ +MIME-Version: 1.0 +Date: Thu, 31 Mar 2022 19:25:32 +0530 +Message-ID: +Subject: Discussion: Let's debate these attachments +From: Sony Mathew +To: +Cc: Replies +Content-Type: multipart/alternative; boundary="00000000000001f49e05db8404a8" + +--00000000000001f49e05db8404a8 +Content-Type: text/plain; charset="UTF-8" + +Hello, + +Find the related inbox. + +-- +*Sony Mathew* + +--00000000000001f49e05db8404a8 +Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +
Hello,

Find the related inbox.

--
Sony Mathew

+ +--00000000000001f49e05db8404a8-- diff --git a/spec/mailboxes/application_mailbox_spec.rb b/spec/mailboxes/application_mailbox_spec.rb index f8b2e877f..3f3e8b97f 100644 --- a/spec/mailboxes/application_mailbox_spec.rb +++ b/spec/mailboxes/application_mailbox_spec.rb @@ -6,6 +6,7 @@ RSpec.describe ApplicationMailbox, type: :mailbox do describe 'route the inbound mail to appropriate mailbox' do let(:welcome_mail) { create_inbound_email_from_fixture('welcome.eml') } let(:reply_mail) { create_inbound_email_from_fixture('reply.eml') } + let(:reply_cc_mail) { create_inbound_email_from_fixture('reply_cc.eml') } let(:reply_mail_without_uuid) { create_inbound_email_from_fixture('reply.eml') } let(:reply_mail_with_in_reply_to) { create_inbound_email_from_fixture('in_reply_to.eml') } let(:support_mail) { create_inbound_email_from_fixture('support.eml') } @@ -55,6 +56,14 @@ RSpec.describe ApplicationMailbox, type: :mailbox do expect(dbl).to receive(:perform_processing).and_return(true) described_class.route support_mail end + + it 'routes support emails to Support Mailbox with cc email' do + channel_email.update(email: 'test@example.com') + dbl = double + expect(SupportMailbox).to receive(:new).and_return(dbl) + expect(dbl).to receive(:perform_processing).and_return(true) + described_class.route reply_cc_mail + end end end end diff --git a/spec/mailboxes/support_mailbox_spec.rb b/spec/mailboxes/support_mailbox_spec.rb index bad22aff3..7f5368ea4 100644 --- a/spec/mailboxes/support_mailbox_spec.rb +++ b/spec/mailboxes/support_mailbox_spec.rb @@ -148,6 +148,7 @@ RSpec.describe SupportMailbox, type: :mailbox do expect(conversation_1.messages.count).to eq(1) reply_mail_without_uuid.mail['In-Reply-To'] = 'conversation/6bdc3f4d-0bec-4515-a284-5d916fdde489/messages/123' + reply_mail_without_uuid.mail['Message-Id'] = '0CB459E0-0336-41DA-BC88-E6E28C697SFC@chatwoot.com' described_class.receive reply_mail_without_uuid