Gmailをメーラーとして使ってますが、メールを開くのがいまだに苦手です。 これをどうにかしようと、メールをもっと気軽に消せる方法はないかなーと思ってInbox Zeroを思い出したのでやり始めました。

次の記事や動画を参考にしています。

基本的には、この動画を参考にして設定しました。


Inbox Zeroの設定方法

細かい設定は参考にした動画や記事の方に任せます。

Gmailの”設定”でやること

  • 詳細タブ
    • [ ] 自動表示 を有効化(アーカイブしたときに次のメールを自動で開く)
    • [ ] カスタム キーボード ショートカット を有効化
      • “キーボード ショートカット”というタブが増えて、ショートカットをカスタマイズできる
  • 全般タブ
    • [ ] 送信&アーカイブ を 表示する(送信したらアーカイブできる)
    • [ ] 自動表示: 前と次は好みで
    • [ ] キーボード ショートカット: ON
  • ラベルタブ(ラベルはお好みで)
    • [ ] Action Required ラベルを追加
    • [ ] Read Later ラベルを追加
    • [ ] Waiting ラベルを追加
  • 受信トレイタブ
    • [ ] マルチ受信トレイ を選択
    • [ ] セクション1,2,3に、次のラベル検索を追加
      • l:Action Required
      • l:Waiting
      • l:Read Later

これで設定は完了して、ホームに戻ると左右にトレイが並んだ感じの画面になります。

inbox

Inbox Zeroの運用

Inbox Zeroはよくわかっていませんが、基本的にGTDと同じようなものだと思います。 なので、メールをとりあえず開いて、次のようなフローでメールをラベリング and アーカイブするだけです。

  • メールを開く
  • 2分以内にできる? → すぐ処理(返信とか)してアーカイブ
  • 自分以外の対応を待つ必要がある? → Waitingラベルをつけてアーカイブ
  • 自分で対処しないといけない? → Action Requiredラベルをつけてアーカイブ
  • 後でしっかり見る必要がある? → Read Laterラベルをつけてアーカイブ
  • その他 → アーカイブ

指の動き的にはeを連打しながら、たまにvを押してラベルをつけるだけです。

基本全部アーカイブするので、受信トレイは空になるのでInbox Zeroというのだと思います。 既存のメールは頑張って全部を選択してアーカイブを繰り返してアーカイブしました。

この辺はGTDのよく見る図とかと流れは同じだと思います。

全部アーカイブしたら、ラベルをつけたものだけが右のカラムに表示されるので、その後ラベルに基づいて処理するだけです。 このときにラベルを手動で外してるけど、なんかショートカットで綺麗に外せない(yとかそれっぽいけどラベルが消えない)

基本的な設定と運用はこれだけなのですが、いくつか工夫しないとメールが無駄に増えてしまいました。 その工夫をメモっておきます。

Inbox Zeroの工夫

メールマガジン

メールマガジンはRSSリーダで読むように移行しました。 また、Inoreaderだとメールを受け取ってRSSにする機能もあります。

  • RSSフィードとして購読
  • メールをRSSフィードとして受け取る

実際に移行してみると、メールで受け取る必要があるメールマガジンは実はなかったというのが発見でした。

GitHub

GitHub NotificationsはWatchで崩壊してるので、関係するGitHubリポジトリの通知はメールで受け取っています。 GitHubはOrgnizationごとに通知先のメールアドレスを変更できるので、それでうまくフィルターしています。

そのメールに対する対処は次のようなイメージでやっています。

  • Issueのトリアージ
    • すぐできるので、GitHubにラベルをつける
  • Issueへのコメント
    • テンションによるので、すぐやる or Action Required ラベルをつける
  • PRのレビュー
    • テンションによるので、すぐやる or Action Required ラベルをつける

dependabot

GitHubリポジトリのセキュリティアップデートのみはdependabotでやってます。 それ以外のメンテナンス的なアップデートはrenovatebotでautomergeしてます。

dependabotはautomergeをしてくれないので、メールに対して @dependabot merge という返信をしています。 PRやIssueのメールに返信するとGitHubのコメントとして扱えるので、@dependabot mergeを送ってCIが通ってるならマージされます。 PRのマージボタンを押してマージしないのは、悪意ある攻撃者がdependabotと偽装してpackage-lock.jsonとかに細工したPRを送られると気付けないからです。

@dependabot mergeコメントなら、PRの送り主がdependabotじゃないならマージされません。

一方で、dependabotの通知は基本的に見たくない(リポジトリが1000以上あるので無限にPRの通知がきます)ので、dependabotからのPRに対して自動で @dependabot merge を返信するGASを動かしています。

ちょっと雑なコードなので、誰かがいい感じにしてくれると思います。

