When we first migrated to Discourse months ago, the default digest settings, combined with a large number of legacy user accounts ported over from our original forums, caused a flood of email from the new Discourse setup. This flood of emails caused our email server to shut down, temporarily.
It then occurred to me that Discourse should permit different smtp_settings
for "high priority" such as user password resets and email logins as well as admin setup emails; and a different set of smtp_settings
for "low priority" emails like topic digests.
Today, I looked into this by reviewing the Discourse code and found that this is very easy to do. If we look at the ActionMailers in the Discourse application by class:
class AdminConfirmationMailer < ActionMailer::Base
class DownloadBackupMailer < ActionMailer::Base
class GroupSmtpMailer < ActionMailer::Base
class InviteMailer < ActionMailer::Base
class RejectionMailer < ActionMailer::Base
class SubscriptionMailer < ActionMailer::Base
class TestMailer < ActionMailer::Base
class UserNotifications < ActionMailer::Base
class VersionMailer < ActionMailer::Base
There are basically two ActionMailer::Base classes which should be "high priority" and sent in different SMTP channel. These are:
class AdminConfirmationMailer < ActionMailer::Base
class UserNotifications < ActionMailer::Base
To accomplish this should quite easy.
Write a plugin which extends the two classes above, something like this:
HIGH_PRIORITY_SMTP_SETTINGS = {
:address=>"my.email.server.com",
:port=>587,
:user_name=>"my_email_address",
:password=>"my_email_password",
:authentication=>"plain",
:enable_starttls_auto=>true
}
after_initialize do
AdminConfirmationMailer.class_eval do
before_action :high_priority_smtp_settings
def high_priority_smtp_settings
self.smtp_settings = HIGH_PRIORITY_SMTP_SETTINGS
end
end
UserNotifications.class_eval do
before_action :high_priority_smtp_settings
def high_priority_smtp_settings
self.smtp_settings = HIGH_PRIORITY_SMTP_SETTINGS
end
end
end
I think it is important to have two SMTP channels, one for HIGH_PRIORITY SMTP traffic and one for LOW PRIORITY SMTP traffic (the DEFAULT).
When I looked at the UserNotifications
mailer, I noticed that the digest emails are in the same mailer as lost password reset requests, etc. This means the simple code above will not accomplish our goal for the UserNotifications
mailer.
It might seem unfortunate that all these mailer actions are lumped into one mailer class; but we can get around this (I think, not confirmed) by changing the callback like this (for example):
before_action :high_priority_smtp_settings, only: [:digest]
Hence, the prototype Discourse plugin code will be more like this:
HIGH_PRIORITY_SMTP_SETTINGS = {
:address=>"my.email.server.com",
:port=>587,
:user_name=>"my_email_address",
:password=>"my_email_password",
:authentication=>"plain",
:enable_starttls_auto=>true
}
after_initialize do
AdminConfirmationMailer.class_eval do
before_action :high_priority_smtp_settings
def high_priority_smtp_settings
self.smtp_settings = HIGH_PRIORITY_SMTP_SETTINGS
end
end
UserNotifications.class_eval do
before_action :high_priority_smtp_settings, only: [:digest]
def high_priority_smtp_settings
self.smtp_settings = HIGH_PRIORITY_SMTP_SETTINGS
end
end
end
Caveat: I have not confirmed the
only
property for thebefore_action
callback works as expected in anActionMailer
.
On the other hand, I have enough in mind to start prototyping this later on!
See Also: