Ruby SMTP脚本收件地址不存在未收到退信,求差异原因
我写了一个简单的Ruby邮件发送脚本,正常发送邮件时功能没问题,但收件地址不存在时,收不到SMTP服务器的投递失败通知。用Thunderbird发相同邮件却能正常收到失败通知,请问这是什么原因?
require 'json' require 'date' require 'net/http' require 'mail' class Email attr_accessor :subject, :attachments def initialize() @to = "test@testtest12121.com" @subject = "Test" @from = "myemail" end def send() Mail.defaults do delivery_method :smtp, { address: "server", port: 465, user_name: "user", password: "password", authentication: "plain", ssl: true, enable_starttls_auto: true } end mail = Mail.new mail.from = @from mail.to = @to mail.subject = @subject mail.body = "test" mail.charset = 'UTF-8' mail.message_id = @from mail.return_path = @from mail['Organization'] = "Company Name" begin mail.deliver! puts "Email was sent successfully." rescue Net::SMTPAuthenticationError => e puts "Authentifizierungsfehler: #{e.message}" exit(1) rescue Net::SMTPServerBusy => e puts "The SMTP server is currently busy: #{e.message}" exit(1) rescue Net::SMTPUnknownError => e puts "Unknown error when sending the e-mail: #{e.message}" exit(1) rescue => e puts "An error has occurred: #{e.message}" exit(1) end end end mail = Email.new mail.send
核心原因分析
你的脚本里有两个关键设置导致收不到退信通知:
错误的
message_id设置mail.message_id = @from这行把邮件的唯一标识Message-ID设成了发件人邮箱地址,不符合邮件标准。正常的Message-ID应该是包含随机字符串和域名的唯一值(比如<random-string@your-domain.com>)。收件方服务器处理退信时,需要通过合法的Message-ID关联原邮件,错误的格式会导致退信无法正确路由回你。return_path与发件人格式问题
你设置的@from只是用户名而非完整邮箱地址(比如应该是myemail@your-domain.com而非myemail),即使指定了return_path = @from,退信服务器也无法识别这个不完整的地址,导致退信无法送达。另外,结合错误的Message-ID,部分SMTP服务器会判定邮件格式不规范,直接丢弃退信。
修复方案
删除自定义的
message_id设置
删掉mail.message_id = @from这行,Ruby的mail库会自动生成符合RFC标准的唯一Message-ID,确保退信能正确关联原邮件。使用完整的发件人邮箱地址
将@from修改为完整的邮箱格式,比如myemail@your-domain.com,return_path可以保持和from一致,或者直接省略该设置(mail库会默认用from地址作为退信地址)。
调整后的关键代码片段:
mail = Mail.new mail.from = "myemail@your-domain.com" # 改为完整邮箱地址 mail.to = @to mail.subject = @subject mail.body = "test" mail.charset = 'UTF-8' # 移除mail.message_id = @from # 可选:保留或删除mail.return_path = @from,库会自动处理 mail['Organization'] = "Company Name"
修改后,当收件地址不存在时,SMTP服务器就能正确生成退信并发送到你的发件邮箱。
内容的提问来源于stack exchange,提问作者Paul Muaddib