// MIT LICENSE ©️ azu
// Interval hours
const FETCH_INTERVAL_HOURS = 12;
const YOUR_MAIL_ADDRESS = "{yourmaiel}@gmail.com"
const MERGE_REPLY_LABEL = "dependabot-merge"; // 除外するラベル
function fetchPublishedMails() {
    const now = Math.floor(new Date().getTime() / 1000);
    const timeTerm = now - (60 * 60 * FETCH_INTERVAL_HOURS);
    // -label does not apply thread
    // https://webapps.stackexchange.com/questions/62881/exclude-label-from-a-gmail-search
    // -cc:[email protected]
    // ignore comment = thread
    const strTerms = `after:${timeTerm} from:dependabot[bot] <[email protected]> deliveredto:${YOUR_MAIL_ADDRESS} -l:${MERGE_REPLY_LABEL} -cc:[email protected]`;
    console.log("Search: ", strTerms);
    return GmailApp.search(strTerms);

}

/**
 * Creates time triggers.
 */
function createTimeTrigger() {
    ScriptApp.newTrigger('main')
        .timeBased()
        .everyHours(FETCH_INTERVAL_HOURS)
        .create();
}

function main() {
    const threadList = fetchPublishedMails()
    if (threadList.length === 0) {
        console.log("No new mail");
        return;
    }
    console.log("New mail threads: " + threadList.length);
    if (threadList.length > 100) {
        throw new Error("Too many replyTo");
    }
    threadList.forEach((mainThreads, index) => {
        const message = mainThreads.getMessages()?.[0];
        if (!message) {
            return;
        }
        const replyTo = message.getReplyTo();
        console.log("replyTo", replyTo);
        // need to embed replayTo into body for recognizing by GitHub
        // 2022年12月18日(日) 18:22 dependabot[bot] ***@***.***>:
        message.reply(`@dependabot merge

${new Date().toLocaleString()} ${replyTo}
`);
        mainThreads.addLabel(GmailApp.getUserLabelByName(MERGE_REPLY_LABEL));
        Utilities.sleep(1000);
    });

}

なんかもっといい方法が欲しいです(GitHub Actionsはリポジトリごとなので設定が厳しいです)。

Action Requiredラベルの自動化

気軽にアーカイブしていくので、Action Requiredなメールをすっ飛ばすこともありそうです。 なので次のようなフィルターを書いてました。

条件: subject:(Action required)
処理: ラベル「Action Required」を付ける

Note

  • マルチ受信トレイでは、メインを未読のみの表示にできませんでした
    • 未読がずっと見えるのは変なので、アーカイブする運用にしてるんだと思います(未読のみ表示ができるなら、アーカイブじゃなくても良いと思います)
    • アーカイブと未読は、感覚的に違いはないです(検索とかはできるので消えるわけじゃない)
  • 左のサイドバーは、左上のハンバーガーメニューから折り畳めます
    • left menu
    • これでマルチ受信トレイの領域を広くできます
    • 左のメニューは送信済み(is:sent)とスター(is:star)の確認をたまにするぐらい
    • これも検索クエリにできるので、右カラムに追加もできます。ただ積もるので自分は足してないです

まとめ

結構シンプルな設定で、Inbox Zeroができていそうです。

eでアーカイブが気軽にできるようになって、メールがRSSリーダ(RSSリーダはIrodrを使ってます)にちょっと近くなりました。 以前よりはメールを開くまでに気合を入れる時間が減った気はします。 メールクライアントの未読通知のbadgeがちゃんと未読の意味になったので、クライアントを開く回数が減りました。

不満なところはGmailとかのクライアントの問題でいくつかあります。

  • eで間違ってアーカイブしたときにそのメールを見直しにくい
    • jで進んだら、kで戻る感じにしたい
  • yAction Required とかつけたラベルが消えてくれない(処理が終わったら外したい)
  • Action Required とかのラベルをショートカット一発でつけたい
  • マルチカラムだとラベルをつけても、右カラムにリロードするまで反映されない
  • 次に移動するメールがわかってた方がRSSリーダの感覚に近いので、そうしたい
    • 現状はキーを押すまでわからないから、キーが押しにくい
  • T 押したときにGoogle Taskにメールを入れられるけど、これをNotionとか自作のエンドポイントに送りたい

自分は受け取るメールの総量がそんな多くないのでなんとかなってますが、この辺もっと軽い感じにできるといいなーと思いました。 (そういうクライアントとかあるのかなー、でも大体Gmailレベルのフィルターができるものがなくて止まってる気がする)

Inbox Zeroをやる前から未読自体はあまり多くないタイプでしたが、同じもの(メルマガなど)が1-2週間残りがちなので0にするために実施した感じです。 “後で見る”を既読未読 + 未読のみを表示で表現すると、毎回視界に入るのが負荷になるので、それをどうにかしたかったというが主な理由な気がします。