TranslateProject/sources/tech/20190808 Sending custom emails with Python.md

13 KiB
Raw Blame History

使用Python发送定制邮件

Mailmerge是一个可以处理简单邮件和复杂邮件的命令行程序可以用它定制组邮件。 Chat via email

电子邮件还是生活的一部分,尽管有种种不足,它仍然是大多数人发送信息的最佳方式,尤其是在以自动化方式实现受众信息队列的场景。

我作为Fedora社区行动和影响协调员 的工作之一就是给人们发送旅行基金相关的好消息,我经常通过电子邮件做这些事。这里,我将给你展示如何使用Mailmerge,一个可以处理简单邮件及复杂邮件的命令行程序,向一组人发送定制信息。

安装 Mailmerge

在Fedora中Mailmerge已经打包可用你可以通过在命令行中运行sudo dnf install python3-mailmerge来安装它。你还可以使用pip命令从PyPi中安装具体可以参阅该项目的说明

配置 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][5],"Myself",17
[bob@bobdomain.com][6],"Bob",42

你可以使用他们的名字,给这两个人发送邮件,并各告诉他们一个数字。这个示例文件虽然不是特别有趣,但应用了一个重要的原则,那就是:始终让自己处于邮件接收列表的首位。这样你可以在向列表全员发送邮件之前,先给自己发送一个测试邮件,以验证邮件的效果是否如你预期。

任何包含半角逗号的值,都 必须 以半角双引号(")封闭。如果恰好在半角双引号封闭的区域需要有一个半角双引号,那就在同一行中使用两个半角双引号。引用的定义规则比较有趣,去Python3中的CSV一探究竟吧。

Template.txt

我的工作之一就是向Fedora贡献者协会发送与旅行基金有关的信息Flock。通过简单的邮件告诉有关的人,他被选中为旅行基金支持的幸运者,以及相应基金支持的详细信息。与接收者相关的具体信息之一就是我们可以为他的旅行提供多少资助。下面是一份我的节略后的模板文件(为了简洁,已经移除大量的文本):

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

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][9],1000
PersonA,[persona@fedoraproject.org][10],1500
PèrsonB,[personb@fedoraproject.org][11],500

注意我把自己放在了第一个这是为了测试方便。除了我还有另外两个人的信息在文档中。列表中的第二个人PèrsonB他的名字中有一个包含变音符号的字母Mailmerge会对这类字母自动编码。

以上包含了模板的全部知识点:写上你自己的电子邮件信息,并编写好以双大括弧封闭的占位符。接下来创建用来提供前述占位符具体值的数据文件。现在测试一下电子邮件的效果。

测试并发送简单邮件

试运行

测试从邮件的试运行开始,试运行就是讲邮件内容显示出来,所有的占位符都会被具体值取代。默认情况下,如果你运行不带参数的命令mailmerge,它将对收件列表中的第一个人进行试运行:

$ mailmerge
>>> encoding ascii
>>> message 0
TO: [bexelbie@redhat.com][9]
SUBJECT: Flock 2019 Funding Offer
FROM: Brian Exelbierd <[bexelbie@redhat.com][9]>
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条信息和计算机中很多计数场景一样计数从0开始),可以看到我的名字及旅行预算是正确的。如果你想检视所有的邮件,运行mailmerge --no-limit告诉Mailmerge不要仅仅处理第一个收件人的信息。下面是第三个收件人邮件的试运行结果用来测试特殊字符的编码

>>> message 2
TO: [personb@fedoraproject.org][11]
SUBJECT: Flock 2019 Funding Offer
FROM: Brian Exelbierd <[bexelbie@redhat.com][9]>
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-runMailmerge将向收件人列表中的第一个人发送电子邮件:

$ mailmerge --no-dry-run
>>> encoding ascii
>>> message 0
TO: [bexelbie@redhat.com][9]
SUBJECT: Flock 2019 Funding Offer
FROM: Brian Exelbierd <[bexelbie@redhat.com][9]>
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][9]
>>>   security = STARTTLS
>>> password for [bexelbie@redhat.com][9] 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.

倒数第4行它将要求你输入你的密码。如果你使用的是双因素认证或者域控制登录那就需要创建应用密码来绕过这些控制。如果你使用的是Gmail或者类似的系统可以直接在界面上完成密码验证。如果不行的话联系你的邮件系统管理员。 虽然这些步骤不会影响邮件系统的安全性,但是仍然有必要使用复杂的安全性好的密码。

我在我的邮件收件箱中,看到了这封格式美观的测试邮件。如果测试邮件看起来没有问题,那就可以运行mailmerge --no-dry-run --no-limit发送所有的邮件了。

发送复杂邮件

只有充分了解了Jinja2 templating你才可能充分领略Mailmerge真正的威力。在邮件模板中使用条件语句及附带附件是很有用的。下面就是一个复杂邮件的模板及对应的数据文件

$ cat mailmerge_template.txt
TO: {{Email}}
SUBJECT: Flock 2019 Funding Offer
FROM: Brian Exelbierd <[bexelbie@redhat.com][9]>
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][9],1000,Yes,visa_bex.pdf
PersonA,[persona@fedoraproject.org][10],1500,No,visa_person_a.pdf
PèrsonB,[personb@fedoraproject.org][11],500,Yes,visa_person_b.pdf

在这个邮件中有两项新内容。首先是附件我需要向参加国际旅行的人发送签证邀请信帮助他们来Flock文件头的附件部分说明了要包含什么文件;为了保持我的文档目录清晰,我将所以的所有需要作为附件的文档保存于附件子目录下。其次是包含了关于宾馆的条件信息,因为有些人的旅行资金包含了住宿费用,我需要对涉及住宿的人员诉及相关信息,而这是通过if判断实现的:

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

这和大多数编程语言中的if判断是一样的。Jinja2实力非凡可以实现多级判断。通过包含数据元素控制邮件内容能大大简化相关的日常工作。空格的正确使用对邮件的易读性很重要。ifendif语句中的短线(-)是Jinja2控制符的一部分whitespace。这里面选项很多,所以还是要通过试验找到最适合自己的方式。

在上面的例子中,我在数据文件扩充了HotelFile两个字段这些字段的值控制着宾馆信息和附件文件名。另外在上例中我和PèrsonB有住宿资助但PersonA没有。

对于简单邮件和复杂邮件而言,试运行及正式发送邮件的操作都是相同的。快去试试吧!

你还可以尝试在邮件头中使用条件判断(ifendif),比如你可以使发送给在数据库中的某人的邮件包含附件,或者改变对部分人改变发送人的信息。

Mailmerge的优点

Mailmerge是用来批量发送个性化邮件的简洁而高效的工具。每个人只接受到他需要的信息其它额外的操作和细节都是透明的。

我还发现即使是在发送简单的集团邮件时相对于使用CC或者BCC向一组受众发送一封邮件采用Mailmerge也是非常高效的。很多人使用了邮件过滤那些不是直接发给他们的邮件他们一律不会立刻处理。使用Mailmerge保证了每名受众接收到的就是自己的邮件。所有的信息会对接收者进行正确过滤再也不会有人无意间回复到整个邮件组。


via: https://opensource.com/article/19/8/sending-custom-emails-python

作者:Brian "bex" Exelbierd 选题:lujun9972 译者:silentdawn-zz 校对:校对者ID

本文由 LCTT 原创编译,Linux中国 荣誉推出