この記事は Mobb/Repp Advent Calendar の7日目です
Reppのインターフェイス
少し前のエントリで、Reppはインターフェイスだと解説しましたが、実はそのインターフェイスの定義をきちんと書いたドキュメントは存在しません。それは何故かと言うと、まだインターフェイスをどのように固めれば柔軟に今後対応していけるかという確信が、書いている本人である私にないからです。現状の仮実装として、Slackを事実上の対象サービスとして想定した記述ができるように、次のように実装されています。
-
environmentのハッシュを引数に一つ受け取るcallメソッドが実装されている
-
2つの要素からなる配列を返す。サービスに投稿する文字列が1つ目の要素、各サービスごとにオプショナルに解釈してほしい内容をハッシュで2つめの要素に入れる
ReppはRackの模倣をして作られた、各種サービスとBotフレームワークとの間をつなぐ取り決めですが、Rackの取り扱うHTTP(正確にはWebサーバー)の世界とは違い、Botが接続するSlackやShellやChatWorkやLINEや、あるいはHTTPかもしれないサービスとの接続はその形式が多種多様に渡り、抽象化するとどのようにまとまるのかをうまく調整することが難しいのです。
たとえば、SlackにはAttachmentsというチャットの発言とは別にチャットの内容を装飾するための取り決めがありますが、それは他のサービスにはありません。しかし、Reppとしては存在したりしなかったりする内容に関してもきちんと橋渡しをする必要があります。
おさらい:Rackのインターフェイス
ここで、Rackの取り決めを一度おさらいしましょう。
http://rack.github.io/
To use Rack, provide an "app": an object that responds to the call method, taking the environment hash as a parameter, and returning an Array with three elements: > > > * The HTTP response code > > * A Hash of headers > > * The response body, which must respond to each >
Rackの扱うオブジェクトは、environmentというハッシュを一つ引数に取るcallメソッドが定義されている必要があります。そしてそのメソッドは、次の3つの要素からなる配列をリターンします。
-
HTTPのレスポンスコード
-
HTTPヘッダを表すハッシュ
-
レスポンスボディ、ただし each メソッドに応答できること(つまりEnumerableであること)
この取り決めは、HTTPの世界観をミニマルに表しています。HTTPは、リクエストに対してレスポンスコード・ヘッダ・ボディを持つメッセージを返すからです。
Reppが扱う世界観とインターフェイス
Reppが扱うサービスの対象は、少なくともチャットサービスです。そう考えたとき、戻り値として必ず必要になるものは、「対象のサービスに投稿する文字列」です。そのため、Reppは戻り値のハッシュの1番目の要素に、テキストを要求しています(現状、eachに応答する必要はありません)。これは、HTTPにおけるステータスコードとおなじで、どんなリクエストに対しても必ず存在するレスポンスの要素です。
難しいのはここからです。投稿する文字列以外の情報は、サービスによって著しく異なります。
現在考えている案として、ReppもRackと同じく、3つの要素からなる配列を返すようにするよう将来的には想定しています。現状、2つ目の要素のハッシュには、各種情報がギュウギュウに詰め込まれている状態なので、その中からある程度チャットサービスのBotとして必須であろうと思われる情報(例えば、投稿先のチャネル名など)を別のハッシュに切り出して、新しく配列の2番めの要素として入れようと思っています。
現在存在しない3番目の要素には、各サービスに完全に依存した、Reppのハンドラに解釈を委ねる情報を入れようと思っています(例えば、SlackのAttachmentsなど)。
しかし、現状では2番めと3番目のハッシュの区別をどう行うべきか、まだ十分な検討がされていません。それは何故かと言うと、Repp+Mobbの構成が、事実上Slackを使用することを完全に想定しているからです。
Reppのインターフェイスを確定させるために必要なもの
Slackを事実上のリファレンスとしている以上、他の実装が試されなくては、取捨選択の決定を下すことができません。つまり、いまReppに必要なのは、Slack以外のサービスのハンドラです。
現在、LINE用のハンドラと、Discord用のハンドラを、新たに実装しようと考えているところです。時間の都合でまだ公開できるものはありませんが、少なくとも2019年の1月中には公開した上で、その実装の過程で得られた取捨選択をもとにReppのインターフェイスを決定したいと思っています。