📨

Gmailに届く認証コードをGmailAPIから自動確認したい

2023/08/27に公開

ご挨拶

はじめまして! おチヌと申します。
普段は Java に触ることが多いですが、個人では Python や JS など自由にやっています。

何かしらやってることの区切りがついたり、おもしろそうなネタがまとまったりした際に記事などアウトプットしていきたいと考えてます。

誰かの記事に助けられることが多いので、自分の記事も微力ながら誰かの+@になるとうれしいです。
どうぞよろしくお願いします。

GmailAPI の設定

公式ドキュメントが分かりやすかったです。
https://developers.google.com/gmail/api/quickstart/python?hl=ja

GmailAPI で独自ラベルを指定する

独自ラベルの ID が分からない

例えば、次のように記述されているとして

GMAIL = discovery.build("gmail", "v1", http=creds.authorize(Http()))
user_id = "me"
first_label = "INBOX"
second_label = "UNREAD"

GMAIL.list(userId="me", labelIds=[first_label, second_label])

「INBOX」や「UNREAD」などデフォルトで用意されているものは、少し調べれば何を入れるべきかある程度分かりました。

ただ、自分で作成したラベルの指定ができず、エラーになるという問題にあたりました。
具体的には次のような流れです。

  1. Gmail 上で「test」というラベルを作って、狙い撃ちしたいメールにだけラベル追加
  2. コード上で「first_label = 'test'」と記述
  3. 実行するとエラー

どうやら、first_label = 'test'(独自ラベル)の ID と記述するみたいです。
Gmail の画面から確認できない…。

独自ラベルの ID の確認方法

前提として、GmailAPI が動かせる環境になっている必要があります。
確認方法に、先ほどの公式サイトのサンプルを利用しました。
https://developers.google.com/gmail/api/quickstart/python?hl=ja

サイト後半に出てくるサンプルコードの記述を

for label in labels:
    print(label['name'])

次のように変更しました。

for label in labels:
    print(label)

変更後に実行すると、全ラベル(10 件前後?)が出力されますが、次のような出力形式になるので、目視で簡単に探せました。
{'id': '独自ラベルの ID', 'name': '独自ラベルの名称', 'type': 'user'}

あとは、該当の ID を先ほどのコード内に含めます。

GMAIL = discovery.build("gmail", "v1", http=creds.authorize(Http()))
user_id = "me"
first_label = "Label_12345678987654321" # 独自ラベルのIDで置き換え
second_label = "UNREAD"

GMAIL.list(userId="me", labelIds=[first_label, second_label])

API 実行時は次のように実行しました。

mylabel_msgs = (
    GMAIL.users()
    .messages()
    .list(userId=user_id, labelIds=[label_id_one, label_id_two])
    .execute()
)

コード全体

コード概要

ログイン時の認証メールから認証コードを取得します。
認証メールが複数件届いていても、最新の 1 件の認証コードのみを取得します。

下準備

大まかに次のような順番で下準備をしてから実行します。

  1. GmailAPI の設定
  2. 対象の認証メールに独自ラベルを設定
    ⚠️GmailAPI の設定と認証メールを受け取るメールアドレスは同じものを使う前提です

コード

from apiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools

# 独自ラベルのIDを別ファイルで管理
import my_confidential


def get_authentication_code() -> str:
    """
    ログイン時の認証メールから認証コードを取得する

    Args:
        None

    Returns:
        str: 認証コード
    """

    SCOPES = "https://www.googleapis.com/auth/gmail.modify"
    store = file.Storage("storage.json")
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets("credentials.json", SCOPES)
        creds = tools.run_flow(flow, store)
    GMAIL = discovery.build("gmail", "v1", http=creds.authorize(Http()))
    user_id = "me"
    label_id_one = "INBOX"
    label_id_two = my_confidential.Information.LABEL
    mylabel_msgs = (
        GMAIL.users()
        .messages()
        .list(userId=user_id, labelIds=[label_id_one, label_id_two])
        .execute()
    )
    mssg_list = mylabel_msgs["messages"]
    m_id = mssg_list[0]["id"]  # 対象ラベルの最新メールだけ取得
    message = GMAIL.users().messages().get(userId=user_id, id=m_id).execute()
    mail_body = message["snippet"]

    return mail_body[6:12]
GitHubで編集を提案

Discussion