使用Mailmerge發(fā)送定制郵件
Mailmerge 是一個(gè)可以定制群發(fā)郵件的命令行程序,它可以處理簡單和復(fù)雜的郵件。
電子郵件還是生活的一部分,盡管有種種不足,它仍然是大多數(shù)人發(fā)送信息的最佳方式,尤其是在按隊(duì)列將郵件發(fā)送給收件人的自動化方式中。
作為 Fedora 社區(qū)行動和影響協(xié)調(diào)員,我的工作之一就是給人們發(fā)送資助旅行相關(guān)的好消息,我經(jīng)常通過電子郵件做這些事。這里,我將給你展示如何使用 Mailmerge 向一群人發(fā)送定制郵件的,Mailmerge 是一個(gè)可以處理簡單和復(fù)雜的郵件的命令行程序。
安裝 Mailmerge
在 Fedora 中,Mailmerge 已經(jīng)打包可用,你可以通過在命令行中運(yùn)行 sudo dnf install python3-mailmerge 來安裝它。你還可以使用 pip 命令從 PyPi 中安裝,具體可以參閱該項(xiàng)目的 README。
配置 Mailmerge
三個(gè)配置文件控制著 Mailmerge 的工作模式。運(yùn)行 mailmerge --sample,將生成配置文件模板。這些文件包括:
mailmerge_server.conf:這里保存著 SMTP 服務(wù)端郵件發(fā)送相關(guān)詳細(xì)配置,但你的密碼 不 在這里保存。mailmerge_database.csv:這里保存每封郵件的定制數(shù)據(jù),包括收件人的電子郵件地址。mailmerge_template.txt:這里保存電子郵件的文本,文本中包含占位符,這些占位符會使用mailmerge_database.csv中的數(shù)據(jù)替換。
Server.conf
配置模板文件 mailmerge_server.conf 包含幾個(gè)大家應(yīng)該很熟悉的例子。如果你曾經(jīng)往手機(jī)上添加過電子郵件或者設(shè)置過桌面電子郵件客戶端,那你就應(yīng)該看到過這些數(shù)據(jù)。需要提醒的是要記得把你的用戶名更新到這個(gè)文件中,尤其是在你使用模板所提供的配置時(shí)。
Database.csv
mailmerge_database.csv 這個(gè)配置文件稍微有點(diǎn)復(fù)雜。最起碼要將郵件接收者的電子郵件地址保存在這里,其它在電子郵件中任何需要替換的定制信息也要保存在這里。推薦在創(chuàng)建本文件的占位符列表時(shí),同步編輯 mailmerge_template.txt 文件。我發(fā)現(xiàn)一個(gè)有效的做法是,使用電子表格軟件錄入這些數(shù)據(jù),完成后導(dǎo)出為 CSV 文件。使用下面的示例文件:
email,name,numbermyself@mydomain.com,"Myself",17bob@bobdomain.com,"Bob",42
可以你向這兩個(gè)人發(fā)送電子郵件,使用他們的名字并告訴他們一個(gè)數(shù)字。這個(gè)示例文件雖然不是特別有趣,但應(yīng)用了一個(gè)重要的原則,那就是:始終讓自己處于郵件接收列表的首位。這樣你可以在向列表全員發(fā)送郵件之前,先給自己發(fā)送一個(gè)測試郵件,以驗(yàn)證郵件的效果是否如你預(yù)期。
任何包含半角逗號的值,都 必須 以半角雙引號(")封閉。如果恰好在半角雙引號封閉的區(qū)域需要有一個(gè)半角雙引號,那就在同一行中連續(xù)使用兩個(gè)半角雙引號。引號的規(guī)則比較有趣,去 Python 3 中關(guān)于 CSV 的內(nèi)容中 一探究竟吧。
Template.txt
我的工作之一,就是為我們 Fedora 貢獻(xiàn)者會議 Flock 發(fā)送與旅行基金有關(guān)的信息。通過簡單的郵件告訴有關(guān)的人,他被選中為旅行基金支持的幸運(yùn)者,以及相應(yīng)基金支持的詳細(xì)信息。與接收者相關(guān)的具體信息之一就是我們可以為他的旅行提供多少資助。下面是一份我的節(jié)略后的模板文件(為了簡潔,已經(jīng)移除大量的文本):
$ cat mailmerge_template.txtTO: {{Email}}SUBJECT: Flock 2019 Funding OfferFROM: 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>>
模板的起頭定義了郵件的接收者、發(fā)送者和主題。在空行之后,是郵件的內(nèi)容。該郵件需要從 database.csv 文件中獲取接收者的 Email 、Name 和 Travel_Budget 。注意,上述這些占位符是由雙大括弧( {{、}} )封閉的。相應(yīng)的 mailmerge_database.csv 如下:
$ cat mailmerge_database.csvName,Email,Travel_BudgetBrian,bexelbie@redhat.com,1000PersonA,persona@fedoraproject.org,1500PèrsonB,personb@fedoraproject.org,500
注意,我把自己的信息放在了首條,這是為了測試方便。除了我,還有另外兩個(gè)人的信息在文檔中。列表中的第二個(gè)人 PèrsonB,他的名字中有一個(gè)包含變音符號的字母,Mailmerge 會對這類字母自動編碼。
以上包含了模板的全部知識點(diǎn):寫上你自己的電子郵件信息,并編寫好以雙大括弧封閉的占位符。接下來創(chuàng)建用來提供前述占位符具體值的數(shù)據(jù)文件。現(xiàn)在測試一下電子郵件的效果。
測試并發(fā)送簡單郵件
試運(yùn)行
測試從郵件的試運(yùn)行開始,試運(yùn)行就是講郵件內(nèi)容顯示出來,所有的占位符都會被具體值取代。默認(rèn)情況下,如果你運(yùn)行不帶參數(shù)的命令 mailmerge,它將對收件列表中的第一個(gè)人進(jìn)行試運(yùn)行:
$ mailmerge>>> encoding ascii>>> message 0TO: bexelbie@redhat.comSUBJECT: Flock 2019 Funding OfferFROM: Brian Exelbierd <bexelbie@redhat.com>MIME-Version: 1.0Content-Type: text/plain; charset="us-ascii"Content-Transfer-Encoding: 7bitDate: Sat, 20 Jul 2019 18:17:15 -0000Hi 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.
從試運(yùn)行生成的郵件中(列表中的 message 0 ,和計(jì)算機(jī)中很多計(jì)數(shù)場景一樣,計(jì)數(shù)從 0 開始),可以看到我的名字及旅行預(yù)算是正確的。如果你想檢視所有的郵件,運(yùn)行 mailmerge --no-limit,告訴 Mailmerge 不要僅僅處理第一個(gè)收件人的信息。下面是第三個(gè)收件人郵件的試運(yùn)行結(jié)果,用來測試特殊字符的編碼:
>>> message 2TO: personb@fedoraproject.orgSUBJECT: Flock 2019 Funding OfferFROM: Brian Exelbierd <bexelbie@redhat.com>MIME-Version: 1.0Content-Type: text/plain; charset="iso-8859-1"Content-Transfer-Encoding: quoted-printableDate: Sat, 20 Jul 2019 18:22:48 -0000Hi P=E8rsonB,
沒有問題,P=E8rsonB 是 PèrsonB 的編碼形式。
發(fā)送測試信息
現(xiàn)在,運(yùn)行 mailmerge --no-dry-run,Mailmerge 將向收件人列表中的第一個(gè)人發(fā)送電子郵件:
$ mailmerge --no-dry-run>>> encoding ascii>>> message 0TO: bexelbie@redhat.comSUBJECT: Flock 2019 Funding OfferFROM: Brian Exelbierd <bexelbie@redhat.com>MIME-Version: 1.0Content-Type: text/plain; charset="us-ascii"Content-Transfer-Encoding: 7bitDate: Sat, 20 Jul 2019 18:25:45 -0000Hi 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.
在倒數(shù)第 4 行,它將要求你輸入你的密碼。如果你使用的是雙因素認(rèn)證或者域控制登錄,那就需要創(chuàng)建應(yīng)用密碼來繞過這些控制。如果你使用的是 Gmail 或者類似的系統(tǒng),可以直接在界面上完成密碼驗(yàn)證。如果不行的話,聯(lián)系你的郵件系統(tǒng)管理員。上述這些操作不會影響郵件系統(tǒng)的安全性,但是仍然有必要采用復(fù)雜的安全性好的密碼。
我在我的郵件收件箱中,看到了這封格式美觀的測試郵件。如果測試郵件看起來沒有問題,那就可以運(yùn)行 mailmerge --no-dry-run --no-limit 發(fā)送所有的郵件了。
發(fā)送復(fù)雜郵件
只有充分了解了 Jinja2 模板 ,你才可能充分領(lǐng)略 Mailmerge 真正的威力。在郵件模板中使用條件語句及附帶附件,是很有用的。下面就是一個(gè)復(fù)雜郵件的模板及對應(yīng)的數(shù)據(jù)文件:
$ cat mailmerge_template.txtTO: {{Email}}SUBJECT: Flock 2019 Funding OfferFROM: 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.csvName,Email,Travel_Budget,Hotel,FileBrian,bexelbie@redhat.com,1000,Yes,visa_bex.pdfPersonA,persona@fedoraproject.org,1500,No,visa_person_a.pdfPèrsonB,personb@fedoraproject.org,500,Yes,visa_person_b.pdf
在這個(gè)郵件中有兩項(xiàng)新內(nèi)容。首先是附件,我需要向參加國際旅行的人發(fā)送簽證邀請信,幫助他們來 Flock,文件頭的 ATTACHMENT 部分說明了要包含什么文件;為了保持我的文檔目錄清晰,我將所有需要作為附件的文檔保存于附件子目錄下。其次是包含了關(guān)于賓館的條件信息,因?yàn)橛行┤说穆眯匈Y金包含了住宿費(fèi)用,我需要對涉及住宿的人員訴及相關(guān)信息,而這是通過 if 判斷實(shí)現(xiàn)的:
{% if Hotel == "Yes" -%}Lodging: Lodging in the hotel Wednesday-Sunday (4 nights){%- endif %}
這和大多數(shù)編程語言中的 if 判斷是一樣的。Jinja2 實(shí)力非凡,可以實(shí)現(xiàn)多級判斷。通過包含數(shù)據(jù)元素控制郵件內(nèi)容,能大大簡化相關(guān)的日常工作。空格的正確使用對郵件的易讀性很重要。if 和 endif 語句中的短線( - )是 Jinja2 控制 空白字符 的一部分。這里面選項(xiàng)很多,所以還是要通過試驗(yàn)找到最適合自己的方式。
在上面的例子中,我在數(shù)據(jù)文件擴(kuò)充了 Hotel 和 File 兩個(gè)字段,這些字段的值控制著賓館信息和附件文件名。另外,在上例中,我和 PèrsonB 有住宿資助,但 PersonA 沒有。
對于簡單郵件和復(fù)雜郵件而言,試運(yùn)行及正式發(fā)送郵件的操作都是相同的。快去試試吧!
你還可以嘗試在郵件頭中使用條件判斷( if … endif ),比如你可以使發(fā)送給在數(shù)據(jù)庫中的某人的郵件包含附件,或者改變對部分人改變發(fā)送人的信息。
Mailmerge 的優(yōu)點(diǎn)
Mailmerge 是用來批量發(fā)送定制郵件的簡潔而高效的工具。每個(gè)人只接受到他需要的信息,其它額外的操作和細(xì)節(jié)都是透明的。
我還發(fā)現(xiàn),即使是在發(fā)送簡單的集團(tuán)郵件時(shí),相對于使用 CC 或者 BCC 向一組受眾發(fā)送一封郵件,采用 Mailmerge 也是非常高效的。很多人使用了郵件過濾,那些不是直接發(fā)給他們的郵件,他們一律不會立刻處理。使用 Mailmerge 保證了每名接收者收到的就是自己的郵件。所有的信息會對接收者進(jìn)行正確過濾,再也不會有人無意間回復(fù)到整個(gè)郵件組。
























