rcmdnk's blog

20180913_gmailfilter_200_200

ちょっとGmailのフィルタをアップデートしてて気づいたのですが、 最近Gmailのフィルタの順序がまったく保存されなくなったようです。

現在新しいインターフェースと古いインターフェースの両方が使えますが、 いずれでも駄目でした。

Gmailのフィルタ

Gmailのフィルタは基本的にラベル付けに使っています。

Gmailではフォルダという概念はなくて全てラベルで分ける仕様になっています。 ラベルなのでEvernoteで言うタグみたいなもので一つのメールに複数のラベルを付けることも可能です。

そういう意味もあって、Gmailのフィルタは入ってきたメールに対して全てのフィルタが適用される様になっています。 フォルダ分けであれば最初に該当したフォルダに入れて終わり、ですが、ラベルであれば複数該当するフィルタがあってそれを付けたい、ということで。

一つのフィルタも複数の条件の組み合わせでできるので簡単なことだけならそれで全てをまかなえるかもしれませんが、 自分の使い方だとちょっと難しいところがあります。

やりたいことは簡単にいうと

  • メーリングリスト宛などのものはその名前のラベルを付ける(もしくはある程度グループ化してそのラベルを付ける)
  • その他送り先などの条件でラベルを付ける
  • 必要なものはInboxに残し、それ以外はアーカイブする
  • ラベルが何もついてなければ最後に00_NoLabelといったラベルを付けてアーカイブする

といった感じ。

ただし、メールをアーカイブするかInboxに残すか、ということをやるのは結構面倒で、 特定の送り先から来たら基本アーカイブ、だけどさらに特殊な条件のときだけInboxに残す、 と言ったことをしようとすると

  • やり方1:
    • (from:mailinglist -to:bbb) -> archiveする
    • (from:mailinglist) -> label mailinglistをつける
  • やり方2:
    • (from:mailinglist) -> label mailinglistをつける
    • (to:bbb) -> DummyInboxラベルを付ける
    • 最後にDummyInboxラベルがついてないものをすべてarchiveする

といったどちらかの方法になります。これだけ見ると1のほうが簡単そうですが、 たくさんのラベルをつけようと思うと1の方では全てに対して2つづつ作っていかなくてはいけないのに対し、 2の方では各mailinglistに対しては一つの定義だけで済むのでフィルタの数が大分少なく住みます。

また、フィルタの条件は色々条件が組み合わせられますが、文字数に制限があってあまり長い条件は書けません。 なので2の様にそれぞれの場合で分けて作らないと無理な場合もあります。 (この辺の数字も前にどこかで見たような気がしますが見つけられず。) ただ、長いものを作ろうとすると失敗することは確かです。

フィルタの数にも制限があるとかないとか書かれてますが、200個とかならいける、といったものは見ました。 いまのところこれの制限にかかったことはないです。

先のNoLabelとこのDummyInboxの適用を行うには 確実に最後にこれらのフィルタが適用される必要があります。 なので順序が大事。

以前のGmailではフィルタは作成順に設置され、編集とかすると一番下に来る、といった感じでした。

順序を簡単に変える方法がないので 一旦エクスポートして編集して、一旦Gmail上のフィルタを全部消してインポートする、といったことをしてました。

この作業も特にエクスポートされるXMLファイルの編集が 面倒なのでそれを簡単にするツールとかも作ってました。

そんな中、今年はじめくらい?から新しいGmailのインターフェースが使える様になっていて、 最近では新しいものを使うことが推奨されています。

タスクリストとかがよりきれいに統合されたり色々と外部連携が充実したりして 全体的にはかなり良いアップデートかな、という感じなのですが、 フィルタに関して言うとちょっと微妙な感じがありました。

フィルタを設定で開いてみると、以前せっていしたものとは違う順序になっています。 ただ、エクスポートしてみると以前の設定どおりになっている、といった状態。これが一ヶ月くらい前に確認した時のものです。

フィルタの順序が保存されなくなった?

これが昨日くらいにアップデートしようと思ってまたフィルタをインポートしてみたところ、 どうもNoLabelに行くべきものがついてなかったり、Inboxに残したいものが残ってなかったりぐちゃぐちゃになってしまいました。

フィルタを見ると、インポートした直後はただしく入れたとおりに表示されていたものの、 その後開くと全く違う順序に。

以前も新しいインターフェースでは順序は変わってましたが、エクスポートすると思い通りの順序だったのでエクスポートしてみると 今度は順序がばらばらに。。。

ばらばら、というかよく見るとidの数字の順序になってました。 このid1524641463341とか大きい数字で作った順序などには関係なく、ユーザーが管理できるものではありません。 インポート時に、XMLファイルのなかの数字を変更してもGmail上で書き換えられて適当なidになります。 (Gmail全体でuniqueな数字?)

