使用 Python 发送自定义电子邮件

使用 Mailmerge(一个命令行程序,可以处理简单和复杂的电子邮件)自定义您的群发邮件。
115 位读者喜欢这篇文章。
Chat via email

电子邮件仍然是生活的一部分。 尽管它有缺点,但它仍然是向大多数人发送信息的最佳方式,尤其是在允许消息为收件人排队的自动化方式中。

作为 Fedora 社区行动和影响协调员,我的工作亮点之一是为人们带来关于旅行资助的好消息。 我经常通过电子邮件发送这些信息。 在这里,我将向您展示如何使用 Mailmerge(一个命令行 Python 程序,可以处理简单和复杂的电子邮件)向人群发送自定义消息。

安装 Mailmerge

Mailmerge 已打包并在 Fedora 中提供,您可以使用命令 sudo dnf install python3-mailmerge 从命令行安装它。 您也可以使用 pip 从 PyPI 安装它,正如该项目的 README 解释

配置您的 Mailmerge 文件

三个文件控制 Mailmerge 的工作方式。 如果您运行 mailmerge --sample,它将为您创建模板文件。 这些文件是

  • mailmerge_server.conf: 这包含用于 SMTP 主机发送电子邮件的配置详细信息。 您的密码存储在此文件中。
  • mailmerge_database.csv: 这保存了每封电子邮件的自定义数据,包括收件人的电子邮件地址。
  • mailmerge_template.txt: 这是您的电子邮件文本,其中包含占位符字段,这些字段将使用来自 mailmerge_database.csv 的数据进行替换。

Server.conf

示例 mailmerge_server.conf 文件包含几个您应该熟悉的示例。 如果您曾经将电子邮件添加到您的手机或设置桌面电子邮件客户端,您以前见过此数据。 要记住的大事是在文件中更新您的用户名,特别是如果您正在使用示例配置之一。

Database.csv

mailmerge_database.csv 文件有点复杂。 它必须包含(至少)收件人的电子邮件地址以及替换电子邮件中字段所需的任何其他自定义详细信息。 最好在您为此文件创建字段列表的同时编写 mailmerge_template.txt 文件。 我发现使用电子表格捕获此数据并在完成后将其导出为 CSV 文件很有帮助。 此示例文件

email,name,number
myself@mydomain.com,"Myself",17
bob@bobdomain.com,"Bob",42

允许您向两个人发送电子邮件,使用他们的名字并告诉他们一个数字。 此文件虽然不是很有趣,但说明了一个重要的习惯:始终将自己作为文件中的第一个收件人。 这使您可以向自己发送测试电子邮件,以在您向整个列表发送电子邮件之前验证一切是否按预期工作。

