Ubuntu Weekly Recipe

第426回Twitterクライアントのmikutterに日本語を話してもらおう(前編)

Ubuntuで利用可能なTwitterクライアントとして、mikutterがあります。前編ではこのmikutterをインストールして動かします。またmikutterのプラグインインターフェイスについて概説し、後編のプラグイン開発の準備を行います。

インストール

mikutterとは、Rubyで書かれたTwitterクライアントです。開発者は日本の方で、ウェブサイトはある種のユーモアに溢れています。ユーザー会が存在し、根強い人気に支えられたプロジェクトです。

Ubuntuのリポジトリにはmikutterのパッケージが収録されており、Ubuntuソフトウェアセンターからインストールできます。

図1 Ubuntuソフトウェアでmikutterを検索
画像

基本設定とみくったーちゃん

UnityのDashを使ってmikutterを起動すると、以下のウィンドウが開きます。

図2 インストール直後のウィンドウ
画像

「次へ」ボタンを押すと、マスコットキャラクターである「みくったーちゃん」が自己紹介してくださいます。みくったーちゃんは親切にも、Twitterのアカウント登録を促してくださいます。なお、公式ウェブページなどでみくったーちゃんのお姿を拝見できます。

図3 アカウントの登録方法
画像

提示してくださったURLをクリックすると、ウェブブラウザが起動します。Twitterサービスにログイン済みの場合、以下のページが開きます。

図4 Twitterサービスでmikutterを許可する
画像

ご厚意に感謝しつつ「連携アプリを認証」ボタンをクリックすると、ページが遷移してPINコードが表示されます。このPINコードをmikutterに登録すると、mikutter経由でTwitterのサービスを利用できます。mikutterのウィンドウにタイムラインを表示してくださいます。

実績とチュートリアル

mikutterの操作説明には「実績」というアイディアが使われています。⁠実績」とはビデオゲームで使われる手法で、あらかじめ用意された特定の条件をプレイヤーが達成したことを意味します。達成したことを「解除」と表現します。mikutterではこの「実績」システムを、使い方チュートリアルとして実装しています。

現在はTwitterアカウントの登録操作を終えたところなので、⁠register_account」という実績を解除したことになります。みくったーちゃんが祝福してくださいます。実績に関する案内を一通り読むと、今度は「tutorial」という実績が解除され、再び祝福してくださいます。

図5 実績解除に対するみくったーちゃんの祝福
画像

他にも実績が用意されているので、いろいろな操作を試してみてください。

プラグインプログラミングインターフェイス

mikutterはプラグインのためのプログラミングインターフェイスを提供しています。プラグインを利用する、あるいは書くことで、mikutterの機能を増やすことができます。前章で述べた実績システムも、Achievementプラグインとして実装されています。

プラグインの構成要素

プラグインは、ユーザーのホームディレクトリの「~/.mikutter/plugin」以下に配置する作法となっています。mikutterのコマンドライン機能を使うと、プラグインの雛形を作成できます。

試しに、⁠my_dump」というプラグインを作ってみます。端末を開いて以下のコマンドを実行してください。

$ mikutter generate my_dump
directory generated: /home/mocchi/.mikutter/plugin/my_dump
file generated: /home/mocchi/.mikutter/plugin/my_dump/my_dump.rb

出力されたファイルの内容を確認すると、以下となります。

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

Plugin.create(:my_dump) do

end

このブロックがプラグインのエントリーポイントとなります。基本的には、mikutterの提供するイベントに対し、ハンドラを登録する処理を書くことになります。イベントやハンドラについては後述します。

プラグインは定義ファイルを持つことを推奨されています。mikutterのコア機能は、解釈可能な定義ファイルを見つけるとプラグインのコードをパースし始めます。定義ファイルはymlフォーマットのテキストです。この定義ファイルもまた、mikutterのコマンドライン機能を使って作成できます。

$ mikutter spec ~/.mikutter/plugin/my_dump/
my_dump: name> my_dump
my_dump: description> Plulgin tutorial to dump tweet
---
slug: :my_dump
depends:
  mikutter: 3.3.6
  plugin: []
version: '1.0'
author: 
name: my_dump
description: Plugin tutorial to dump tweet

プラグインに最低限要求されるのは、これら2つのファイルです。

プラグインのロード確認

それではプラグインをロードしてみましょう。今回はプラグインが読み込まれたことがわかるよう、以下のようにコードを変更し、適当な文字列を出力するようにします。

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

Plugin.create(:my_dump) do
    p('my_plugin')
end

標準出力された文字列がわかるよう、mikutterを端末で起動します。適当な端末ソフトウェアを起動し、mikutterコマンドを実行してください。

$ mikutter
"my_plugin"

上のように、⁠my_plugin」という文字列が出力されたら成功です。もし出力されなかった場合は、プラグインのファイルの配置場所やコードの内容を確認してください。デバッグには、mikutterのdebugモードが有用です。このモードを利用するには、⁠--debug」引数を与えてmikutterコマンドを実行します。以下の出力から、今回のプラグインがロードされたことがわかります。

$ mikutter --debug
...
notice: {MIKUTTER_DIR}/core/miquire_plugin.rb:135:in `load': plugin loaded: /home/mocchi/.mikutter/plugin/my_plugin/my_plugin.rb
...

フックイベントとハンドラ

これだけだとプラグインがロードされた時にしか処理を行うことができません。mikutterにはフックイベントが設けられており、⁠タイムラインが更新された」「リツイートされた」といった、非同期な事象に対する処理を実装できます。このような処理のことをハンドラと呼びます。

試しに、タイムラインが更新されたというイベントに対応するハンドラを書き、その処理タイミングを確認しましょう。コードを以下のように変更します。

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

Plugin.create(:my_dump) do
    onupdate do |service, messages|
        p('updated')
    end
end

mikutterを端末ソフトウェアで実行してしばらく待つと、適当なタイミングで「updated」が出力されるはずです。このイベントはserviceとmessagesという2つの引数をブロックに渡します。messages変数はツイート1つ1つを表現するMessagesクラスのインスタンスの配列であり、例えば以下のようにするとツイート内容を出力できます。

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

Plugin.create(:my_dump) do
    onupdate do |service, messages|
        for message in messages do
            if message.respond_to?('body') then
                p(message.body())
            end
        end
    end
end

プラグインのブロックの実行コンテキスト

処理を記述したブロックですが、実行コンテキストはPluginクラスのインスタンスです。このインスタンスはmy_dump専用に確保されたものです。そのため、Pluginを継承したクラスを用意すると、ブロック内からselfキーワードを用いてそのクラスのインスタンスを参照できます。

下の例は、ツイートの内容を出力するメソッドを実装したクラスを用意し、それを呼び出すサンプルです。筆者はmikutterの名前空間のポリシーについて詳しくないため、ここではクラスをグローバルな名前空間に追加しています。

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

class MyPlugin < Plugin
    def dump(message)
        p(message)
    end
end

MyPlugin.create(:my_dump) do
    onupdate do |service, messages|
        for message in messages do
            if message.respond_to?('body') then
                self.dump(message.body())
            end
        end
    end
end

まとめ

今回は素敵なTwitterクライアントであるmikutterの使い方と、プラグイン作成の簡単なチュートリアルをお届けしました。次回後編では本連載の第250回第251回を参考に、ツイートが増える度にその内容を音声出力するプラグインを書きます。

おすすめ記事

記事・ニュース一覧