Rails ActionMailer具有多个SMTP服务器

31 smtp ruby-on-rails actionmailer

我需要在Rails应用程序中使用两个不同的smtp服务器.似乎ActionMailer的构造方式,不可能为子类设置不同的smtp_settings.每当发送消息时,我都可以为每个邮件程序类重新加载smtp设置,但这会混淆我无法控制的ExceptionNotifier插件(除非我也搞乱它).有没有人有这样的解决方案/插件?

理想情况下我想拥有

class UserMailer < ActionMailer::Base; end
Run Code Online (Sandbox Code Playgroud)

然后在environment.rb中设置

ActionMailer::Base.smtp_settings = standard_smtp_settings
UserMailer.smtp_settings = user_smtp_settings
Run Code Online (Sandbox Code Playgroud)

因此,我的大多数邮件程序(包括ExceptionNotifier)都会提取默认设置,但UserMailer会使用付费中继服务.

小智 21

根据Oreilly的文章,我想出了我在这里写的解决方案:http: //transfs.com/devblog/2009/12/03/custom-smtp-settings-for-a-specific-actionmailer-subclass

这是相关的代码:

class MailerWithCustomSmtp < ActionMailer::Base
  SMTP_SETTINGS = {
    :address => "smtp.gmail.com",
    :port => 587,
    :authentication => :plain,
    :user_name => "custom_account@transfs.com",
    :password => 'password',
  }

  def awesome_email(bidder, options={})
     with_custom_smtp_settings do
        subject       'Awesome Email D00D!'
        recipients    'someone@test.com'
        from          'custom_reply_to@transfs.com'
        body          'Hope this works...'
     end
  end

  # Override the deliver! method so that we can reset our custom smtp server settings
  def deliver!(mail = @mail)
    out = super
    reset_smtp_settings if @_temp_smtp_settings
    out
  end

  private

  def with_custom_smtp_settings(&block)
    @_temp_smtp_settings = @@smtp_settings
    @@smtp_settings = SMTP_SETTINGS
    yield
  end

  def reset_smtp_settings
    @@smtp_settings = @_temp_smtp_settings
    @_temp_smtp_settings = nil
  end
end
Run Code Online (Sandbox Code Playgroud)


wnm*_*wnm 16

class UserMailer < ActionMailer::Base
  def welcome_email(user, company)
    @user = user
    @url  = user_url(@user)
    delivery_options = { user_name: company.smtp_user,
                         password: company.smtp_password,
                         address: company.smtp_host }
    mail(to: @user.email,
         subject: "Please see the Terms and Conditions attached",
         delivery_method_options: delivery_options)
  end
end
Run Code Online (Sandbox Code Playgroud)

Rails 4允许动态交付选项.上面的代码直接来自动作邮件基础知识指南,您可以在此处找到:http://guides.rubyonrails.org/v4.0/action_mailer_basics.html#sending-emails-with-dynamic-delivery-options

有了这个,您可以为您发送的每封电子邮件设置不同的smtp设置,或者像在Usercase,OtherMailer等不同子类的用例中一样.


Lev*_*sky 11

Rails 4.2+的解决方案:

config/secrets.yml:

production:
  gmail_smtp:
    :authentication: "plain"
    :address: "smtp.gmail.com"
    :port: 587
    :domain: "zzz.com"
    :user_name: "zzz@zzz.com"
    :password: "zzz"
    :enable_starttls_auto: true
  mandrill_smtp:
    :authentication: "plain"
    :address: "smtp.mandrillapp.com"
    :port: 587
    :domain: "zzz.com"
    :user_name: "zzz@zzz.com"
    :password: "zzz"
    :enable_starttls_auto: true
  mailgun_smtp:
    :authentication: "plain"
    :address: "smtp.mailgun.org"
    :port: 587
    :domain: "zzz.com"
    :user_name: "zzz@zzz.com"
    :password: "zzz"
    :enable_starttls_auto: true
Run Code Online (Sandbox Code Playgroud)

config/environments/production.rb:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = Rails.application.secrets.gmail_smtp
Run Code Online (Sandbox Code Playgroud)

app/mailers/application_mailer.rb:

class ApplicationMailer < ActionMailer::Base
  default from: '"ZZZ" <zzz@zzz.com>'

  private

  def gmail_delivery
    mail.delivery_method.settings = Rails.application.secrets.gmail_smtp
  end

  def mandrill_delivery
    mail.delivery_method.settings = Rails.application.secrets.mandrill_smtp
  end

  def mailgun_delivery
    mail.delivery_method.settings = Rails.application.secrets.mailgun_smtp
  end
end
Run Code Online (Sandbox Code Playgroud)

app/mailers/user_mailer.rb:

class UserMailer < ApplicationMailer
  # after_action :gmail_delivery, only: [:notify_user]
  after_action :mandrill_delivery, only: [:newsletter]
  after_action :mailgun_delivery, only: [:newsletter2]

  def newsletter(user_id); '...' end # this will be sent through mandrill smtp
  def newsletter2(user_id); '...' end # this will be sent through mailgun smtp
  def notify_user(user_id); '...' end # this will be sent through gmail smtp
end
Run Code Online (Sandbox Code Playgroud)


bod*_*ous 10

对于任何与Rails的更高版本(3+)接近此问题的人,请尝试这样做

http://guides.rubyonrails.org/action_mailer_basics.html#sending-emails-with-dynamic-delivery-options

  • is delivery_method_options really in rails 3? I only find the docs in rails 4... (2认同)

Tut*_*teC 6

试图在Rails 3.2.1中使用jkrall的选项,但由于某种原因它不会覆盖默认配置,但是:

MyMailer.my_email.delivery_method.settings.merge!(SMTP_SETTINGS).deliver
Run Code Online (Sandbox Code Playgroud)

http://www.scottw.com/multiple-smtp-servers-with-action-mailer类似,使其有效.


Dam*_*IEU 0

恐怕这在本地是做不到的。
但是您可以通过修改模型中的 @@smtp_settings 变量来欺骗它。

Oreilly 上有一篇文章很好地解释了这一点,尽管他们的代码根本不干净。 http://broadcast.oreilly.com/2009/03/using-multiple-smtp-accounts-w.html