[ActionMailbox] Ingress with recipient omitted in the raw email

Hi,

I’ve run into the following situation:

There are some senders that may send emails that do not contain actual recipient the email is intended for. They may use Bcc, for example. I’ve seen messages without To whatsoever.

When trying to route such emails, ActionMailbox fails as none of the defined routes match, as it is only looking for recipients inside of the raw email. However, in the above case, the sender only gives that address during the SMTP session’s using RCPT TO.

I am not 100% sure about other ingress sources (just haven’t had time to explore), but in my case, I use Postmark and they do include OriginalRecipient field in their callback that captures that piece of information. However, rails/inbound_emails_controller.rb at main · rails/rails · GitHub throws it out by only getting the raw email.

At this point, the only source for potential extraction of the recipient address would be sifting through From fields but I find this rather uncomforting to dig through these as a reliable method.

Can we strategize a better way to avoid losing this rather critical piece of information? Or is it out of scope for ActionMailbox? Has anybody dealt with this before?

Since we’re dealing with rather different ingresses, it’s obvious there isn’t going to be one strategy-fits-all. I am not even positive whether all ingress types will be able to relay original recipient information.

I will try to address it by perhaps amending the ingress controller provided by ActionMailbox with something like an after_action that will capture the original recipient and add it to InboundEmail (for which the database model will have to be amended, or the relationship will be modelled externally – or even amend the raw source to contain x_original_to).

Any thoughts, comments?

Update: this is the current solution I’ve devised to combat the problem (not addressing past emails just yet):

I’ve defined a concept of overrides using this method from Rails Gudes and then overrode ActionMailbox::Ingresses::Postmark::InboundEmailsController this way:

ActionMailbox::Ingresses::Postmark::InboundEmailsController.class_eval do
  before_action :extract_original_recipient

  def extract_original_recipient
    original_recipient = params.require("OriginalRecipient")
    mail = Mail.from_source(params.require("RawEmail"))
    unless mail.recipients.include?(original_recipient)
      mail.headers x_original_to: original_recipient
    end
    params["RawEmail"] = mail.to_s
  end
end

It’s a bit hacky but the basic idea here is to make raw email in params have x-original-to header field so that ActionMailbox can route it.

1 Like