前提
以前作成した下記記事の環境からスタート
GCP設定
クレデンシャルを作成
GCPのコンソール上でAPIとサービス
> 認証情報
OAuth クライアント IDの作成
アプリケーションの種類:デスクトップ
→ JSONをダウンロードして、appと同じ階層にclient_id.json
として作成
アクセス許可
gmail.py
import json
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
import httplib2
SCOPES = 'https://www.googleapis.com/auth/gmail.readonly'
CLIENT_SECRET_FILE = 'client_id.json'
USER_SECRET_FILE = 'credentials-gmail.json'
def create_service():
store = Storage(USER_SECRET_FILE)
credentials = store.get()
if not credentials:
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)
print(json.dumps(credentials.to_json()))
elif credentials.invalid:
credentials.refresh(httplib2.Http())
print(json.dumps(credentials.to_json()))
return credentials
app.py
import os
from flask import Flask
import gmail
app = Flask(__name__)
@app.route("/")
def test ():
gmail.create_service()
return "ok"
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))
確認
- ターミナルで
python3 app.py
を実行 - 別ターミナルで
curl http://localhost:8080
を実行
→ Gmailのアクセスを許可するかブラウザが起動する
→ 許可
→credentials-gmail.json
がappと同じ階層に作成されていればOK!!
コード
先ほど作成したcreate_service
関数の下にget_messages
の関数を作成
全体取得
def get_messages():
credentials = create_service()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
messages = service.users().messages()
msg_list = messages.list(userId='me', maxResults=1).execute()
for msg in msg_list['messages']:
topid = msg['id']
msg = messages.get(userId='me', id=topid).execute()
print(msg)
※どんなデータが取得できるか見れる
件名取得
def get_messages():
credentials = create_service()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
messages = service.users().messages()
msg_list = messages.list(userId='me', maxResults=1).execute()
for msg in msg_list['messages']:
topid = msg['id']
msg = messages.get(userId='me', id=topid).execute()
# 件名の取得
for msg in msg_list['messages']:
topid = msg['id']
msg = messages.get(userId='me', id=topid).execute()
for header in msg['payload']['headers']:
if header['name'] == "Subject":
print(header['value'])
本文取得
def get_messages():
credentials = create_service()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
messages = service.users().messages()
msg_list = messages.list(userId='me', maxResults=1).execute()
for msg in msg_list['messages']:
topid = msg['id']
msg = messages.get(userId='me', id=topid).execute()
# 本文の取得
if(msg["payload"]["body"]["size"]!=0):
decoded_bytes = base64.urlsafe_b64decode(
msg["payload"]["body"]["data"])
decoded_message = decoded_bytes.decode("UTF-8")
print(decoded_message)
else:
#メールによっては"parts"属性の中に本文がある場合もある
decoded_bytes = base64.urlsafe_b64decode(
msg["payload"]["parts"][0]["body"]["data"])
decoded_message = decoded_bytes.decode("UTF-8")
print(decoded_message)
要約取得
def get_messages():
credentials = create_service()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
messages = service.users().messages()
msg_list = messages.list(userId='me', maxResults=1).execute()
for msg in msg_list['messages']:
topid = msg['id']
msg = messages.get(userId='me', id=topid).execute()
# 要約の取得
print(msg['snippet'])
添付ファイル取得(Excel)
downloadフォルダを作成しておく
def get_messages():
row_list = []
credentials = create_service()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
messages = service.users().messages()
msg_list = messages.list(userId='me', maxResults=1).execute()
for msg in msg_list['messages']:
topid = msg['id']
msg = messages.get(userId='me', id=topid).execute()
for part in msg['payload']['parts']:
if 'filename' in part and part['filename'] and 'attachmentId' in part['body']:
msgId = msg['id']
att_id = part['body']['attachmentId']
att = service.users().messages().attachments().get(userId='me',messageId=msgId,id=att_id).execute()
data = att['data']
file_info = base64.urlsafe_b64decode(data.encode('UTF-8'))
excel = pd.ExcelFile(file_info)
sheet = excel.parse("シート1", header=None)
for row in sheet.iterrows():
row_str = ",".join(map(str, row))
row_list.append(row_str)
row_data = '\n'.join(row_list)
# csvの形になっているか確認
with open("downloadフォルダ「パスのコピー」/test.csv", mode='w') as f:
f.buffer.write(str.encode(row_data))
requirements.txtの追記
flask
oauth2client
google-api-python-client
app.pyの変更
gmail.create_service()
→ gmail.get_messages()
- ターミナル1で
python3 app.py
- ターミナル2で
curl http://localhost:8080
先ほど作成したdownloadフォルダにtest.csvとして格納されていればOK!
最後に
コード > 全体取得の部分でprint(msg)
を見た時、かなり複雑なデータになっているなと感じました。
また、ボットから送られてくるメールだとデータ構造が違うということが起きるので作成したコードでもデータ取得できないことがあります。
メール内にある添付ファイル取得する処理も追記しましたが、これもデータを見てからではないと取れないことがあります。
参考文献