I would like to alter the Message-ID
header that is in the header portion of an email sent from a Ruby on Rails v3 application using ActionMailer.
I am using Sendmail on localhost for mail delivery.
Do I configure this in Sendmail or ActionMailer?
Where do I configure this (if it is ActionMailer): a file in config/
folder or a file in app/mailers/ folder?
Teddy's answer is good, except that if you actually want each message to have a different ID, you need to make the default a lambda. In the first block of code in his answer, it calculates the message-ID once, at init, and uses the same one for every message.
Here's how I'm doing this in my app:
default "Message-ID" => lambda {"<#{SecureRandom.uuid}@#{Rails.application.config.mailgun_domain}>"}
... with the domain taken from a custom app config variable (and using SecureRandom.uuid, which is a little more straightforward than a SHA-2 based on the timestamp IMO.)
I usually prefer generating the message-id with a UUID. Assuming you have the uuid gem:
headers['Message-ID'] = "<#{ UUID.generate }@example.com>"
Also you should note that according to RFC 2822 the message-id should be placed inside "<" and ">"
In Rails 4+ (or just Ruby 2.0+) the folowing syntax is working correctly:
default "Message-ID" => ->(v){"<#{Digest::SHA2.hexdigest(Time.now.to_i.to_s)}@yourdomain.com>"}
Tested this with MailCatcher.
I figured this out. The easiest way to do is to use the default
method at the top of the mailer class file.
Example:
require 'digest/sha2'
class UserMailer < ActionMailer::Base
default "Message-ID"=>"#{Digest::SHA2.hexdigest(Time.now.to_i.to_s)}@yourdomain.com"
# ... the rest of your mailer class
end
However, I found this difficult to test, so I wrote a private method and used the sent_at
time instead of Time.now
:
def message_id_in_header(sent_at=Time.now)
headers["Message-ID"] = "#{Digest::SHA2.hexdigest(sent_at.to_i.to_s)}@yourdomain.com"
end
And I simply called that method before calling the mail
method. This made it easy to pass a sent_at
parameter from my test and verify a match in email.encoded
.
@jasoncrawford is almost right. The problem is that the mailgun_domain attribute may not be able at development environment, so it is better to access the ActionMailer configs.
default "Message-ID" => lambda {"<#{SecureRandom.uuid}@{ActionMailer::Base.smtp_settings[:domain]}>"}