LINEBot

Python×GmailAPIで未読メールだけを受信する

PythonでGmailAPIを利用して内容を取得した。
チャットボットに組み込んだ機能の一つ。

もくじ

  1. PythonでGmailAPIを使う
  2. GmailAPIで未読のメールの本文だけ取得する
  3. まとめ
  4. 参考

GmailAPIを使う

GmailAPIとは、Googleが提供しているGmailを扱うためのAPI。

できることは、

・メッセージの読み取りと送信
・下書きと添付ファイルの管理
・スレッドとメッセージの検索
・ラベルの操作
・プッシュ通知の設定
・およびGmail設定の管理

と多岐にわたる。
というかGmailで使う機能をほぼほぼ網羅してる。
要するにコードで自由にGmailを扱えるってことね。
素晴らしい。

GmailAPIの使い方については詳細には書かない。
理由は、他に非常にわかりやすくまとまっているサイトがあるため。

参考サイトはこちら。
PythonでGmailのメールを確認しよう

何ならこのサイト通りにするだけで、GoogleAPIを使ってメールの要約を表示するところまでは出来てしまうのでおすすめ。

GmailAPIで未読のメールの本文だけ取得する

とりあえずコード。
基本的にはさっきの参考サイトのコピペ。

認証情報へのPATHを直接コードに書いてたり、余計な動作が混じってるのはご容赦。

  import httplib2, os
  from apiclient import discovery
  from oauth2client import client, tools
  from oauth2client.file import Storage


  def gmail_get_service():
    # ユーザー認証の取得
    credentials = getauth()
    http = credentials.authorize(httplib2.Http())
    # GmailのAPIを利用する
    service = discovery.build('gmail', 'v1', http=http)
    return service

  # メッセージの一覧を取得
  def gmail_get_messages():
    service = gmail_get_service()
    data_list = []
    # メッセージの一覧を取得
    messages = service.users().messages()

    msg_list = messages.list(userId='me', maxResults=30).execute()

    # 取得したメッセージの一覧を表示
    for msg in msg_list['messages']:
        topid = msg['id']
        msg = messages.get(userId='me', id=topid).execute()

        if msg['labelIds'][0] == "UNREAD":
            data_list.append(msg['snippet'])
            print(msg['snippet'])
    return "OK"

  def getauth():
    # ユーザーの認証データの読み取り
    store = Storage('credentials-gmail.json')
    credentials = store.get()
    # ユーザーが認証済みか?
    if not credentials or credentials.invalid:
        # 新規で認証する
        flow = client.flow_from_clientsecrets('gmail.json', 'https://www.googleapis.com/auth/gmail.readonly')
        flow.user_agent = 'Python Gmail API'
        credentials = tools.run_flow(flow, store, None)
    return credentials


  gmail_get_messages()

ポイントはこの部分。

  # メッセージの一覧を取得
  messages = service.users().messages()

  msg_list = messages.list(userId='me', maxResults=30).execute()

  # 取得したメッセージの中で未読のものを表示
  for msg in msg_list['messages']:
      topid = msg['id']
      msg = messages.get(userId='me', id=topid).execute()

      if msg['labelIds'][0] == "UNREAD":
          data_list.append(msg['snippet'])
          print(msg['snippet'])

Gmailから受け取ったメッセージは次のような形式で渡される。
未読のメールに関しては、'labelIds'に'UNREAD'という情報が追加されている。
なので'UNREAD'の有無の条件分岐で未読メールを表示できる。

  {
    'id': '16629c6e7163565f',
    'threadId': '16629c6e7163565f',
    'labelIds': ['UNREAD', 'IMPORTANT', 'SENT', 'INBOX'],
    'snippet': 'テストメール',
    'historyId': '4807380',
    'internalDate': '1538299190000',
    'payload': {'partId': '', 'mimeType': 'text/plain', 'filename': '',
    'headers': [{'name': 'Return-Path', 'value': '<メールアドレス>'
  },
  {
    'name': 'Received',
    'value': 'from [IPアドレス] (ai126173163159.46.access-internet.ne.jp. [IPアドレス])
    by smtp.gmail.com with ESMTPSA id y85-v6sm17088410pfa.170.2018.09.30.02.19.52
    for <メールアドレス>
    (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
    Sun, 30 Sep 2018 02:19:52 -0700 (PDT)'
  },
  {
    'name': 'From',
    'value': '"送信者" <メールアドレス>'
  },
  {'name': 'Content-Transfer-Encoding', 'value': 'base64'},
  {'name': 'Content-Type', 'value': 'text/plain; charset=utf-8'},
  {'name': 'Mime-Version', 'value': '1.0 (1.0)'},
  {'name': 'Date', 'value': 'Sun, 30 Sep 2018 18:19:50 +0900'},
  {'name': 'Message-Id', 'value': '<メールアドレス>'},
  {'name': 'To', 'value': '"送信者" <メールアドレス>'},
  {
    'name': 'X-Mailer',
    'value': 'iPhone Mail (15G77)'}],
    'body': {'size': 20, 'data': '44OG44K544OI44Oh44O844OrDQo='}
  },
  'sizeEstimate': 752}

まとめ

とりあえずこれでGmailAPIから受け取った内容をPythonで扱うことが出来た。
今回作ったこのコードは、自作のLINEBotに組み込んでメール通知機能として使っている。
とはいえその機能自体はメールアプリで事足りる。
送信者でIF文を書けば特定の相手からのメールのみを通知したりできるし、使い方はアイデアしだいで広がりそう。

ちなみに僕は始め、GmailをPythonで扱うためにIMAPプロトコルを利用したのだが、問題があってやめてしまった。
その問題とは、Googleのセキュリティレベルを下げなければならない点である。
IMAPでGmailと連携すると、通常の設定ではブロックされてしまう。
便利なAPIがある中で無理に問題のある方法を選ぶ必要はないので、特に使う必要はないだろう。

参考

・WEB
PythonでGmailのメールを確認しよう

PythonでGmailを確認しよう その2

COMMENT

メールアドレスが公開されることはありません。