diff --git a/app/mailers/conversation_reply_mailer.rb b/app/mailers/conversation_reply_mailer.rb index 2913fffef..d30c58ab1 100644 --- a/app/mailers/conversation_reply_mailer.rb +++ b/app/mailers/conversation_reply_mailer.rb @@ -35,9 +35,8 @@ class ConversationReplyMailer < ApplicationMailer end def email_reply(message) - return unless smtp_config_set_or_development? - init_conversation_attributes(message.conversation) + return unless smtp_config_set_or_development? || email_oauth_enabled @message = message prepare_mail(true) diff --git a/app/services/email/send_on_email_service.rb b/app/services/email/send_on_email_service.rb index 64fe4a381..4786cd56f 100644 --- a/app/services/email/send_on_email_service.rb +++ b/app/services/email/send_on_email_service.rb @@ -5,10 +5,15 @@ class Email::SendOnEmailService < Base::SendOnChannelService Channel::Email end - def perform_reply + def perform_reply # rubocop:disable Metrics/AbcSize return unless message.email_notifiable_message? - reply_mail = ConversationReplyMailer.with(account: message.account).email_reply(message).deliver_now + mail = ConversationReplyMailer.with(account: message.account).email_reply(message) + raise "Email could not be prepared for message #{message.id}" if mail.nil? + + reply_mail = mail.deliver_now + raise "Email delivery returned nil for message #{message.id}" if reply_mail.nil? + Rails.logger.info("Email message #{message.id} sent with source_id: #{reply_mail.message_id}") message.update!(source_id: reply_mail.message_id) rescue StandardError => e diff --git a/spec/services/email/send_on_email_service_spec.rb b/spec/services/email/send_on_email_service_spec.rb index 5a4997eb0..f950862a4 100644 --- a/spec/services/email/send_on_email_service_spec.rb +++ b/spec/services/email/send_on_email_service_spec.rb @@ -57,6 +57,39 @@ describe Email::SendOnEmailService do end end + context 'when email_reply returns nil' do + let(:exception_tracker) { instance_double(ChatwootExceptionTracker, capture_exception: true) } + + before do + allow(mailer_context).to receive(:email_reply).with(message).and_return(nil) + allow(ChatwootExceptionTracker).to receive(:new).and_return(exception_tracker) + end + + it 'marks the message as failed with preparation error' do + service.perform + + expect(message.reload.status).to eq('failed') + expect(message.reload.external_error).to include("Email could not be prepared for message #{message.id}") + end + end + + context 'when deliver_now returns nil' do + let(:exception_tracker) { instance_double(ChatwootExceptionTracker, capture_exception: true) } + + before do + allow(mailer_context).to receive(:email_reply).with(message).and_return(delivery) + allow(delivery).to receive(:deliver_now).and_return(nil) + allow(ChatwootExceptionTracker).to receive(:new).and_return(exception_tracker) + end + + it 'marks the message as failed' do + service.perform + + expect(message.reload.status).to eq('failed') + expect(message.reload.external_error).to include("Email delivery returned nil for message #{message.id}") + end + end + context 'when an error occurs' do let(:error_message) { 'SMTP connection failed' } let(:error) { StandardError.new(error_message) }