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

golangでidobataのbotを書く

前提条件

  • idobataを使っている
  • idobata botがどうやって動いているのか知らないので、知りたい欲求がある
  • golangはほとんど書けないが、練習のためにgolangで書く
  • websocketについては、複数クライアントでのお絵かき同期サンプルを作ったことがある程度の知識

目標

  • botにリプライしたら返事ができる

調査内容

  • 自分が読んで意味のわかる言語Rubyで書かれているruboty-idobataのコードを読む
  • なんとなくPusherを使っているっぽいことがわかる
  • Pusherはwebsocket機能をやってくれるBaaSっぽい。ようはwebsocketを使っている
  • Pusherはgoでかかれたライブラリpusher/pusher-http-goを公式に提供している
  • idobataはbotのkeyがわかれば投稿自体はすぐできる
  • リプライされる事を知るためにはwebsocketで投稿を監視しなければならない

獲得情報

  • Pusherの公式ライブラリpusher/pusher-http-goは、サーバー機能実装をサポートするためのものであって、websocketは使っていない。つまりクライアントになる機能がない。おそらくはJSやiOS/Android端末ぐらいしかクライアントとして使われないだろうとの予測と思われる。
  • Pusherの公式クライアントがないのでwebsocketから直接通信するしかない(謎の確信)。というかそこが知りたい
  • websocketは基本的に生socketのように、Read/Writeすればいい(ようにライブラリーでラップされている)
  • websocketでは、たいていのアプリではただの文字列ではなく、情報を構造化してJSONでやりとりしている。ようはアプリが勝手に決めている取り決め。
  • さらに、websocketでよく見る「なんとかイベントが来たら、このコールバックを呼び出す」という実装も、websocketの通信上どういうデータが次に来るのかはわからないので、イベント名とデータ(JSON)のセットをアプリで取り決めて、実装しやすいようにしているだけ。本質はただ文字列をRead/Writeしているだけ。
  • websocketのgolangライブラリはgolang-samples/websocketで使われているgolang.org/x/net/websocketでいいだろう。golang界隈のライブラリ事情はよくわからないが、mattnさんが使っているのならまちがいない
  • 通信の順番はruboty-idobataを参考にすればいい
  • JSONからstructに書き起こすのが面倒だと思ったら、自動化してくれるサイトがあった( http://json2struct.mervine.net/ )。便利

成果物

疑問点

  • 一度idobataへメッセージを投稿すると、なぜかwebsocket側では二回同じメッセージを受け取ってしまうので、二回websocketをReadしなければならなかった。yasslab/ruboty-idobataではそんなことはしていないようなので、何か手順を間違えているのかもしれない。
  • websocketのプロトコルが深いところまではわからなかった。結局tcp-socketをいい感じの取り決めでRead/Writeしてるだけなんだろうか。
  • golangのセオリー的なものがまだよくわからないので書き方は模索中

妄想

  • JSONじゃなくてMessagePackでもよさそう。websocket.MessagePack.Receive()とか。

注意事項

  • idobataのAPIはすべて公式に公開しているわけではなく、仕様が変わる可能性が大いにある