Pythonを使ってGmail経由でメールを送る
「計算が終わった」とか「スクリプトが終わった」とか「コンパイルが終わった」とか,そういうときに通知が欲しい.
そこで,メールを使って通知させることにする.
作業が終わったら,サーバからメールを送ってそれをメーラで受け取ることで通知になるわけだ.
メールを送るといったらmailコマンドなのだけど,mailコマンドを使って外部にメールを飛ばすにはサーバを立ち上げないといけない.
それだとどこでも使えないので(そもそも職場や研究室のネットワークを勝手にいじれないし),sendmailで外部のSMTPサーバ,今回はGmail,を使って送信できるようにする.
このようなことは,Pythonでできるらしいので,以下のページを参考にやってみる.
独学Linux : Python スクリプトでGmail経由のメールを送信する方法
#junki::acoustic: PythonでGmailを送信
ウノウラボ by Zynga Japan: Pythonでメールを送信したい人のためのサンプル集
gmailsend.pyとsend_notify.pyをまとめてダウンロード
PythonのGmail送信スクリプト
まずは,Gmailでメールを送るための関数などを定義.
ココのを参考にした.
解説はココに詳しい.
ダウンロード - gmailsend.py
#!/usr/bin/python import smtplib from email.MIMEText import MIMEText from email.Header import Header from email.Utils import formatdate class sendGmail: def __init__(self, encoding, subject, body, from_addr, to_addr, login_addr, passwd): self.date = formatdate() self.encoding = encoding self.subject = subject self.body = body.encode('utf-8') self.from_addr = from_addr self.to_addr = to_addr self.login_addr = login_addr self.passwd = passwd def sendMail(self): msg = MIMEText(self.body, 'plain', self.encoding) msg['Subject'] = Header(self.subject, self.encoding) msg['From'] = self.from_addr msg['To'] = self.to_addr msg['Date'] = self.date s = smtplib.SMTP('smtp.gmail.com', 587) s.ehlo() s.starttls() s.ehlo() s.login(self.login_addr, self.passwd) s.sendmail(self.from_addr, self.to_addr, msg.as_string()) s.close()
これらの関数を読みこめば,以下のようにメールを送信することが出来るはず(Macで実行した場合).
$ python Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import gmailsend * >>> sg = sendGmail(encoding, subject, body, 'from_address@gmail.com', to_address@xxx.xxx, 'gmail_account@gmail.com', passwd)
解説すると
- encoding: メールの文字セット
- subject: 件名
- from_address: 送信元アドレス(普通はxxx@gmail.com)
- to_address: 送信先アドレス(任意)
- gmail_account: Gmailのアカウント名(xxx@gmail.com)
- passwd: Gmailアカウントのログイン
という感じ.
gmailsend.pyを使った通知スクリプト
gmailsend.pyを使って,作業が終わったら呼び出されて通知メールを送るスクリプト.
ダウンロード - send_notify.py
#!/usr/bin/python # -*- coding: utf-8 -*- import sys argvs = sys.argv # 引数のリスト argc = len(argvs) # 引数の数 # 本文をつくるなど import commands pwd = commands.getoutput("pwd") host = commands.getoutput("hostname") date = commands.getoutput("date +%D-%T") subject = '[Notification]' if (argc < 2): # 宛先がない場合はエラー print 'Usage: python send_notify.py address subject body' quit() if (argc < 3): # 件名なし subject = subject + ' ' + date else: subject = subject + ' ' + argvs[2] + ' ' + date print subject if (argc < 4): # 本文なし lbody = '' else: lbody = argvs[3] body = lbody + '\nFrom ' + host + '\n' + pwd + '\n' + date to_addr = argvs[1] print 'Notify to %s.' % to_addr print 'Subject: ' + subject print body # メールの送信 from sendgmail import * sg = sendGmail('utf-8', subject, body, 'xxx@gmail.com', to_addr, 'xxx@gmail.com', 'passwd') sg.sendMail()
最後から2番目の行の'xxx@gmail.com'と'passwd'には,送信に用いるGmailのアドレス,ユーザ名,パスワードをあらかじめ書いておく.
send_notify.pyの使い方は,
$ python send_notify.py to_addr@xxx.xx test "send notification, thank you."
というふうに,送信先アドレス,件名,本文の順に引数として渡します.
送信先アドレスだけ必須.
これを実行すると,
- 宛先: to_addr@xxx.xx
- 件名: [Nortification] test 01/31/12-13:19:10
- 送信元: xxx@gmail.com
- 本文:
send notification, thank you.
From hostname.com
/dev/pts/12
/hoge/users/dir1/dir2
01/31/12-13:19:10
というメールが来ます.
本文は
- 1行目: 3番目の引数(ない場合は改行のみ)
- 2行目: 送信元サーバのホストネーム
- 3行目: 端末の名前
- 4行目: 送信元のカレントディレクトリ
- 5行目: 現在時間
という構成になっている.
commands.pyを使うとシェルコマンドの返り値を簡単に本文に入れられるので,けっこう便利だと思う.
Pythonはかなり素人なので,多分突っ込みどころ満載だと思う.
一応Mac(Snow leopard)とLinux(CentOS 5.5とUbuntu 11.10)で動作確認済み.