动态配置 SMTP 设置时 ActionMailer 不传送邮件
ActionMailer not delivering mail when SMTP settings configured dynamically
我正在尝试将 ActionMailer 的 SMTP 设置设置为能够在运行时进行配置,但当发生这种情况时,它似乎无法连接到第 3 方服务来发送邮件。以下是两种情况,第一种情况是邮件将发送并投递,第二种情况什么也没有发生。我正在使用开发环境进行测试
此配置对两种场景通用
# config/environments/development.rb
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default :charset => "utf-8"
config.action_mailer.delivery_method = :smtp
有效:
# config/environments/development.rb
config.action_mailer.default_url_options = { host: 'www.mysite.com' }
config.action_mailer.smtp_settings = {
:address => "smtp.thirdpartyservice.com",
:port => 587,
:domain => 'mysite.com',
:user_name => "me@mysite.com",
:password => "my-password",
:authentication => "plain",
:enable_starttls_auto => true
}
这会传送邮件,但也会在跟踪日志时,请求中有轻微延迟,所以我知道请求是向第三方服务发出的。
这行不通:
这是我想要的设置,使用我正在使用的自定义邮件程序。
class MyCustomMailer < Devise::Mailer
before_filter :use_smtp_settings
def example_mailer(record)
Rails.logger.warn self.smtp_settings
@resource = record
mail(to: record.email,
from: AppSettings.first.mailer_sender,
subject: "Example")
end
private
def use_smtp_settings
self.default_url_options[:host] = AppSettings.first.domain_address
self.smtp_settings = {
:address => AppSettings.first.smtp_address,
:port => AppSettings.first.smtp_port,
:domain => AppSettings.first.smtp_domain,
:user_name => AppSettings.first.smtp_username,
:password => AppSettings.first.smtp_password,
:authentication => "plain",
:enable_starttls_auto => true
}
end
end
#example_mailer()
方法中的 rails 记录器显示与第一个示例中使用的相同属性,尽管是从 app_settings
table 加载的。但是这次跟踪日志时,没有延迟,所以 ActionMailer 似乎甚至没有尝试向第三方服务发出请求。
这不起作用,因为您正在修改邮件程序实例上的 smtp 设置,但基础邮件 gem 从邮件程序 class 级别属性读取它。在 Rails 4.0 及更高版本中支持的方法是将名为 :delivery_method_options 的自定义 header 传递给邮件调用,例如:
class MyCustomMailer < Devise::Mailer
before_filter set_default_host
def example_mailer(record)
mail to: record.email,
from: app_mailer_sender,
subject: "Example",
delivery_method_options: app_smtp_settings
end
private
def app_settings
@app_settings || AppSettings.first
end
def app_domain_address
app_settings.domain_address
end
def app_mailer_sender
app_settings.mailer_sender
end
def app_smtp_settings
self.smtp_settings = {
address: app_settings.smtp_address,
port: app_settings.smtp_port,
domain: app_settings.smtp_domain,
user_name: app_settings.smtp_username,
password: app_settings.smtp_password,
authentication: "plain",
enable_starttls_auto: true
}
end
def set_default_host
default_url_options[:host] = app_settings.domain_address
end
end
结束
一个小提示 - 不要重复调用 AppSettings.first,因为 re-queries 数据库(实际上它会被 AR 查询缓存捕获,但每次都会创建一个新实例) .但你知道的是对的 ;-)
我正在尝试将 ActionMailer 的 SMTP 设置设置为能够在运行时进行配置,但当发生这种情况时,它似乎无法连接到第 3 方服务来发送邮件。以下是两种情况,第一种情况是邮件将发送并投递,第二种情况什么也没有发生。我正在使用开发环境进行测试
此配置对两种场景通用
# config/environments/development.rb
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default :charset => "utf-8"
config.action_mailer.delivery_method = :smtp
有效:
# config/environments/development.rb
config.action_mailer.default_url_options = { host: 'www.mysite.com' }
config.action_mailer.smtp_settings = {
:address => "smtp.thirdpartyservice.com",
:port => 587,
:domain => 'mysite.com',
:user_name => "me@mysite.com",
:password => "my-password",
:authentication => "plain",
:enable_starttls_auto => true
}
这会传送邮件,但也会在跟踪日志时,请求中有轻微延迟,所以我知道请求是向第三方服务发出的。
这行不通:
这是我想要的设置,使用我正在使用的自定义邮件程序。
class MyCustomMailer < Devise::Mailer
before_filter :use_smtp_settings
def example_mailer(record)
Rails.logger.warn self.smtp_settings
@resource = record
mail(to: record.email,
from: AppSettings.first.mailer_sender,
subject: "Example")
end
private
def use_smtp_settings
self.default_url_options[:host] = AppSettings.first.domain_address
self.smtp_settings = {
:address => AppSettings.first.smtp_address,
:port => AppSettings.first.smtp_port,
:domain => AppSettings.first.smtp_domain,
:user_name => AppSettings.first.smtp_username,
:password => AppSettings.first.smtp_password,
:authentication => "plain",
:enable_starttls_auto => true
}
end
end
#example_mailer()
方法中的 rails 记录器显示与第一个示例中使用的相同属性,尽管是从 app_settings
table 加载的。但是这次跟踪日志时,没有延迟,所以 ActionMailer 似乎甚至没有尝试向第三方服务发出请求。
这不起作用,因为您正在修改邮件程序实例上的 smtp 设置,但基础邮件 gem 从邮件程序 class 级别属性读取它。在 Rails 4.0 及更高版本中支持的方法是将名为 :delivery_method_options 的自定义 header 传递给邮件调用,例如:
class MyCustomMailer < Devise::Mailer
before_filter set_default_host
def example_mailer(record)
mail to: record.email,
from: app_mailer_sender,
subject: "Example",
delivery_method_options: app_smtp_settings
end
private
def app_settings
@app_settings || AppSettings.first
end
def app_domain_address
app_settings.domain_address
end
def app_mailer_sender
app_settings.mailer_sender
end
def app_smtp_settings
self.smtp_settings = {
address: app_settings.smtp_address,
port: app_settings.smtp_port,
domain: app_settings.smtp_domain,
user_name: app_settings.smtp_username,
password: app_settings.smtp_password,
authentication: "plain",
enable_starttls_auto: true
}
end
def set_default_host
default_url_options[:host] = app_settings.domain_address
end
end
结束
一个小提示 - 不要重复调用 AppSettings.first,因为 re-queries 数据库(实际上它会被 AR 查询缓存捕获,但每次都会创建一个新实例) .但你知道的是对的 ;-)