Ruby:抄送地址的电子邮件丢失
Ruby: Emails go missing for Cc addresses
问题总结
当我尝试将地址包含到 CC 字段时,Ruby mailfactory
gem(或 Net::SMTP
)出现问题。我不确定我可能用错了两者中的哪一个。
两个 test/production 系统的 mailfactory
版本相同,但 Ruby 安装的版本不同。我正在使用 mailfactory (1.4.0)
。测试系统有ruby 2.1.2p95 (2014-05-08) [x86_64-linux-gnu]
,生产系统有ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
.
当前代码
这是我的 email-sending 函数中的代码:
mail = MailFactory.new
to_addr = 'to@domain.com'
cc_addr = ['cc1@domain.com', 'cc2@domain.com']
#
# ...ommitted for brevity...
#
mail.to = to_addr
mail.cc = cc_addr.join ';'
mail.from = 'from@domain.com'
mail.subject = "Subject here"
mail.text = "Some text here"
mail.html = "Some HTML text here"
Net::SMTP.start('smtp-host@domain.com', 25) do |smtp|
smtp.send_message(mail.to_s, mail.from.to_s, to_addr)
end
上面的代码有效,但只是部分有效。当我 运行 我的 测试 (并且只有 有时 )时,CC 列表中的那些人似乎会收到电子邮件,但是当代码 运行s in production,CC 列表中似乎没有人收到副本。 (我碰巧在 CC 列表中,但我从来没有得到过任何一个。)
我尝试了几种不同的方法,包括将 to_addr
和 cc_addr
连接成一个字符串,如下所示:
cc_addr << to_addr
Net::SMTP.start('smtp-host@domain.com', 25) do |smtp|
smtp.send_message(mail.to_s, mail.from.to_s, cc_addr.join(';'))
end
这也没有用。
我也试过使用mailfactory
的add_header
方法:
mail.add_header('To', to_addr)
mail.add_header('Cc', cc_addr.join(';'))
mail.add_header('From', "from@domain.com")
# etc...
这也没有用。 CC 列表中的地址不会收到消息(即使在曾经有效的测试环境中也不会)。事实上,即使 CC 包含单个字符串,它仍然不起作用。
其他观察结果
这里还有一些我直接观察到的东西:
当我 puts mail.to_s
到终端时,邮件 headers 似乎没问题(即我看到了地址,包括抄送 - 请参阅下面的示例);
当用户回复其中一封收到的电子邮件时,所有地址都清楚地列在抄送字段中,即使似乎没有人收到(至少我知道我没有收到) );
其他 non-Ruby 程序使用相同的 SMTP 服务器 (IT-managed) 发送电子邮件,包括抄送,没有问题;
程序 运行 运行正常(即没有出现警告或错误消息);
电子邮件地址有效,即使我曾经收到一个这样的地址的邮件发送通知失败(没有再看到,似乎是 IT 方面的 one-time 问题)
尝试将多个地址 join
放入 To:
字段中是行不通的。 (源代码似乎将 to
字段限制为 单个 地址。)
我已经检查过其他 references/examples,但它们非常简单,只关注单个 To:
、From:
等。因为这似乎对我有用,它们没有用。
Header 示例 1
这是真实的电子邮件 headers,由 puts mail.to_s
生成,地址和域出于显而易见的原因进行了编辑。
下面的headers是使用
制作的
mail.add_header('To:', 'to@domain.com')
mail.add_header('From:', 'from@domain.com')
mail.add_header('Cc:', 'cc1@domain.com')
...等等。输出是:
To: to@domain.com
From: from@domain.com
Cc: cc1@domain.com
Cc: cc2@domain.com
Reply-to: from@domain.com
Subject: The subject
Message-ID: <1455811642.9742095.1000.11119260@domain.com>
Date: Thu, 18 Feb 2016 08:07:22 -0800
MIME-Version: 1.0
Content-Type: multipart/alternative;boundary="----=_NextPart_APX_H3L1_qoWN58XIkVGr5SL_"
Header 示例 2
下面的headers是使用
制作的
mail.to = 'to@domain.com'
mail.cc = cc_addr.join ';'
...等等。他们制作了:
to: to@domain.com
cc: cc1@domain.com;cc2@domain.com
from: from@domain.com
subject: =?utf-8?Q?The_subject?=
Message-ID: <1455812736.522942.1000.7983900@domain.com>
Date: Thu, 18 Feb 2016 08:25:36 -0800
MIME-Version: 1.0
Content-Type: multipart/alternative;boundary="----=_NextPart_hTUHy..uLF3qVgnLqYEaQKd21"
headers中的不同大小写似乎没有什么区别。在这两种情况下,只有 To:
字段中列出的地址才能收到邮件。 Cc:
中的那些人没有。
问题
关于我可能在这里遗漏的任何想法?
我应该使用 mailfactory
吗? (最近注意到一些回购协议,他们的最后一次提交是在 8 年前……)
如果这是 deprecated/obsoleted,它的替代品是什么?我在哪里可以找到它 + docs/examples? (我没有找到对 mailfactory
...有意义的文档)
我是在使用 Net::SMTP
不正确还是只是遗漏了什么?
我一直在浏览其他几个库,我看到 mail
和 Pony
在不同的 SO post 中被建议,但我不确定我是否只是 运行 遇到同样的问题...
感谢帮助。
其他参考资料
我已经完成了其他 SO 问题,包括但不限于以下问题。我尝试了他们的一些建议,但它们似乎对我不起作用。
Ruby Net::SMTP - Send email with bcc: recipients
Email subject not correctly assigned with Ruby net/smtp
您最好使用 "actionmailer" 或 "mail" 宝石。两者都有很好的文档。
我最终放弃使用 mailfactory
来尝试 mail
,但我遇到了文档中未涵盖的问题。以下基于文档的示例:
Mail.defaults do
delivery_method :smtp, address: 'smtp.domain.com', port: 25
end
因 Net::SMTPServerBusy
异常而失败:
/usr/lib/ruby/2.1.0/net/smtp.rb:957:in `check_response': 450 4.7.1 <localhost.localdomain>: Helo command rejected: Service temporarily unavailable (Net::SMTPServerBusy)
出于某种原因,它坚持使用 localhost 而不是 address
键指定的指定服务器。对我来说,这看起来像是 mail (2.6.3)
中的错误...虽然我可能遗漏了一些东西。
相反,我不得不添加 :domain => 'domain.com'
对来解决这个问题,如下所示:
options = {
:address => 'smtp.domain.com',
:port => 25,
:domain => 'domain.com' # <<-- required
}
Mail.defaults do
delivery_method :smtp, options
end
This this SO post 对解决这个问题很有帮助。
EDIT-1: 虽然这在测试环境中确实有效,但生产环境仍然存在问题。完全解决后,我会更新此 post。
EDIT-2: 结果是 SMTP 服务器导致 Net::SMTPFatalError
异常,错误消息 Relay access denied
。我不确定为什么会这样,但这似乎是 IT 部门如何配置服务器的副作用。
相反,为了解决 Net::SMTPFatalError
我必须使用不同的内部 SMTP 服务器,该服务器已配置为允许将电子邮件中继到内部地址。
在昨天 运行 程序投入生产后,之前丢失的电子邮件开始按预期出现。
问题总结
当我尝试将地址包含到 CC 字段时,Ruby mailfactory
gem(或 Net::SMTP
)出现问题。我不确定我可能用错了两者中的哪一个。
两个 test/production 系统的 mailfactory
版本相同,但 Ruby 安装的版本不同。我正在使用 mailfactory (1.4.0)
。测试系统有ruby 2.1.2p95 (2014-05-08) [x86_64-linux-gnu]
,生产系统有ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
.
当前代码
这是我的 email-sending 函数中的代码:
mail = MailFactory.new
to_addr = 'to@domain.com'
cc_addr = ['cc1@domain.com', 'cc2@domain.com']
#
# ...ommitted for brevity...
#
mail.to = to_addr
mail.cc = cc_addr.join ';'
mail.from = 'from@domain.com'
mail.subject = "Subject here"
mail.text = "Some text here"
mail.html = "Some HTML text here"
Net::SMTP.start('smtp-host@domain.com', 25) do |smtp|
smtp.send_message(mail.to_s, mail.from.to_s, to_addr)
end
上面的代码有效,但只是部分有效。当我 运行 我的 测试 (并且只有 有时 )时,CC 列表中的那些人似乎会收到电子邮件,但是当代码 运行s in production,CC 列表中似乎没有人收到副本。 (我碰巧在 CC 列表中,但我从来没有得到过任何一个。)
我尝试了几种不同的方法,包括将 to_addr
和 cc_addr
连接成一个字符串,如下所示:
cc_addr << to_addr
Net::SMTP.start('smtp-host@domain.com', 25) do |smtp|
smtp.send_message(mail.to_s, mail.from.to_s, cc_addr.join(';'))
end
这也没有用。
我也试过使用mailfactory
的add_header
方法:
mail.add_header('To', to_addr)
mail.add_header('Cc', cc_addr.join(';'))
mail.add_header('From', "from@domain.com")
# etc...
这也没有用。 CC 列表中的地址不会收到消息(即使在曾经有效的测试环境中也不会)。事实上,即使 CC 包含单个字符串,它仍然不起作用。
其他观察结果
这里还有一些我直接观察到的东西:
当我
puts mail.to_s
到终端时,邮件 headers 似乎没问题(即我看到了地址,包括抄送 - 请参阅下面的示例);当用户回复其中一封收到的电子邮件时,所有地址都清楚地列在抄送字段中,即使似乎没有人收到(至少我知道我没有收到) );
其他 non-Ruby 程序使用相同的 SMTP 服务器 (IT-managed) 发送电子邮件,包括抄送,没有问题;
程序 运行 运行正常(即没有出现警告或错误消息);
电子邮件地址有效,即使我曾经收到一个这样的地址的邮件发送通知失败(没有再看到,似乎是 IT 方面的 one-time 问题)
尝试将多个地址
join
放入To:
字段中是行不通的。 (源代码似乎将to
字段限制为 单个 地址。)
我已经检查过其他 references/examples,但它们非常简单,只关注单个 To:
、From:
等。因为这似乎对我有用,它们没有用。
Header 示例 1
这是真实的电子邮件 headers,由 puts mail.to_s
生成,地址和域出于显而易见的原因进行了编辑。
下面的headers是使用
制作的mail.add_header('To:', 'to@domain.com')
mail.add_header('From:', 'from@domain.com')
mail.add_header('Cc:', 'cc1@domain.com')
...等等。输出是:
To: to@domain.com
From: from@domain.com
Cc: cc1@domain.com
Cc: cc2@domain.com
Reply-to: from@domain.com
Subject: The subject
Message-ID: <1455811642.9742095.1000.11119260@domain.com>
Date: Thu, 18 Feb 2016 08:07:22 -0800
MIME-Version: 1.0
Content-Type: multipart/alternative;boundary="----=_NextPart_APX_H3L1_qoWN58XIkVGr5SL_"
Header 示例 2
下面的headers是使用
制作的mail.to = 'to@domain.com'
mail.cc = cc_addr.join ';'
...等等。他们制作了:
to: to@domain.com
cc: cc1@domain.com;cc2@domain.com
from: from@domain.com
subject: =?utf-8?Q?The_subject?=
Message-ID: <1455812736.522942.1000.7983900@domain.com>
Date: Thu, 18 Feb 2016 08:25:36 -0800
MIME-Version: 1.0
Content-Type: multipart/alternative;boundary="----=_NextPart_hTUHy..uLF3qVgnLqYEaQKd21"
headers中的不同大小写似乎没有什么区别。在这两种情况下,只有 To:
字段中列出的地址才能收到邮件。 Cc:
中的那些人没有。
问题
关于我可能在这里遗漏的任何想法?
我应该使用
mailfactory
吗? (最近注意到一些回购协议,他们的最后一次提交是在 8 年前……)如果这是 deprecated/obsoleted,它的替代品是什么?我在哪里可以找到它 + docs/examples? (我没有找到对
mailfactory
...有意义的文档)我是在使用
Net::SMTP
不正确还是只是遗漏了什么?
我一直在浏览其他几个库,我看到 mail
和 Pony
在不同的 SO post 中被建议,但我不确定我是否只是 运行 遇到同样的问题...
感谢帮助。
其他参考资料
我已经完成了其他 SO 问题,包括但不限于以下问题。我尝试了他们的一些建议,但它们似乎对我不起作用。
Ruby Net::SMTP - Send email with bcc: recipients
Email subject not correctly assigned with Ruby net/smtp
您最好使用 "actionmailer" 或 "mail" 宝石。两者都有很好的文档。
我最终放弃使用 mailfactory
来尝试 mail
,但我遇到了文档中未涵盖的问题。以下基于文档的示例:
Mail.defaults do
delivery_method :smtp, address: 'smtp.domain.com', port: 25
end
因 Net::SMTPServerBusy
异常而失败:
/usr/lib/ruby/2.1.0/net/smtp.rb:957:in `check_response': 450 4.7.1 <localhost.localdomain>: Helo command rejected: Service temporarily unavailable (Net::SMTPServerBusy)
出于某种原因,它坚持使用 localhost 而不是 address
键指定的指定服务器。对我来说,这看起来像是 mail (2.6.3)
中的错误...虽然我可能遗漏了一些东西。
相反,我不得不添加 :domain => 'domain.com'
对来解决这个问题,如下所示:
options = {
:address => 'smtp.domain.com',
:port => 25,
:domain => 'domain.com' # <<-- required
}
Mail.defaults do
delivery_method :smtp, options
end
This this SO post 对解决这个问题很有帮助。
EDIT-1: 虽然这在测试环境中确实有效,但生产环境仍然存在问题。完全解决后,我会更新此 post。
EDIT-2: 结果是 SMTP 服务器导致 Net::SMTPFatalError
异常,错误消息 Relay access denied
。我不确定为什么会这样,但这似乎是 IT 部门如何配置服务器的副作用。
相反,为了解决 Net::SMTPFatalError
我必须使用不同的内部 SMTP 服务器,该服务器已配置为允许将电子邮件中继到内部地址。
在昨天 运行 程序投入生产后,之前丢失的电子邮件开始按预期出现。