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