キーワードミュート機能

mikutter標準のミュート機能は、すべてのタイムラインからツイートを非表示にします。このセクションでは、キーワードミュートを実現するために、イベントが発生する前にその内容を編集・削除するためのイベントフィルタ機能、またそれを単体で使って、プラグイン間通信を実現する方法について解説します。

コード

今回は、特定の単語の入ったツイートを非表示にします。

# -*- coding: utf-8 -*-

Plugin.create(:mute_word) do

  exclude_words = ["政治","原発"] # フィルタする単語

  filter_show_filter do |msgs|
    msgs = msgs.select{ |m| not exclude_words.any?{ |word| m.to_s.include?(word) } }
    [msgs]
  end

end

解説

イベントフィルタ

  1. イベントの引数を編集する

    プラグインがツイートを取得するためにイベントを使用していることは前のセクションで触れました。今回は、イベントの発生時にそれを捕まえて、引数を書き換えることができる「イベントフィルタ」を使用します。

    フィルタは、Plugin.createのブロック内で以下のように宣言します。

    filter_update do |service, msgs|
      msgs = msgs.select{ |m| not m.to_s.include?("政治") }
      [service, msgs]
    end
    

    イベントが発生すると、イベントと同じ名前のフィルタが登録されていな いか確認して、登録されていたら先にフィルタを実行し、その戻り値を新 たに引数リストにします。なので、普通のイベントと同じように引数を受 け取り、加工した結果を返すことで、イベントの引数を変更できます。

    この場合は、updateイベントで配送されるツイートをすべて確認して、 「政治」「原発」というキーワードが含まれたツイートを削除します。 三行目が戻り値ですが、ここに注目してください。引数を配列で返してい ます。こうやって、加工した値を返してやることで、実際にイベントが発 生する時には、該当するツイートが除外されるようになるわけです。

    一つ注意しなければいけないのは、戻り値の配列は、必ず引数の数と一 致しなければいけないということです。なぜなら、イベントの引数の数 は、今のところ常に固定だからです。

  2. イベントフィルタを使ったプラグイン間の通信

    イベントを使えば、別のプラグインに情報を伝えることができるという のは前に紹介したとおりです。

    しかし、イベントは受け取りたい方がイベントを待ち受けて、発信されるのを待つ必要があります。 実際には受け取り側のリクエストに即座に答えるような通信をしたいことのほうが多いと思われますが、 こういった用途にもイベントフィルタを使用します。

    まず、イベントフィルタは、イベントが発生していなくても単独で呼び出すことができます。

    Plugin.filtering(:update, Post.primary_service, [Instance of Messages...])
    

    この戻り値は、[Post, [Message…]]のような、イベントフィルタの戻 り値そのままです。

    次に、イベントフィルタは、イベントが未定義でも作成できます。

    filter_plus do |num|
      [num + 1]
    end
    

    つまり、直接呼び出されることだけを想定したフィルタを勝手に定義し てしまえば、リクエスト-レスポンス型の通信が実現できるのです。

    1. mikutterから完全に排除するには

      実は、updateイベントのフィルタでは、ホームタイムラインから表示さ れなくなるだけで、他のタイムラインからはフィルタリングできていま せん。この実装のほうがいい場合もあるでしょうが、mikutter上にそも そも表示されないようにしたい場合もあると思います。

      そのためには、タイムラインが表示前にフィルタを呼び出していれば、 そこで削除することができますね。当然、mikutterはミュートを実現す るために、表示する寸前に以下のようなコードでフィルタを呼び出して います。

      Plugin.filtering(:show_filter, message)
      

      つまり、前に書いたupdateフィルタは以下のように書き換えれば、すべ てのタイムラインに影響するようになります。

      filter_show_filter do |msgs|
        msgs = msgs.select{ |m| not m.to_s.include?("政治") }
        [msgs]
      end
      

      show_filterは、notifyプラグインからも使用されていて、TLに表示さ れないツイートはポップアップ通知や効果音も鳴らさないようになって います。こんなふうに、他のプラグインが他の用途のためのフィルタを 使用したり、コールバックを登録することもできます。イベントとフィ ルタをうまく使えば、プラグインそれ自身に拡張性を持たせることがで きます。

まとめ

イベントフィルタについて学びました。 filter_XXX でフィルタを作成し、Plugin.filteringでそれらを利用することができます。