如果您的任何值包含逗号,则必须将整个值用双引号 (") 括起来。 如果您需要在双引号字段中包含双引号,请连续使用两个双引号。 引用规则很有趣,因此请阅读 Python 3 中的 CSV 以了解具体信息。

Template.txt

作为我工作的一部分,我可以分享关于我们 Fedora 贡献者会议 Flock 的旅行资助决定的消息。 一封简单的电子邮件告诉人们他们已被选中获得旅行资助以及他们的具体资助详情。 一个用户特定的细节是我们可以为他们的机票分配多少钱。 这是我的模板文件的缩写版本(为了简洁起见,我删减了很多文本)

$ cat mailmerge_template.txt
TO: {{Email}}
SUBJECT: Flock 2019 Funding Offer
FROM: Brian Exelbierd <bexelbie@redhat.com>


Hi {{Name}},


I am writing you on behalf of the Flock funding committee.  You requested funding for your attendance at Flock.  After careful consideration we are able to offer you the following funding:


Travel Budget: {{Travel_Budget}}


<<snip>>

模板的顶部指定收件人、发件人和主题。 在空行之后,是电子邮件的正文。 此电子邮件需要来自 database.csv 文件的收件人的 EmailNameTravel_Budget。 请注意,这些字段用双花括号 ({{}}) 括起来。 相应的 mailmerge_database.csv 看起来像这样

$ cat mailmerge_database.csv
Name,Email,Travel_Budget
Brian,bexelbie@redhat.com,1000
PersonA,persona@fedoraproject.org,1500
PèrsonB,personb@fedoraproject.org,500

请注意,我首先列出了自己(用于测试),文件中还有另外两个人。 第二个人 PèrsonB 的名字中有一个重音字符;Mailmerge 将自动对其进行编码。

这就是整个模板概念:编写您的电子邮件并将占位符放在双花括号中。 然后创建一个提供这些值的数据库。 现在让我们测试电子邮件。

测试和发送简单的邮件合并

进行模拟运行

首先进行模拟运行,将完成占位符字段的电子邮件打印到屏幕上。 默认情况下,如果您运行命令 mailmerge,它将对第一封电子邮件进行模拟运行

$ mailmerge
>>> encoding ascii
>>> message 0
TO: bexelbie@redhat.com
SUBJECT: Flock 2019 Funding Offer
FROM: Brian Exelbierd <bexelbie@redhat.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Date: Sat, 20 Jul 2019 18:17:15 -0000


Hi Brian,


I am writing you on behalf of the Flock funding committee.  You requested funding for your attendance at Flock.  After careful consideration we are able to offer you the following funding:


Travel Budget: 1000


<<snip>>


>>> sent message 0 DRY RUN
>>> No attachments were sent with the emails.
>>> Limit was 1 messages.  To remove the limit, use the --no-limit option.
>>> This was a dry run.  To send messages, use the --no-dry-run option.

查看第一封电子邮件(消息 0,因为计数从零开始,就像计算机科学中的许多事物一样),您可以看到我的姓名和旅行预算是正确的。 如果您想查看每封电子邮件,请输入 mailmerge --no-limit 以告诉 Mailmerge 不要将自己限制为第一封电子邮件。 这是第三封电子邮件的模拟运行,显示了特殊字符编码

>>> message 2
TO: personb@fedoraproject.org
SUBJECT: Flock 2019 Funding Offer
FROM: Brian Exelbierd <bexelbie@redhat.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Date: Sat, 20 Jul 2019 18:22:48 -0000


Hi P=E8rsonB,

那不是错误;P=E8rsonBPèrsonB 的编码形式。

发送测试消息

现在,使用命令 mailmerge --no-dry-run 发送测试电子邮件,该命令告诉 Mailmerge 向列表中的第一封电子邮件发送消息

$ mailmerge --no-dry-run
>>> encoding ascii
>>> message 0
TO: bexelbie@redhat.com
SUBJECT: Flock 2019 Funding Offer
FROM: Brian Exelbierd <bexelbie@redhat.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Date: Sat, 20 Jul 2019 18:25:45 -0000


Hi Brian,


I am writing you on behalf of the Flock funding committee.  You requested funding for your attendance at Flock.  After careful consideration we are able to offer you the following funding:


Travel Budget: 1000


<<snip>>


>>> Read SMTP server configuration from mailmerge_server.conf
>>>   host = smtp.gmail.com
>>>   port = 587
>>>   username = bexelbie@redhat.com
>>>   security = STARTTLS
>>> password for bexelbie@redhat.com on smtp.gmail.com: 
>>> sent message 0
>>> No attachments were sent with the emails.
>>> Limit was 1 messages.  To remove the limit, use the --no-limit option.

在倒数第四行,您可以看到它提示您输入密码。 如果您使用双重身份验证或域管理登录,您将需要创建一个应用程序密码来绕过这些控件。 如果您使用 Gmail 和类似系统,您可以直接从界面执行此操作;否则,请联系您的电子邮件系统管理员。 这不会损害您的电子邮件系统的安全性,但您仍应保持密码的复杂性和保密性。

当我检查我的电子邮件帐户时,我收到了一封格式精美的测试电子邮件。 如果您的测试电子邮件看起来已准备就绪,请输入 mailmerge --no-dry-run --no-limit 发送所有电子邮件。

发送复杂的电子邮件

当您利用 Jinja2 模板时,您真的可以看到 Mailmerge 的强大功能。 我发现它对于包含条件文本和发送附件很有用。 这是一个复杂的模板和相应的数据库

$ cat mailmerge_template.txt
TO: {{Email}}
SUBJECT: Flock 2019 Funding Offer
FROM: Brian Exelbierd <bexelbie@redhat.com>
ATTACHMENT: attachments/{{File}}


Hi {{Name}},


I am writing you on behalf of the Flock funding committee.  You requested funding for your attendance at Flock.  After careful consideration we are able to offer you the following funding:


Travel Budget: {{Travel_Budget}}
{% if Hotel == "Yes" -%}
Lodging: Lodging in the hotel Wednesday-Sunday (4 nights)
{%- endif %}


<<snip>>


$ cat mailmerge_database.csv
Name,Email,Travel_Budget,Hotel,File
Brian,bexelbie@redhat.com,1000,Yes,visa_bex.pdf
PersonA,persona@fedoraproject.org,1500,No,visa_person_a.pdf
PèrsonB,personb@fedoraproject.org,500,Yes,visa_person_b.pdf

此电子邮件中有两件新事物。 首先,有一个附件。 我必须向国际旅行者发送签证邀请函,以帮助他们来参加 Flock,并且标头的 ATTACHMENT 部分指定要附加的文件。 为了保持我的目录清洁,我将所有附件都放在我的 Attachments 子目录中。 其次,它包括关于酒店的条件信息,因为有些人收到酒店住宿的资助,我需要为那些获得资助的人包括这些详细信息。 这是通过 if 结构完成的

{% if Hotel == "Yes" -%}
Lodging: Lodging in the hotel Wednesday-Sunday (4 nights)
{%- endif %}

这就像大多数编程语言中的 if 一样工作。 Jinja2 非常具有表现力,可以进行多级条件处理。 通过包含控制电子邮件内容的数据库元素,尝试使您的生活更轻松。 使用空格对于电子邮件的可读性很重要。 ifendif 中的减号 (-) 符号是 Jinja2 控制 空格 方式的一部分。 有很多选项,所以请尝试看看哪种最适合您。

另请注意,我使用两个字段 HotelFile 扩展了数据库。 这些是控制酒店文本包含并提供附件名称的值。 在我的示例中,PèrsonB 和我获得了酒店资助,而 PersonA 没有。

无论您使用的是简单模板还是复杂模板,进行模拟运行和发送电子邮件都是相同的。 试试看!

您还可以尝试在标头中使用条件语句 (ifendif)。 例如,您可以仅在数据库中存在附件时才拥有附件,或者您可能需要更改某些电子邮件的发件人姓名,而不是其他电子邮件。

Mailmerge 的优势

Mailmerge 程序提供了一种强大而简单的方法来发送大量自定义电子邮件。 每个人都只获得他们需要的信息,并且省略了无关的步骤和细节。

即使对于简单的群组电子邮件,我也发现这种方法比使用抄送或密件抄送向一群人发送一封电子邮件有效得多。 很多人会过滤他们的电子邮件并延迟阅读任何未直接发送给他们的邮件。 使用 Mailmerge 确保每个人都收到自己的电子邮件。 消息将为收件人正确过滤,并且没有人可以意外地“全部回复”给整个组。

标签
User profile image.
Brian “bex” Exelbierd 是 RHEL 社区业务负责人,致力于通过社区努力为 RHEL 路线图提供信息,并支持操作系统社区。在红帽,Brian 曾担任技术作家、软件工程师、内容策略师、社区架构师,现在担任产品经理。

1 条评论

感谢您撰写关于 Python 中 mailmerge 的深入文章。解释得非常清楚。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.