laughk / TIL

2 stars 0 forks source link

GCP Pub/Sub と Gmail API をいじる #12

Open laughk opened 5 years ago

laughk commented 5 years ago

10 のつづき

Gmail API -> Pub/Sub -> CloudFunction 的なあれをやりたいのでそのへんいじる

laughk commented 5 years ago

image

「APIとサービス」→「APIとサービスの有効化」から連携サービスを探すことができて、 Gmail もある。こいつを有効にするとよさそう。

laughk commented 5 years ago

認証まわりがどう設定するのがいいかまだ良くわかってないので一旦スキップ

laughk commented 5 years ago

Pub/Sub の準備

image

適当な名前でトピックを作成し、 情報パネルのメンバー追加から gmail-api-push@system.gserviceaccount.com を Pub/Sub パブリッシャーとして追加する。

laughk commented 5 years ago

Cloudfunctions を用意

Gmail -> Pub/Sub がよくわかってないので一旦 Pub/Sub -> Cloud Functions へ まずは雑にポチポチそれっぽく作る。

image

laughk commented 5 years ago

Gmail -> Pub/Sub

この辺がヒントになりそうかな Push Notifications  |  Gmail API  |  Google Developers

laughk commented 5 years ago

どうも Gmail API と Pub/Sub の関係を勘違いしていた模様。 少し整理してみると以下のような感じらしい。


この辺は以下の記事が参考になる

Gmail APIとPub/Subでリアルタイムメール受信 on ruby - Qiita

テストした私が噛み砕くと、watchメソッドは、「gmail上のどんな些細な変更も順番に記録されているhistoryIDの中から、有る特定のイベント(正確な条件は私は調べても分からなかった)が起きた際に、指定されたPub/Sub上のトピックに、historyIDとその他些細なデータを含めたメッセージをPublishすることを試みることを一定期間において継続的に実行する」ことを起動するメソッドである。

laughk commented 5 years ago

つまり Pub/Sub を使うにせよ、結局どこかから何らかの方法で watch request し続ける必用がありそうで、 単純に Pub/Sub をトリガーとした Cloud Functions 一つでは上手くできなさそう。 Cloud Function だけでやるなら以下のように2つ用意する必用があるかも?

laughk commented 5 years ago

:thought_balloon: Pub/Sub にはいい感じにキューイングされそうだと思ってたので面倒臭くなってきた...

laughk commented 5 years ago

勢で https://github.com/laughk/TIL/pull/13 をやってしまったけど、これ多分いらなそう

laughk commented 5 years ago

こうすれば認証情報 (credentials.json)が取得できた

image

laughk commented 5 years ago

:thought_balloon: Qiita の記事とかみてると Heroku や GAE に雑に Web アプリを立てているが、 それは Pub/Sub のサブスクリプションで設定するエンドポイントの話。今回は Pub/Sub のイベントをトリガーにするのでそこは考える必用は無い。(冷静にみればそりゃそーだ)

laughk commented 5 years ago

とりあえず watch request はできたっぽい

$ python watch.py
{'historyId': '11907096', 'expiration': '1566031177696'}

コードはこんな感じ

import typing as t

from googleapiclient.discovery import build

from fetch import get_creds

def watch(request: t.Dict):

    creds = get_creds()
    service = build('gmail', 'v1', credentials=creds)
    return service.users().watch(userId='me', body=request).execute()

if __name__ == '__main__':
    print(
        watch({
            'labelIds': ["INBOX", "SENT"],
            'topicName': 'projects/private-tool-kit/topics/gmail-tool',
        })
    )

https://github.com/laughk/TIL/blob/master/gmail_tool/modules/fetch.py#L60-L84

laughk commented 5 years ago

watch を一回実行したら Pub/Sub にキューイングされ始めたっぽい

image