Rails 5应用部署到Heroku后,在生产环境下无法发送SendGrid邮件

5

我昨天和今天早上都在尝试弄清楚发生了什么事情。我有一个简单的Rails 5应用程序,成功地通过开发Rails控制台使用sendgrid发送电子邮件,但是在heroku部署的生产Rails控制台中尝试相同的操作不会发送电子邮件,而是生成以下错误:

Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 25
from (irb):1

更多细节:

  • ruby 2.3.3
  • rails 5.1.3
  • gem 'sendgrid-ruby', '~> 5.0'

config/environment.rb

# Load the Rails application.
require_relative 'application'                                

# Initialize the Rails application.                           
Rails.application.initialize!                                 

Invoicer::Application.configure do 
  # Setup the mailer config                                   
  config.action_mailer.delivery_method = :smtp                
  config.action_mailer.perform_deliveries = true              
  config.action_mailer.smtp_settings = {
    :user_name => ENV['SENDGRID_USERNAME'],                   
    :password => ENV['SENDGRID_PASSWORD'],                    
    :domain => '[myapp].herokuapp.com',
    :address => 'smtp.sendgrid.net',                          
    :port => 587,
    :authentication => :plain,                                
    :enable_starttls_auto => true    
  }
end

config/environments/development.rb

唯一与电子邮件相关的未被注释的代码是:

# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false

config.action_mailer.perform_caching = false

config/environments/production.rb

唯一未被注释的与电子邮件相关的行是:

config.action_mailer.perform_caching = false

在我的本地开发环境中,会生成一封电子邮件。

在开发环境下的Rails控制台:

>> ActionMailer::Base.delivery_method
=> :smtp
>> InvoiceMailer.invoice_email(Customer.first).delivery_method
  Customer Load (0.6ms)  SELECT  "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT $1  [["LIMIT", 1]]
  Rendering invoice_mailer/invoice_email.html.erb within layouts/mailer
  Rendered invoice_mailer/invoice_email.html.erb within layouts/mailer (0.0ms)
  Rendering invoice_mailer/invoice_email.text.erb within layouts/mailer
  Rendered invoice_mailer/invoice_email.text.erb within layouts/mailer (0.0ms)
InvoiceMailer#invoice_email: processed outbound mail in 17.6ms
=> #<Mail::SMTP:0x007f939b607b48 @settings=    {:address=>"smtp.sendgrid.net", :port=>587, :domain=>"fm-    invoicer.herokuapp.com", :user_name=>"app75430225@heroku.com", :password=>"ms9nps8r7677", :authentication=>:plain, :enable_starttls_auto=>true, :openssl_verify_mode=>nil, :ssl=>nil, :tls=>nil}>

在Heroku生产环境中,我没有收到任何电子邮件并且出现了错误。

在Heroku Rails控制台中

