我看过这篇文章,但我的情况略有不同:
Rails ActionMailer with multiple SMTP servers
我允许用户使用自己的SMTP凭据发送邮件,因此它确实来自他们。
但它们将从Rails应用程序发送,这意味着每个用户需要使用自己的SMTP服务器发送电子邮件。
我该怎么做?
答案 0 :(得分:58)
执行其他答案中描述的内容并不安全;你在这里设置类变量,而不是实例变量。如果您的Rails容器正在分叉,您可以执行此操作,但现在您的应用程序依赖于容器的实现细节。如果你没有分配新的Ruby进程,那么你可以在这里遇到竞争条件。
你应该有一个扩展ActionMailer :: Base的模型,当你调用一个方法时,它将返回一个Mail :: Message对象。这是您的实例对象,您应该更改设置。这些设置也只是一个哈希值,因此您可以内联它。
msg = MyMailer.some_message
msg.delivery_method.settings.merge!(@user.mail_settings)
msg.deliver
在上面的mail_settings中返回一些带有适当键IE
的哈希值{:user_name=>username, :password=>password}
答案 1 :(得分:12)
这是我根据之前的答案和评论提出的解决方案。这使用ActionMailer interceptor class。
class UserMailer < ActionMailer::Base
default from: proc{ @user.mail_settings[:from_address] }
class DynamicSettingsInterceptor
def self.delivering_email(message)
message.delivery_method.settings.merge!(@user.mail_settings)
end
end
register_interceptor DynamicSettingsInterceptor
end
答案 2 :(得分:9)
对于Rails 3.2.x
您可以在邮件程序类中包含AbstractController :: Callbacks,并在邮件程序中执行“after_filter:set_delivery_options”。
set_delivery_options方法可以访问您在邮件程序操作中设置的实例变量,并且您可以将邮件对象作为“邮件”进行访问。
class MyNailer < ActionMailer::Base
include AbstractController::Callbacks
after_filter :set_delivery_options
def nail_it(user)
@user = user
mail :subject => "you nailed it"
end
private
def set_delivery_options
message.delivery_method.settings.merge!(@user.company.smtp_creds)
end
end
答案 3 :(得分:3)
只需在每次发送操作之前设置ActionMailer :: Base配置值。
smtp_config = user.smtp_configuration
ActionMailer::Base.username = smtp_config.username
ActionMailer::Base.password = smtp_config.password
ActionMailer::Base.server = ..
ActionMailer::Base.port = ..
ActionMailer::Base.authentication = ..
答案 4 :(得分:3)
如果某人需要动态设置传递方法和smtp凭据,您可以使用Mail::Message instance method将传递方法与其变量一起设置,以便我的addapted Aditya Sanghi版本为:
class MainMailer < ActionMailer::Base
WHATEVER_CONDITION = true # example only f.e. @ser
include AbstractController::Callbacks
after_filter :set_delivery_options
private
def set_delivery_options
settings = {
:address => 'smtp.mandrillapp.com', # intentionally
:port => 587, # intentionally
:domain => 'your_domain', #insetad of localhost.localdomain'
:user_name => 'smtp_username',
:password => 'smtp_password',
:authentication => 'PLAIN' # or smthing else
}
if WHATEVER_CONDITION
message.delivery_method(:smtp, settings)
end
end
end
答案 5 :(得分:0)
从Rails 4+开始,它就可以通过 delivery_method_options 参数直接提供凭据:
class UserMailer < ApplicationMailer
def welcome_email
@user = params[:user]
@url = user_url(@user)
delivery_options = { user_name: params[:company].smtp_user,
password: params[:company].smtp_password,
address: params[:company].smtp_host }
mail(to: @user.email,
subject: "Please see the Terms and Conditions attached",
delivery_method_options: delivery_options)
end
end
请参见Sending Emails with Dynamic Delivery Options (Rails Guides)