Featured image of post Python系列: smtplib 模組實現自動寄信

Python系列: smtplib 模組實現自動寄信

Background photo by Brett Jordan on Unsplash

在信箱收件夾,不乏看到許多自動寄出的信件,像是來自 slurm job 通知分析狀態的信,以及訂閱內容的自動通知等。自動寄信不僅節省人力操作,也可廣發信件增加傳播效率。今天就要介紹如何用python實現自動寄信

Part1: SMTP協定介紹

通訊協定,是協助資訊在不同軟硬體之間傳輸的方式,例如使用相同IP的兩台電腦,可以突破主機限制互相通訊。網際網路中,常用的通訊協定包含TCP/IP, HTTPS(TLS/SSL加密),以及本文要使用的SMTP協定。 SMTP全名為簡易郵件傳輸通訊協定 (Simple Mail Transfer Protocol),是透過網路在電腦與伺服器之間接收與傳送電子郵件的通訊方式。只要知道服務廠商的smtp, port, 並提供一個寄件帳號,就可以自動\廣發信件給多名收件人。

常見的廠商與smtp伺服器:

  • gmail: smtp.gmail.com
  • outlook: smtp-mail.outlook.com

常見的連接埠比較(內容節錄自cloudflare網站) :

連接埠 25 最常用於 SMTP 伺服器之間的連線。如今,用於終端使用者網路的防火牆通常會封鎖該連接埠,因為垃圾郵件發送者嘗試濫用它來傳送大量垃圾郵件。

連接埠 465 曾經專供具有安全通訊端層 (SSL) 加密的 SMTP 使用。但是 SSL 已被 Transport Layer Security (TLS) 取代,因此現代電子郵件系統不再使用該連接埠。它只存在於舊版(過時的)系統中。

連接埠 587 現在是電子郵件提交的預設連接埠。透過此連接埠進行的 SMTP 通訊使用 TLS 加密。

Part2: 撰寫python程式

python 提供 smtplib 模組來協助 smtp 封裝信息並傳輸給目標端。由於

step0: 引入套件和開啟google mail 權限

1
import smtplib

除了基本模組,常搭配擴充電子郵件標準套件,來處理內文部分

1
2
from email.mime.multipart import MIMEMultipart #email內容載體
from email.mime.text import MIMEText           #製作郵件內文

若要在gmail使用smtplib,需要到 google 帳戶的安全性頁面 完成帳戶密碼設定(下圖紅框標示處)

step1: 設定帳戶資訊

1
2
3
4
5
6
7
MAIL_USER = "from_who_user_@gmail..."  #寄件者email帳號
MAIL_PASSWD = "......"                 #寄件者email密碼
FROM_ADDRESS = MAIL_USER               #和寄件者相同

# 郵件平台的主機 port (這裡使用 gmail smtp 伺服器)
MAIL_SMTP = "smtp.gmail.com"
MAIL_PORT = 587                        #安全加密port "587"

step2: 撰寫郵件內容與寄件人

1
2
to_address = "to_who_@gmail..."        #收件者email帳號
body_content = ""                      #輸入郵件內文

step3: 以擴充電子郵件標準來組合 email 結構

1
2
3
4
5
6
mail = MIMEMultipart()
mail['From'] = FROM_ADDRESS            #寄件者
mail['Subject'] = "the subject"        #主旨
mail['To'] = to_address                #收件者

mail.attach(MIMEText(body_content))    #以attach方式貼上內文

step4: 設定smtp伺服器並寄信

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
smtpserver = smtplib.SMTP(MAIL_SMTP, MAIL_PORT)

# 發出「Hello」訊息,以在用戶端和伺服器之間建立SMTP連線
smtpserver.ehlo()   

# TLS加密:延伸保護 SMTP 階段作業
smtpserver.starttls() 

# 登入寄件人郵件系統
smtpserver.login(MAIL_USER. MAIL_PASSWD) 

# 將step3產生的信件內容轉成string並寫入
smtpserver.sendmail(FROM_ADDRESS, to_address, mail.as_string()) 

# 結束系統連線
server.quit() 

Part3: 完整script & 成果展示

附上完整的 python script 注意: 由於使用個人主機測試,才敢將信箱帳密直接輸入在command line、由 sys 存取,若在公用主機請注意資安考量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env python3

import os
import sys
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

mail_user = sys.argv[1]
mail_passwd = sys.argv[2]
from_address = mail_user

mail_smtp = "smtp.gmail.com"
mail_port = 587

to_address = sys.argv[3]
body_content = """
    This is the auto-send email test 
"""

mail = MIMEMultipart()
mail['From'] = mail_user
mail['To'] = to_address
mail['Subject'] = "Test for smtp email-sender"

mail.attach(MIMEText(body_content))

server = smtplib.SMTP(mail_smtp, mail_port)
server.ehlo()
server.starttls()
server.login(mail_user, mail_passwd)
server.sendmail(mail_user, to_address, mail.as_string())
server.quit()

到收件者的信箱查看,成功收到如下圖的信件

參考資料

https://aws.amazon.com/tw/what-is/smtp/ https://www.cloudflare.com/zh-tw/learning/email-security/what-is-smtp/

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus