kakakakakku blog

Weekly Tech Blog: Keep on Learning!

最高すぎる!Gmail のフィルタ設定をデプロイできる CLI「gmailfilters」

無限に届くメールを整理するために Gmail の「フィルタ設定」を使っている人は多いと思う.

  • ラベルを付けたり
  • アーカイブをしたり
  • 削除をしたり

僕自身 Gmail を10年以上(メールを遡ったら2006年頃から)使っているため,歴史的な経緯から「フィルタ設定」が増えすぎてしまって,もはや管理不可能になっていた.もともと「フィルタ設定」には XML 形式で「エクスポート」「インポート」をする機能があるけど,もっとシンプルに設定を記述し,GitHub で管理し,継続的にデプロイする「Gmail Filter as Code」 を実現できたら最高だな!と考えていた.

gmailfilters とは?

gmailfilters を使うと,TOML フォーマットで Gmail フィルタ設定を記述できる.以下の例はnotifications@github.com から届くメールに GitHub ラベルを付ける」という意味になる.そして gmailfilters CLI を使って「エクスポート」をしたり,実際に Gmail に「デプロイ」もできる.今回は Go で実装された gmailfilters を紹介する.導入して1週間だけど,本当に最高すぎる!

[[filter]]
query = "from:notifications@github.com"
label = "GitHub"

github.com

アジェンダ

  1. gmailfilters を使う前に
  2. 認証情報を取得する
  3. gmailfilters をセットアップする
  4. gmailfilters でフィルタ設定をエクスポートする
  5. gmailfilters でフィルタ設定を継続的にデプロイする

1. gmailfilters を使う前に

1-1. フィルタ設定をバックアップする

闇雲に gmailfilters を使うと,今までのフィルタ設定を消してしまう可能性もあるため,バックアップ用途で XML をエクスポートしておく.エクスポートした XML を grep したら「計155件」もフィルタ設定があって驚いた!多すぎる...

$ grep '<id>' mailFilters.xml | wc -l
     155

1-2. フィルタ設定とメール配信設定を精査する

フィルタ設定を精査したところ,不要なフィルタ設定が多くあった.特に「不要なメールを削除するフィルタ設定(通販サイト/旅行サイト/クーポン関連/SaaS 関連など)」が1番多かった.根本的な解決を目指すため,会員登録をしている不要なサービスを全て「退会」し,会員登録をしておくサービスは「メール配信解除 (unsubscribe)」にした.またフィルタ設定は OR 条件なども使えるため,関連するフィルタ設定をリファクタリングした.最終的に「計20件」まで減らせた.スッキリした!

2. 認証情報を取得する

gmailfiltersGoogle API を使うため,事前に「認証情報(OAuth クライアント ID)」を取得しておく必要がある.ザックリと取得までのフローを紹介する.まず Google API Console にアクセスし,新しくプロジェクトを作成する.プロジェクト名は gmailfilters にしておく.

console.developers.google.com

次に「API とサービスを有効化」から「Gmail」を検索し「Gmail API」を有効化する.

f:id:kakku22:20200421130447p:plain

サイドバーから「認証情報」「認証情報を作成」「OAuth クライアント ID」と進む.「OAuth 同意画面(外部)」を作成してから認証情報を作成する.「アプリケーションの種類」「その他」にした.

f:id:kakku22:20200421130501p:plain

最後にプロジェクトページから認証情報を取得する.デフォルトだと client_secret_xxx.json というファイル名になっていた.

f:id:kakku22:20200421130513p:plain

3. gmailfilters をセットアップする

やっと準備が整った!さっそく gmailfilters をセットアップする.インストールは go get で簡単に行える.

$ go get github.com/jessfraz/gmailfilters

$ gmailfilters version
gmailfilters:
 version     :
 git hash    :
 go version  : go1.13.1
 go compiler : gc
 platform    : darwin/amd64

次は取得した認証情報ファイルを環境変数 GMAIL_CREDENTIAL_FILE に設定しておく.今回は direnv を使って export するようにした.

$ export GMAIL_CREDENTIAL_FILE=client_secret.json

環境変数を設定したら gmailfilters コマンドを実行する.表示された URL にアクセスし,権限を付与すると,コードをコピーする画面になる.コードをコピーしたら,入力待機中のままになっている gmailfilters コマンドにそのままペーストする.

$ gmailfilters
Go to the following link in your browser then type the authorization code:
https://accounts.google.com/o/oauth2/auth?xxx

(中略)

INFO[0329] Saving credential file to: /var/folders/xxx/token.json
must pass a path to a gmail filter configuration file

f:id:kakku22:20200421235922p:plain

4. gmailfilters でフィルタ設定をエクスポートする

gmailfilters コマンドと --export オプションを使って,フィルタ設定をエクスポートする.ファイル名は filter.toml にした.

$ gmailfilters --export filter.toml
exporting existing filters...
Exported 20 filters

