来自: [url]http://www.beyondrails.com/blogs/11[/url]
ActionMailer现在的实现只支持smtp和Sendmail两种方式发送邮件,配置分别如下:
[code]
# ActionMailer::Base.delivery_method = :smtp
# ActionMailer::Base.smtp_settings = SMTP_SETTINGS
ActionMailer::Base.delivery_method = :sendmail
ActionMailer::Base.sendmail_settings = SENDMAIL_SETTINGS
SMTP_SETTINGS = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "beyondrails.com",
:authentication => :login,
:user_name => "beyondrails@gmail.com",
:password => "password"
}
SENDMAIL_SETTINGS = {
:location => '/usr/sbin/sendmail',
:arguments => '-i -t'
}
[/code]
为什么只支持这两种方式呢?让我们看下ActionMailer::Base的源码:
[code]
module ActionMailer
class Base
class << self
def method_missing(method_symbol, *parameters)#:nodoc:
case method_symbol.id2name
when /^create_([_a-z]\w*)/ then new($1, *parameters).mail
when /^deliver_([_a-z]\w*)/ then new($1, *parameters).deliver!
when "new" then nil
else super
end
end
end
def deliver!(mail = @mail)
raise "no mail object available for delivery!" unless mail
logger.info "Sent mail:\n #{mail.encoded}" unless logger.nil?
begin
send("perform_delivery_#{delivery_method}", mail) if perform_deliveries
rescue Exception => e # Net::SMTP errors or sendmail pipe errors
raise e if raise_delivery_errors
end
return mail
end
private
def perform_delivery_smtp(mail)
destinations = mail.destinations
mail.ready_to_send
Net::SMTP.start(smtp_settings[:address], smtp_settings[:port], smtp_settings[:domain],
smtp_settings[:user_name], smtp_settings[:password], smtp_settings[:authentication]) do |smtp|
smtp.sendmail(mail.encoded, mail.from, destinations)
end
end
def perform_delivery_sendmail(mail)
IO.popen("#{sendmail_settings[:location]} #{sendmail_settings[:arguments]}","w+") do |sm|
sm.print(mail.encoded.gsub(/\r/, ''))
sm.flush
end
end
end
end
end
[/code]
我们可以清楚的看到ActionMailer的调用顺序,首先是method_missing捕捉deliver_xxx方法,然后进入deliver!方法,然后根据deliver_method进入perform_deliver_xxx方法。
可以看到,sendmail方式的实现也非常简单,直接使用IO.popen方法来调用系统命令。
使用Sendmail这一Linux下高性能邮件服务器发送邮件,可以避免使用Gmail等邮件系统提供的smtp服务不稳定或需要Recaptcha图片验证等麻烦问题。
ActionMailer现在的实现只支持smtp和Sendmail两种方式发送邮件,配置分别如下:
[code]
# ActionMailer::Base.delivery_method = :smtp
# ActionMailer::Base.smtp_settings = SMTP_SETTINGS
ActionMailer::Base.delivery_method = :sendmail
ActionMailer::Base.sendmail_settings = SENDMAIL_SETTINGS
SMTP_SETTINGS = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "beyondrails.com",
:authentication => :login,
:user_name => "beyondrails@gmail.com",
:password => "password"
}
SENDMAIL_SETTINGS = {
:location => '/usr/sbin/sendmail',
:arguments => '-i -t'
}
[/code]
为什么只支持这两种方式呢?让我们看下ActionMailer::Base的源码:
[code]
module ActionMailer
class Base
class << self
def method_missing(method_symbol, *parameters)#:nodoc:
case method_symbol.id2name
when /^create_([_a-z]\w*)/ then new($1, *parameters).mail
when /^deliver_([_a-z]\w*)/ then new($1, *parameters).deliver!
when "new" then nil
else super
end
end
end
def deliver!(mail = @mail)
raise "no mail object available for delivery!" unless mail
logger.info "Sent mail:\n #{mail.encoded}" unless logger.nil?
begin
send("perform_delivery_#{delivery_method}", mail) if perform_deliveries
rescue Exception => e # Net::SMTP errors or sendmail pipe errors
raise e if raise_delivery_errors
end
return mail
end
private
def perform_delivery_smtp(mail)
destinations = mail.destinations
mail.ready_to_send
Net::SMTP.start(smtp_settings[:address], smtp_settings[:port], smtp_settings[:domain],
smtp_settings[:user_name], smtp_settings[:password], smtp_settings[:authentication]) do |smtp|
smtp.sendmail(mail.encoded, mail.from, destinations)
end
end
def perform_delivery_sendmail(mail)
IO.popen("#{sendmail_settings[:location]} #{sendmail_settings[:arguments]}","w+") do |sm|
sm.print(mail.encoded.gsub(/\r/, ''))
sm.flush
end
end
end
end
end
[/code]
我们可以清楚的看到ActionMailer的调用顺序,首先是method_missing捕捉deliver_xxx方法,然后进入deliver!方法,然后根据deliver_method进入perform_deliver_xxx方法。
可以看到,sendmail方式的实现也非常简单,直接使用IO.popen方法来调用系统命令。
使用Sendmail这一Linux下高性能邮件服务器发送邮件,可以避免使用Gmail等邮件系统提供的smtp服务不稳定或需要Recaptcha图片验证等麻烦问题。