Ruby 发送邮件 – SMTP
在 Ruby 中,通过 SMTP(Simple Mail Transfer Protocol) 发送电子邮件是一个常见需求。Ruby 提供了内置的 net/smtp
库来实现 SMTP 邮件发送,简单高效,适合发送纯文本、HTML 或带附件的邮件。以下是对 Ruby 使用 SMTP 发送邮件的中文讲解,涵盖核心功能、配置、发送邮件的步骤、示例代码及注意事项,力求简洁清晰。
1. SMTP 简介
SMTP 是用于发送电子邮件的标准协议。Ruby 的 net/smtp
库允许通过 SMTP 服务器(如 Gmail、SendGrid)发送邮件,支持身份验证、TLS/SSL 加密等功能。
特点:
- 轻量,直接与 SMTP 服务器交互。
- 支持多种邮件格式(文本、HTML、附件)。
- 需要 SMTP 服务器的配置信息(如主机、端口、用户名、密码)。
2. 安装与准备
net/smtp
是 Ruby 标准库的一部分,无需额外安装。直接在代码中引入:
require 'net/smtp'
先决条件:
- SMTP 服务器:如 Gmail、SendGrid 或企业邮箱服务器。
- 账户信息:需要 SMTP 服务器的主机地址、端口、用户名和密码。
- Gmail 示例:
- 主机:
smtp.gmail.com
- 端口:587(TLS)或 465(SSL)
- 用户名:你的 Gmail 地址
- 密码:应用专用密码(需启用两步验证后生成,详见注意事项)。
- 主机:
3. 发送简单邮件
使用 Net::SMTP
类直接发送邮件,需要构造符合 SMTP 协议的邮件内容。
基本示例
require 'net/smtp'
# 邮件内容
message = <<~MESSAGE
From: Sender Name <sender@example.com>
To: Receiver Name <receiver@example.com>
Subject: Test Email
This is a test email sent from Ruby!
MESSAGE
# SMTP 配置
smtp = Net::SMTP.new('smtp.gmail.com', 587)
smtp.enable_starttls # 启用 TLS
smtp.start('gmail.com', 'sender@example.com', 'your_app_password', :login) do |smtp|
smtp.send_message(message, 'sender@example.com', 'receiver@example.com')
end
说明:
Net::SMTP.new(host, port)
:创建 SMTP 连接。enable_starttls
:启用 TLS 加密(Gmail 要求)。start(domain, user, password, auth_type)
:启动 SMTP 会话,auth_type
通常为:login
。send_message(message, from, to)
:发送邮件,message
是格式化的邮件内容。
4. 发送复杂邮件(HTML、附件)
对于 HTML 邮件或带附件的邮件,需要构造 MIME 格式的邮件内容。推荐使用 mail
库(需安装 gem install mail
),它是对 net/smtp
的封装,简化复杂邮件的处理。
安装 Mail 库
gem install mail
发送 HTML 邮件
require 'mail'
Mail.defaults do
delivery_method :smtp, {
address: 'smtp.gmail.com',
port: 587,
domain: 'gmail.com',
user_name: 'sender@example.com',
password: 'your_app_password',
authentication: :login,
enable_starttls_auto: true
}
end
mail = Mail.new do
from 'sender@example.com'
to 'receiver@example.com'
subject 'Test HTML Email'
html_part do
content_type 'text/html; charset=UTF-8'
body '<h1>Hello!</h1><p>This is an <b>HTML</b> email sent from Ruby.</p>'
end
end
mail.deliver
说明:
Mail.defaults
:设置全局 SMTP 配置。html_part
:定义 HTML 内容部分。deliver
:发送邮件。
发送带附件的邮件
require 'mail'
Mail.defaults do
delivery_method :smtp, {
address: 'smtp.gmail.com',
port: 587,
user_name: 'sender@example.com',
password: 'your_app_password',
authentication: :login,
enable_starttls_auto: true
}
end
mail = Mail.new do
from 'sender@example.com'
to 'receiver@example.com'
subject 'Email with Attachment'
text_part { body 'See the attached file.' }
add_file 'path/to/file.pdf' # 添加附件
end
mail.deliver
说明:
text_part
:添加纯文本部分(多部分邮件)。add_file
:添加附件,文件路径需有效。
5. 异常处理
发送邮件可能因网络、认证失败等原因抛出异常,需妥善处理。
require 'net/smtp'
begin
smtp = Net::SMTP.new('smtp.gmail.com', 587)
smtp.enable_starttls
smtp.start('gmail.com', 'sender@example.com', 'wrong_password', :login) do |smtp|
smtp.send_message("From: sender@example.com\nTo: receiver@example.com\nSubject: Test\n\nHello!", 'sender@example.com', 'receiver@example.com')
end
rescue Net::SMTPAuthenticationError => e
puts "认证失败: #{e.message}"
rescue Net::SMTPServerBusy => e
puts "服务器忙: #{e.message}"
rescue => e
puts "其他错误: #{e.message}"
end
常见异常:
Net::SMTPAuthenticationError
:用户名或密码错误。Net::SMTPServerBusy
:服务器拒绝连接。Errno::ECONNREFUSED
:无法连接到 SMTP 服务器。
6. 注意事项
- Gmail 应用专用密码:
- Gmail 要求两步验证,需生成应用专用密码:
- 登录 Google 账户 → 安全 → 两步验证 → 应用专用密码。
- 生成密码(如
abcd efgh ijkl mnop
),用于password
参数。
- 编码:邮件内容默认 UTF-8,确保 SMTP 服务器支持。
- 安全性:
- 使用
enable_starttls
或enable_starttls_auto
确保加密传输。 - 不要硬编码密码,推荐使用环境变量:
ruby password = ENV['SMTP_PASSWORD']
- 性能:
net/smtp
适合简单任务,大量邮件发送推荐使用邮件服务(如 SendGrid)或队列(如 Sidekiq)。 - 调试:
- 启用调试输出:
ruby smtp = Net::SMTP.new('smtp.gmail.com', 587) smtp.set_debug_output($stderr)
- 检查邮件服务器日志或服务商控制台。
- 现代替代:Rails 的 Action Mailer 或
mail
库提供更高级的功能,简化复杂邮件处理。
7. 综合示例
以下示例结合 mail
库发送带附件和 HTML 内容的邮件,包含错误处理。
require 'mail'
Mail.defaults do
delivery_method :smtp, {
address: 'smtp.gmail.com',
port: 587,
domain: 'gmail.com',
user_name: 'sender@example.com',
password: ENV['SMTP_PASSWORD'] || 'your_app_password',
authentication: :login,
enable_starttls_auto: true
}
end
begin
mail = Mail.new do
from 'sender@example.com'
to 'receiver@example.com'
subject 'Welcome Email'
text_part { body 'This is a plain text version.' }
html_part do
content_type 'text/html; charset=UTF-8'
body '<h1>Welcome!</h1><p>This is an <b>HTML</b> email.</p>'
end
add_file 'example.pdf' # 假设文件存在
end
mail.deliver
puts "邮件发送成功"
rescue StandardError => e
puts "发送失败: #{e.message}"
end
功能:
- 发送包含文本和 HTML 部分的邮件。
- 添加附件(
example.pdf
)。 - 使用环境变量存储密码,增强安全性。
8. 总结
Ruby 的 net/smtp
库提供了直接的 SMTP 邮件发送功能,适合简单邮件任务。结合 mail
库,可以轻松发送 HTML 邮件和附件,支持 TLS 加密和身份验证。注意配置正确的 SMTP 参数(如 Gmail 的应用专用密码),使用异常处理确保健壮性,优先选择 mail
库简化复杂邮件处理。现代应用可结合 Rails 的 Action Mailer 或第三方服务(如 SendGrid)提升效率。
如果你需要更复杂的功能(如批量发送、邮件模板)或有其他问题,请告诉我!