実際にエクスポートしたフィルタ設定を以下に載せておく.GitHub の README.md では queryarchive など,頭文字は小文字なのに,エクスポートをすると Go の構造体 (Struct) のまま大文字になっている.実装は微妙な感じもするけど,どちらでも使える.

[[Filter]]
Query = "from:notifications@github.com"
Archive = false
Read = false
Delete = false
ToMe = false
ArchiveUnlessToMe = false
Label = "GitHub"
ForwardTo = ""

設定できるフィールドは以下となり,概要と入力値を載せておく.

  • Query : クエリ (条件)
  • QueryOr : OR クエリ (条件)
  • Archive : アーカイブするかどうか (true or false)
  • Read : 既読にするかどうか (true or false)
  • Delete : 削除するかどうか (true or false)
  • ToMe : 自分宛てのメールかどうか (true or false)
  • ArchiveUnlessToMe : 自分宛て以外のメールをアーカイブするかどうか (true or false)
  • Label : ラベルを付ける (ラベル名)
  • ForwardTo : 転送する (メールアドレス)

5. gmailfilters でフィルタ設定を継続的にデプロイする

残るは filter.toml を継続的にデプロイしていく.デプロイする場合は gmailfilters コマンドをそのまま使う.簡単すぎる!

$ gmailfilters filter.toml

Decoding filters from file filter.toml
Updating 20 filters, this might take a bit...
Successfully updated 20 filters

最後に個人的に使っているフィルタ設定を紹介しようと思う.

設定例 : 添付メールに Attachment ラベルを付ける

添付メールを探す場面が多いため,has:attachment クエリで検索をして Attachment ラベルを付けている.

[[filter]]
query = "has:attachment"
label = "Attachment"

設定例 : 1MB を超えるメールに Attachment/Large ラベルを付ける

larger:1M クエリを使うとサイズで検索できる.1MB を超える重すぎるメールは Attachment/Large ラベルを付けている.なお,Gmail のフィルタ設定は階層表現ができるため,gmailfilters では label をスラッシュ区切りにする.

[[filter]]
query = "larger:1M"
label = "Attachment/Large"

さらに gmailfilters はデプロイ時にラベルを新規作成してくれるため,事前にラベルを作っておく必要もなくて便利!以下のログを確認すると Created label と表示されている.

$ gmailfilters filter.toml

Decoding filters from file filter.toml
Updating 20 filters, this might take a bit...
INFO[0002] Created label: Attachment/Large
Successfully updated 20 filters

設定例 : GitHub のリポジトリ名で絞り込む

GitHub のリポジトリ通知は全部読むには多すぎるため,個人的に以下のポリシーで「通知設定 (Notifications)」をしている.

  • 「リリース情報を確認したい」リポジトリ
    • Notifications : Releases only
  • 「プルリクエストまで細かく確認したい」リポジトリ
    • Notifications : Watching

その前提で,GitHub の通知は全て notifications@github.com から届くため,リポジトリ名を subject クエリに設定する.以下は「GitHub の通知に GitHub ラベルを付ける」「GitHub の envoyproxy/envoy の通知に GitHub/Envoy ラベルを付けてアーカイブする」という設定になっている.envoyproxy/envoy の通知には GitHub ラベルも GitHub/Envoy ラベルも付く.

[[filter]]
query = "from:notifications@github.com"
label = "GitHub"

[[filter]]
query = "from:notifications@github.com subject:(envoyproxy/envoy)"
label = "GitHub/Envoy"
archive = true

設定例 : Amazon 購買メールに Amazon ラベルを付ける

Amazon 購買メールは「注文確認」「配達完了」など種類が多く,メールアドレスも異なるため「OR 条件」を使ってフィルタ設定をしている.単純にクエリを書くなら,以下のように OR を使える.

[[filter]]
query = "from:shipment-tracking@amazon.co.jp OR from:auto-confirm@amazon.co.jp OR from:order-update@amazon.co.jp"
label = "Amazon"
archive = true

ただし「OR 条件」が増えると可読性が下がるため,gmailfilters では queryOr フィールドを使って配列を記述できる.最終的に Gmail にデプロイされるフィルタ設定は一緒だけど,個人的に queryOr を使っている.

[[filter]]
queryOr = [
  "from:shipment-tracking@amazon.co.jp",
  "from:auto-confirm@amazon.co.jp",
  "from:order-update@amazon.co.jp"
]
label = "Amazon"
archive = true

まとめ

gmailfilters を使うと,TOML フォーマットで Gmail フィルタ設定を記述できる.現在は filter.toml を GitHub のプライベートリポジトリで管理して,フィルタ設定を継続的にデプロイしている.個人的に今年1番「出会えて良かったツール」と言える.最高すぎる!

さぁ gmailfilters で Gmail のフィルタ設定をデプロイしよう!

f:id:kakku22:20200421130355p:plain