$ heroku run rails c
Loading production environment (Rails 5.1.3)
irb(main):001:0> InvoiceMailer.invoice_email(Customer.first).deliver
D, [2017-09-03T14:59:53.803069 #4] DEBUG -- :Customer Load (7.2ms)      SELECT  "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT     $1  [["LIMIT", 1]]
I, [2017-09-03T14:59:53.863967 #4]  INFO -- :Rendering     invoice_mailer/invoice_email.html.erb within layouts/mailer
I, [2017-09-03T14:59:53.864680 #4]  INFO -- :Rendered invoice_mailer/invoice_email.html.erb within layouts/mailer (0.6ms)
I, [2017-09-03T14:59:53.865742 #4]  INFO -- :Rendering invoice_mailer/invoice_email.text.erb within layouts/mailer
I, [2017-09-03T14:59:53.866329 #4]  INFO -- :Rendered invoice_mailer/invoice_email.text.erb within layouts/mailer (0.4ms)
D, [2017-09-03T14:59:54.087932 #4] DEBUG -- : InvoiceMailer#invoice_email: processed outbound mail in 232.7ms
I, [2017-09-03T14:59:54.101584 #4]  INFO -- : Sent mail to XXX@gmail.com (13.4ms)
D, [2017-09-03T14:59:54.102047 #4] DEBUG -- : Date: Sun, 03 Sep 2017 14:59:54 +0000
From: XXX@gmail.com
To: XXX@gmail.com
Message-ID: <59ac18ea16bd6_451d0d888799@f74404ed-7ea9-41ff-9b05-715d2a185bf4.mail>
Subject: XXXXX Website Monthly Invoice - August-2017
Mime-Version: 1.0
Content-Type: multipart/alternative;
 boundary="--==_mimepart_59ac18ea151a7_451d0d8886dd";
 charset=UTF-8
Content-Transfer-Encoding: 7bit


----==_mimepart_59ac18ea151a7_451d0d8886dd
Content-Type: text/plain; 
 charset=UTF-8
Content-Transfer-Encoding: 7bit

Dear XXX

Attached please find your monthly invoice.

Best,
XXX
CrazyJ Media ;-)


----==_mimepart_59ac18ea151a7_451d0d8886dd
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <style>
      /* Email styles need to be inline */
    </style>
  </head>

  <body>
    <!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <p>Dear XXX,</p>
    <p>Attached please find the latest monthly invoice.</p>
    <p>Best,<br>XXX<br>Crazy J Media</p>
  </body>
</html>

  </body>
</html>

----==_mimepart_59ac18ea151a7_451d0d8886dd--

Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 25
    from (irb):1

在Heroku Rails控制台中也可以执行:

irb(main):001:0> ActionMailer::Base.delivery_method
=> :smtp
irb(main):002:0>     InvoiceMailer.invoice_email(Customer.first).delivery_method
D, [2017-09-13T22:42:58.951166 #4] DEBUG -- :   Customer Load (2.8ms)      SELECT  "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT     $1  [["LIMIT", 1]]
I, [2017-09-13T22:42:59.037206 #4]  INFO -- :   Rendering     invoice_mailer/invoice_email.html.erb within layouts/mailer
I, [2017-09-13T22:42:59.038316 #4]  INFO -- :   Rendered     invoice_mailer/invoice_email.html.erb within layouts/mailer (0.9ms)
I, [2017-09-13T22:42:59.039720 #4]  INFO -- :   Rendering  invoice_mailer/invoice_email.text.erb within layouts/mailer
I, [2017-09-13T22:42:59.040359 #4]  INFO -- :   Rendered invoice_mailer/invoice_email.text.erb within layouts/mailer (0.5ms)
D, [2017-09-13T22:42:59.413839 #4] DEBUG -- :     InvoiceMailer#invoice_email: processed outbound mail in 405.7ms
=> #<Mail::SMTP:0x0000000575c678 @settings={:address=>"localhost",   :port=>25, :domain=>"localhost.localdomain", :user_name=>nil, :password=>nil, :authentication=>nil, :enable_starttls_auto=>true, :openssl_verify_mode=>nil, :ssl=>nil, :tls=>nil}>

有人有什么想法吗?我已经研究了Heroku的sendgrid ruby文档以及几个SO问题和答案,比如这个,但都没有成功。我已经重新启动了我的heroku服务器,与此应用程序链接的sendgrid帐户正在工作并记录从开发中发送的电子邮件。

提前发送积极的善意给任何有洞察力的人!


好的,只是为了确保,您在您的Heroku控制面板中设置了SendGrid变量吗? - Rockwell Rice
非常确定,@RockwellRice。Heroku SendGrid插件与该应用程序相关联,已存储用户名和密码凭据。我能够通过应用程序的Heroku仪表板访问我的应用程序的SendGrid仪表板。 - BenU
你在开发环境中添加了 config.action_mailer.default_url_options = { :host => 'localhost:3000' },在生产环境中添加了 config.action_mailer.default_url_options = { :host => 'myapp.herokuapp.com' } 吗?虽然这只是一个猜测。 - Kruupös
你可以运行 ActionMailer::Base.delivery_methodActionMailer::Base.smtp_settings 来验证你的设置是否正确。如果它们没问题,那么检查邮件实例 InvoiceMailer.invoice_email(Customer.first).delivery_method 上的设置。然后你可以更新你的问题并附上结果。 - Michał Młoźniak
谢谢,@MichałMłoźniak,我已经更新了我的问题并提供了这些信息。现在也会尝试其他建议。 - BenU
2个回答

3
错误显示已经配置使用本地主机端口25的SMTP服务器发送电子邮件,这表明您的配置没有被使用!
当Rails.application.initialize!在生产中运行时,ActionMailer会被急加载并配置为使用它在那个时刻得到的设置。在您的情况下,看起来意味着它使用默认值,因为您自己的配置直到稍后才被设置。
您可以通过简单地在初始化应用程序之前设置配置来解决此问题;要么重新排序您的environment.rb以使配置首先发生,要么将ActionMailer配置移动到application.rb或环境特定配置(例如environments/production.rb)。

谢谢,@jpn。你诊断了问题并提供了解决方案。现在已经将配置代码移动到两个环境/production.rb和environments/development.rb中,可以在开发和生产中发送电子邮件。我会尝试在application.rb中只提供一次代码或在environment.rb中调整代码顺序,以使我的代码更加简洁。 - BenU

1
也许你应该将Action Mailer的配置移动到config/environments/production.rb中,或者检查是否有任何内容在此文件中覆盖了你的设置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接