読者です 読者をやめる 読者になる 読者になる

pockestrap

Web Programmer's memo

mikutterでGETなAPIを叩いて結果を手に入れる

TwitterAPIリファレンスを見れば,実際にAPIを叩くことができるようになります.ここでは例としてプロフィールアイコンと名前を設定してみます.APIhttps://dev.twitter.com/docs/api/1.1/post/account/update_profile_image にまとめられています.これを見ると,Base64エンコードされた700kB以下のGIF,JPG,PNG画像であればアップロードできるようです.基本的にRequestオブジェクトを作成してjsonメソッドを呼べばよいので,割と簡単に実装できます.

require 'base64'
(Service.primary.twitter/'account/update_profile_image').json(:image => Base64.encode64(open('path/to/icon.png').read))
こんな感じでアイコンが変更できます.名前の変更も同様に叩けます.

(Service.primary.twitter/'account/update_profile').json(:name => "ぺんぎんさんだよー")
TwitterAPIが手で叩けるTwitterクライアントはたぶんmikutterだけなので,名前変更芸やアイコン芸が簡単にできそうですね!

http://d.hatena.ne.jp/penguin2716/20130315/1363360196

って感じでmikutterではTwitterAPIを叩けます。便利ですね。

ところが、GETなAPIを叩きたい時はちょっと困ります。
例えば、mikutterコンソールからユーザーのプロフィールを取得するAPIを叩くと、

>>> (Service.primary.twitter/'users/show').json(screen_name: 'p_ck_')
#<Deferred:0x0000000870f500 @follow=#<Thread:0x0000000870f848 sleep>, @callback={:backtrace=>{:ok=>["/opt/mikutter/core/lib/deferred/deferredable.rb:9:in `next'", "/opt/mikutter/core/lib/mikutwitter/api_call_support.rb:73:in `json'", "(eval):1:in `block (3 levels) in <top (required)>'", "/opt/mikutter/core/plugin/console/console.rb:35:in `instance_eval'", "/opt/mikutter/core/plugin/console/console.rb:35:in `block (3 levels) in <top (required)>'", "/opt/mikutter/core/mui/gtk_extension.rb:21:in `call'", "/opt/mikutter/core/mui/gtk_extension.rb:21:in `block in safety_signal_connect'", "/opt/mikutter/core/mui/gtk_extension.rb:39:in `call'", "/opt/mikutter/core/mui/gtk_extension.rb:39:in `block in __track'", "/opt/mikutter/core/plugin/gtk/mainloop.rb:10:in `call'", "/opt/mikutter/core/plugin/gtk/mainloop.rb:10:in `main'", "/opt/mikutter/core/plugin/gtk/mainloop.rb:10:in `mainloop'", "/opt/mikutter/mikutter.rb:62:in `boot!'", "/opt/mikutter/mikutter.rb:80:in `<main>'"]}, :ok=>#<Proc:0x0000000870f550@/opt/mikutter/core/lib/mikutwitter/api_call_support.rb:73>, :ng=>#<Method: Deferred.fail>}>

こんな感じでDeferredクラスのインスタンスが返ってきてしまい、返ってくるはずのjsonを取得できません。

そこで、

(Service.primary.twitter/'users/show').json(screen_name: 'p_ck_').next do |x|
  p x
end

としてやると、mikutterを起動したターミナルにプロフィールがHashで表示されます。
つまり、Deferred#nextのdo-endブロックの引数にAPIを叩いた結果のjsonが入ってるようですね。


ちなみに、Deferredについては
mikutter開発日記: mikutterにDeferred入れたらどうなるのっと
とか

${mikutter_dir}/core/lib/deferred/

とか眺めるとよいと思います。
Deferredは、Threadみたいなもの(理解不足でよくわかってないです)みたいです。
Defrred#nextの実装部分を読んでみると、

### file: core/lib/deferred/deferredable.rb
# なんでもDeferred
module Deferredable

  # このDeferredが成功した場合の処理を追加する。
  # 新しいDeferredのインスタンスを返す
  def next(&proc)
    _post(:ok, &proc)
  end
  alias deferred next
.....

とありますね。Deferredが成功した時に実行されるようです。

私もよく理解できてないのですが、mikutterからAPIを叩いて返ってきたjsonを手に入れる方法でした。
プラグイン開発が捗りそうですね。
jsonを戻り値として取得できないのかなぁ…