Files
chatwoot/app/mailboxes/application_mailbox.rb
T
Shivam Mishra 84993485b2 refactor: unify email routing with NewConversationStrategy fallback
Replace separate SupportMailbox with NewConversationStrategy as the
final fallback in the conversation finder chain. This prevents emails
from being silently dropped when routing rules match but no existing
conversation is found.

Previously, emails could route to ReplyMailbox (based on headers or
channel matching) but get dropped if ReferencesStrategy failed to find
a conversation. This happened when two Chatwoot accounts emailed each
other - References header contained conversation IDs from both accounts,
routing matched globally, but scoped queries found nothing.
2025-10-30 17:09:35 +05:30

41 lines
1.4 KiB
Ruby

class ApplicationMailbox < ActionMailbox::Base
include MailboxHelper
# Last part is the regex for the UUID
# Eg: email should be something like : reply+6bdc3f4d-0bec-4515-a284-5d916fdde489@domain.com
REPLY_EMAIL_UUID_PATTERN = /^reply\+([0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12})$/i
# Route all emails to verified channels to the unified reply mailbox
# The ConversationFinder will determine if it's a reply or new conversation
routing(
lambda { |inbound_mail|
valid_to_address?(inbound_mail) &&
(reply_uuid_mail?(inbound_mail) || EmailChannelFinder.new(inbound_mail.mail).perform.present?)
} => :reply
)
# catchall
routing(all: :default)
class << self
# checks if follows this pattern: reply+<conversation-uuid>@<mailer-domain.com>
def reply_uuid_mail?(inbound_mail)
inbound_mail.mail.to&.any? do |email|
conversation_uuid = email.split('@')[0]
conversation_uuid.match?(REPLY_EMAIL_UUID_PATTERN)
end
end
# if mail.to returns a string, then it is a malformed `to` header
# valid `to` header will be of type Mail::AddressContainer
# validate if the to address is of type string
def valid_to_address?(inbound_mail)
to_address_class = inbound_mail.mail.to&.class
return true if to_address_class == Mail::AddressContainer
Rails.logger.error "Email to address header is malformed `#{inbound_mail.mail.to}`"
false
end
end
end