Ruby 使用 SMTP 发送邮件

1. 开始前的准备

本章节中我们来讲解在 Ruby 如果使用 SMTP(简单邮件传输协议)来发送邮件,我们拿 163 邮箱来举例子。

首先需要我们注册一个163邮箱,然后开启 SMTP 服务。

服务器名称 时机简介(调用的时机) SSL协议端口号 非SSL协议端口号
IMAP 构造函数,创建新对象时 993 143
SMTP smtp.163.com 465/994 25
POP3 pop.163.com 995 110

从上图的表格中我们获取到:在 163 中 SMTP 服务器的地址为:smtp.163.com,非 SSL 协议的端口为:25。

2. 发送第一个邮件(纯文本)

我们会使用到Net::SMTP来发送邮件,这个库提供了通过 SMTP 方式发送邮件的功能。

邮件是有格式的,不符合格式的邮件是不能发送的,邮件的格式规定如下:

From: Your Name <your@mail.address>
To: Destination Address <someone@example.com>
Subject: test message
Date: Sat, 23 Jun 2001 16:26:43 +0900
Message-Id: <unique.message.id.string@example.com>

This is a test message.

根据要求现在让我们先来编辑一段邮件的内容:

sender_email = # 填写刚刚注册用来发送邮件的163账号
receiver_email = # 填写自己接收接收邮件的邮箱账号
sender_email_pwd = # 163邮件密码


msg = <<MESSAGE
From: Andrew <#{sender_email}>
To: Testuser <#{receiver_email}>
Subject: Test Message
Date: #{Time.now.strftime("%a, %d %b %Y %H:%M:%S +0800")}
Message-Id: <#{rand.to_s[3...8]}.message.@163.com>

This is a test message.
MESSAGE

puts msg

# ---- 输出结果 ----
From: Andrew <xxxx>
To: Testuser <xxxx>
Subject: Test Message
Date: Thu, 20 Aug 2020 23:21:34 +0800
Message-Id: <88888.message.@163.com>

然后我们需要使用Net::SMTP 中的start方法来发送这个邮件(邮件是有密码的)。并将我们刚才知道的邮件服务器地址和端口号添加到上面:

实例:

Net::SMTP.start('smtp.163.com', 25, '127.0.0.1', sender_email, sender_email_pwd) do |smtp|
  smtp.send_message msg,
    sender_email,
    receiver_email
  smtp.finish
end

# ---- 输出结果 ----
成功发送邮件~

运行成功后就会成功发送邮件到接收邮箱之中。

3. 发送HTML格式的邮件

如果我们要发送带有 CSS 样式的邮件,那么需要我们在 headers 中加入Content-type: text/html,并更改文件的内容:

msg = <<MESSAGE
From: Andrew <#{sender_email}>
To: Testuser <#{receiver_email}>
Subject: Test Message
Date: #{Time.now.strftime("%a, %d %b %Y %H:%M:%S +0800")}
Content-type: text/html 
Message-Id: <#{rand.to_s[3...8]}.message.@163.com>

<h1>测试标题</h1>
<p style="color: red;">测试这段话</p>

MESSAGE

puts msg

# ---- 输出结果 ---
From: Andrew <xxx.com>
To: Testuser <xxx.qq.com>
Subject: Test Message
Date: Thu, 20 Aug 2020 23:37:43 +0800
Content-type: text/html
Message-Id: <17402.message.@163.com>

<h1>测试标题</h1>
<p style="color: red;">测试这段话</p>

接收到邮件后,我们可以看到内容中的 CSS 已经生效了。

4. 发送带有附件的邮件

让我们先创建一个 txt 文件作为附件。

echo "这是一个测试的txt文件" > test.txt

然后让我再次修改 headers,增加Content-type: multipart/mixed

注意事项:

我们需要使用 pack(“m”) 将函数转化为 base64 格式的。

filename = File.expand_path(File.dirname(__FILE__) + "/test.txt")
encodedcontent = [File.read(filename)].pack("m")

msg = <<MESSAGE
From: Andrew <#{sender_email}>
To: Testuser <#{receiver_email}>
Subject: Test Upload File/mi
Date: #{Time.now.strftime("%a, %d %b %Y %H:%M:%S +0800")}
Message-Id: <#{rand.to_s[3...8]}.message.@163.com>
Content-Transfer-Encoding:8bit
Content-Type: multipart/mixed; name="#{filename}"
Content-Transfer-Encoding:base64
Content-Disposition: attachment; filename="#{filename}"

#{encodedcontent}
MESSAGE

puts msg 

改好即可。

5. 小结

本章节中我们学习了如何使用 SMTP 来发送纯文本、HTML、附件的邮件。