これが新しいインターフェースの変更のためか、と思って古いインターフェースに戻して しばらく試してみましたがやはり駄目でした。 Gmail上の表示が思い通りになっていてもエクスポートするとバラバラでフィルタの動作を見てるとどうやらエクスポートされたもの の順序で適用されてる様子。

とりあえずの対応策: Google App Scriptを使う

NoLabel対策

現状の対応策としては、NoLabelをつけるフィルタを削除しました。

そのままだとラベルがつかないままアーカイブされて見えづらくなるメールが有って困るので、 これに対してはGoogle Apps Script を使ってラベルを付けます。

以下の様なスクリプトを作成します。

updateLabel.gs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function updateLabel() {
  var unlabeled = GmailApp.search("has:nouserlabels -label:inbox -label:sent -label:chats -label:draft -label:spam -label:trash");
  for (var i = 0; i < unlabeled.length; i++) {
    Logger.log("thread: " + i + " " + unlabeled[i].getFirstMessageSubject());
    labels = unlabeled[i].getLabels();
    var n_labels = 0;
    for (var j = 0; j < labels.length; j++) {
      n_labels += 1;
      Logger.log("labels: " + i + " " + labels[j].getName());
      labels[j].addToThread(unlabeled[i]);
    }
    if (n_labels == 0){
      Logger.log("Add 00_NoLabel");
      unlabeled[i].addLabel(GmailApp.getUserLabelByName("00_NoLabel"));
    }
  }

}

最後のif文のところでラベルが付かずInboxにも無いものに対して00_NoLabelというラベルを付けています。

その前のfor文はスレッド内の他のメールにラベルが付いていた場合、そのラベルをスレッド内の全てのメールに つけるためのループです。 条件によって同じスレッド内でもラベルが付いてたり着いてなかったりすることがありますが、 それに00_NoLabelをつけてしまうとスレッドごと00_NoLabelにも入ってしまい邪魔なので。 なのでこれでチェックもしてラベルがつかなかったら最後に00_NoLabelをつける、ということをしています。

Inbox/アーカイブ対策

Inboxに残すかどうか、という対処はさらに面倒で、今の所完璧なものではありません。

とりあえず、DummyInboxラベルをつけてそれがついてるもの以外はアーカイブ、というフィルタは残しています。

ただし、このフィルタが中途半端な位置で適用されるとその後DummyInboxをつける予定だったものが先にアーカイブされてしまいます。

これを救出するために以下の様なスクリプトを用意します。

updateLabel.gs
1
2
3
4
5
6
7
function inboxCheck() {
  var threads = GmailApp.search("-label:inbox -label:sent -label:trash label:99_DummyInbox");
  for (var i = 0; i < threads.length; i++) {
    Logger.log("thread: " + i + " " + threads[i].getFirstMessageSubject());
    threads[i].moveToInbox();
  }
}

こっちはもっと簡単なスクリプトで、99_DummyInboxラベルが付いていてInboxにないものをInboxに戻す、というもの。

ただこれの問題点は一度アーカイブされてしまうのでスマホへの通知が来なくなることです。 アプリのアイコンに未読数として後から表示はされますが直接の通知は来ません。

フィルタにはアーカイブする、という動作はありますが、逆にInboxに戻すという動作はないので 一度アーカイブするフィルタがかけられてしまうとどうしようもありません。

これでちょっと微妙な動作なんですが、 基本的にInboxに残すメールは最小限にしてるので、能動的にチェックする様にすることで最悪通知がなくても 大丈夫かな、というところで落ち着いています。

まあ、リアルタイムで必要な連絡は友達ならラインなり、仕事でも別のもので来たりするのでそこまできちんと出来なくても大丈夫かな、と。

まとめ

もともとGmailのフィルタは順序を考慮して使うように設計されてないもので 順序がどう決定されるかという記述もどこにもないのですが、 ラベルを振りながらInboxに残すかどうか決めようと思うと順序なしのフィルタだと かなり無理があると思います。

実際問題、他の人がどうやってるのか不思議で仕方ないです。 (Inboxに大量のメールがあっても気にしない人は別の意味で不思議ですが。)

通知そのものを考えないのであればいっそInboxなんか無視して全てラベル分けするだけでも良いかもしれませんし そうしてる人もいるのかもしれません。

どうするのが一番良いのかは人によるとは思いますが、 なんかもうちょっと上手いこと出来ないかな、とはいまさら思ってます。

Sponsored Links
Sponsored Links

« CentOS 7などのSystemdに対応したデーモンプログラムを作る Chrome終了後に完全に終了させる方法 »

}