前回サーバー構築と設定をしました。 gologius.hatenadiary.com
今回はメールチェックとメール送信用のスクリプトを書いていきます。
使うスクリプト
GMailAPI を叩くPythonスクリプトです · GitHub
実行環境構築
(1) Google API を有効にしておく(下記URL参照)
スクリプト実行に必要なJSONファイルもDLできるはずです。
ゼロからはじめるPython(22) PythonでGmailのメールを確認しよう | マイナビニュース
(2) 以下のコマンドを実行し、モジュールをインストール
pip3 install google-api-python-client pip3 install oauth2client pip3 install httplib2
(3) 認証用関数user_auth()
を実行する(1回のみ)
(4) JSONファイルcredentials-gmail.json
が生成されます
メールの送受信
# -*- coding: utf-8 -*- import httplib2 import base64 import traceback from googleapiclient import discovery from oauth2client import client from oauth2client import tools from oauth2client.file import Storage from email.mime.text import MIMEText from email.utils import formatdate SCOPES = 'https://mail.google.com/' # Gmail権限のスコープを指定 CLIENT_SECRET_FILE = 'client_id.json' # Google AP管理サイトからダウンロードした権限ファイルのパス USER_SECRET_FILE = 'credentials-gmail.json' # ユーザーごとの設定ファイルの保存パス USE_ADDR = "test@gmail.com" # 使用するメールアドレス #認証用(開発環境を整える際に、初回に一回実行する) def user_auth(): store = Storage(USER_SECRET_FILE) credentials = store.get() # ユーザーが認証済みでない場合 新規認証する if not credentials or credentials.invalid: flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES) flow.user_agent = 'Python Gmail API' credentials = tools.run_flow(flow, store, None) print('認証結果を保存しました:' + USER_SECRET_FILE) return credentials #API使用準備 def get_service(): credentials = user_auth() http = credentials.authorize(httplib2.Http()) service = discovery.build('gmail', 'v1', http=http) return service #N件メールを取得 def get_messages(maxnum): service = get_service() messages = service.users().messages() msg_list = messages.list(userId='me', maxResults=maxnum).execute() print("メールサーバーからの受信完了") payloads = [] # 取得したメッセージの一覧を表示 for msg in msg_list['messages']: topid = msg['id'] payload = messages.get(userId='me', id=topid).execute() payloads.append(payload) # メール情報を確認 item = mail.mail() headers = payload['payload']['headers'] for header in headers: if header['name'] == 'Date': print(header['value']) #受信日? if header['name'] == 'From': print(header['value']) #from if header['name'] == 'To': print(header['value']) #to if header['name'] == 'Cc': print(header['value']) #cc if header['name'] == 'Subject': print(header['value']) #件名 print(payload['snippet']) #本文の概要(※全文は入らない) return # メールを送信する def send_message(to, subject, body): #メール作成 message = MIMEText(body) message["from"] = USE_ADDR message["to"] = to message["subject"] = subject message["Date"] = formatdate(localtime=True) byte_msg = message.as_string().encode(encoding="UTF-8") byte_msg_b64encoded = base64.urlsafe_b64encode(byte_msg) str_msg_b64encoded = byte_msg_b64encoded.decode(encoding="UTF-8") rawdata = {"raw": str_msg_b64encoded} #送信 service = get_service() try: service.users().messages().send( userId="test@gmail.com", body=rawdata ).execute() print("メール送信完了") except: print("メール送信エラー") traceback.print_exc() return
gmail_mailbox.py
の
get_messages()
でメール情報を取得できますsend_message()
でメール送信できます
受信できれば後は好きに弄れば、メール監視スクリプトの完成です。
main.py
を叩くようなバッチを作成し(start.sh
)、crontab -e
にてそのバッチを叩くように設定します(前回記事参照)。
# -*- coding: utf-8 -*- # main.py import datetime import gmail_mailbox def job(): # メール取得+チェック mails = gmail_mailbox.get_messages(40) print('メール取得完了') isError = checkError(mails) #適当にチェック # 現在時間と一緒に、処理結果を表示 nowtime = datetime.datetime.now(); timestr = nowtime.strftime('%Y/%m/%d %H:%M:%S') body = u"<チェック結果>\n" body += u"isError " + str(isError) + "\n" if (isError) == True: print("") print("【結果】 [" + timestr + "] 何か検知しています") print("") gmail_mailbox.send_message(u"example@gmail.com", u"システムエラー", body) else: print("") print("【結果】 [" + timestr + "] 何もありませんでした") print("") return job()
#!/bin/sh cd `dirname ${0}` date datestr=`date '+%Y%m%d'` echo begin mail checker python3 main.py >> log/${datestr}.log 2>&1 echo end mail checker
main.py
では、メールを40通見て、エラーと判定されるとメールを送信するようにしています。
ポイント
from apiclient
からfrom googleapiclient
にモジュール名が変更されています。 古い記事を参考にしている場合、ここでエラーになる場合があります。payload['snippet']
はメールの概要を見るためのものです。実際に全文見ようとすると、 別の項目をエンコードする必要があります
- 調査中ですが、メールを重複して受信する場合があります。
- 恐らく、独自にラベルを設定していると、受信トレイ分とラベル分、二つのメールを受信してしまうようです