透過 Python SMTP 寄信 (code)

內容有分 Python 2.7 & Python 2.4,
起因是業管系統有發 mail 需求,
而 Linux 內建的 Python 常見的有 2.4、2.7,
因此才會需要兩個不同版本的腳本來發信
 

問: 為何不用 sendmail、mailx 來發送,

答: 沒有 root 相關權限來說,用 Python Code 來發信是最有彈性,很好管理與設定,

      有 root 權限,設定 sendmail、mailx 以及管理與維護也相對麻煩,

      未來系統若交接,有 root 權限還好,可以查,沒 root 權限誰會知道你設定了什麼,

      還要跨找主機負責人,看是誰設定的。

說明一下 Python 2.7 版本是在 githut 上發現的,有修改一點原本內容,並增加HTML格式傳送,

Python 2.4 版是參考 Python 2.7 版修改而來。

 

Python 2.7 ( Python 3 以上沒試過)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  sendemail.py
#  
#  (c) 2017 Mike Chaberski
# 
#  MIT License 

import smtplib
from email.mime.text import MIMEText
import argparse
import socket
import os

def send_message(options):
    body = ' '.join(options.message)
    if options.contenttype == 'html':
        msg = MIMEText(body, 'html', 'utf-8')
    else:
        msg = MIMEText(body)
    msg['Subject'] = options.subject
    me = options.sender
    you = options.to
    msg['From'] = me
    msg['To'] = you
    print 'sending message...',
    s = smtplib.SMTP(options.smtp)
    s.sendmail(me, you, msg.as_string())
    s.quit()
    print '...message sent'
    return 0

def main():
    parser = argparse.ArgumentParser(description="Send an email using an SMTP server")
    parser.add_argument("--to", metavar="to@example.com", help="recipient address")
    parser.add_argument("--message", metavar="MESSAGE", help="email body", nargs='*')
    parser.add_argument("--from", dest='sender', metavar="from@example.com", help="sender address")
    parser.add_argument("--subject", metavar="SUBJECT", help="email subject", default="(no subject)")
    parser.add_argument("--file", metavar="PATHNAME", help="file to take message body from")
    parser.add_argument("--smtp", default='localhost', metavar="SERVER")
    parser.add_argument("--contenttype", default='string', metavar="CONTENT", help="content type")
    options = parser.parse_args()
    if (options.message is None or len(options.message) < 1) and options.file is None:
        parser.error("must specify message body as argument or file")
    if options.file is not None:
        with open(options.file, 'r') as ifile:
            options.message = [ifile.read()]
    if options.sender is None:
        domain = socket.getfqdn()
        user = os.environ['USER']
        options.sender = user + '@' + domain
        #domain = options.smtp
        #if domain.startswith('smtp.'): domain = domain[5:]
        #options.sender = 'sender@' + domain
    return send_message(options)

if __name__ == '__main__':
    main()

Python 2.4 使用

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  sendemail.py
#  
#  (c) 2017 Mike Chaberski
#  
#  MIT License 
#
#  Edit by Johnson For Python 2.4

import smtplib
from email.MIMEText import MIMEText
from optparse import OptionParser
import socket
import os

def send_message(options):
    body = ' '.join(options.message)
    if options.contenttype == 'html':
        msg = MIMEText(body, 'html', 'utf-8')
    else:
        msg = MIMEText(body)
    msg['Subject'] = options.subject
    me = options.sender
    you = options.to
    msg['From'] = me
    msg['To'] = you
    print 'sending message...',
    s = smtplib.SMTP(options.smtp)
    s.sendmail(me, you, msg.as_string())
    s.quit()
    print '...message sent'
    return 0

def main():
    parser = OptionParser()
    parser.add_option("--to", metavar="to@example.com", help="recipient address")
    parser.add_option("--message", metavar="MESSAGE", help="email body", default="(no message)")
    parser.add_option("--from", dest='sender', metavar="from@example.com", help="sender address")
    parser.add_option("--subject", metavar="SUBJECT", help="email subject", default="(no subject)")
    parser.add_option("--file", metavar="PATHNAME", help="file to take message body from")
    parser.add_option("--smtp", default='localhost', metavar="SERVER")
    parser.add_option("--contenttype", default='string', metavar="CONTENT", help="content type")
    (options, args) = parser.parse_args()
    if (options.message is None or len(options.message) < 1) and options.file is None:
        parser.error("must specify message body as argument or file")
    if options.file is not None:
        ifile = open(options.file, 'r')
        try:
            options.message = [ifile.read()]
        finally:
            ifile.close()
    if options.sender is None:
        domain = socket.getfqdn()
        user = os.environ['USER']
        options.sender = user + '@' + domain
        #domain = options.smtp
        #if domain.startswith('smtp.'): domain = domain[5:]
        #options.sender = 'sender@' + domain
    return send_message(options)

if __name__ == '__main__':
    main()