おっさんのダベリ

IT系の技術的な話題が多いです

GAE版goslashサンプルで開発モードを実装してみる

goslashのサンプルをちょっと変えてみて、GAEをローカルで動かした時にデバッグしやすい修正をしてみました。

まぁGAE使っている人は知っているよ、という内容だと思います。

やりたいこと

goslashでは、Pluginを呼び出した際にSlackから渡されたresponse_urlに対してレスポンスをPOSTします。 ただし、ローカルで動かした場合にはSlackから呼び出されるわけではないため、response_urlは存在しないこともあります。 このような場合にPluginのデバッグを行うために、ローカルで動かした場合にはリクエストのレスポンスとして、送信内容を返すようにしてみたいと思います。

どうやったか

具体的なコードは以下のようになります(一部)

if appengine.IsDevAppServer() {
    // (1) 開発用サーバの場合
    cmd, _ := req.CmdArgs()
    p, ok := slashPlugins[cmd]
    if !ok {
        renderer.JSON(w, http.StatusNotFound, "cmd not found")
        return
    }

    // (2) リクエストに対するPluginの実行結果をJSONにしてレスポンスとして返す
    msg := p.Do(req)
    var jsonData bytes.Buffer
    if err := json.NewEncoder(&jsonData).Encode(&msg); err != nil {
        renderer.JSON(w, http.StatusInternalServerError, err.Error())
        return
    }
    renderer.JSON(w, http.StatusOK, jsonData.String())
} else {
    // (3) 本番環境の場合
    renderer.Text(w, http.StatusOK, slashCmd.Execute(req))
}

(1) 開発用サーバの判定

開発サーバかどうかは、appengineのIsDevAppServer() APIで判定できます。 この条件が真になった場合には、呼び出し元にレスポンスとして返す処理を実行します。

(2) リクエストに対するPluginの実行結果をJSONにしてレスポンスとして返す

ここのpはそれぞれのPluginの実装になります。 Doメソッドで、リクエストに対する個々のメッセージを作成します。 作成したメッセージはJSONデータとしてエンコードし、リクエストに対するレスポンスとして呼び出し元に返します。

(3) 本番環境の場合

もとのサンプルと同様の処理を実装しています。

動かしてみる

curlで実行した結果は次のようになりました。

$ curl -X POST -d "text=time" http://localhost:8080/v1/cmd
"{\"response_type\":\"in_channel\",\"text\":\"2016-08-08T16:31:26Z\"}\n"

ちょっとしたPluginの確認ならば、簡単にできますね。

具体的なコードは、この辺に置いときます。 https://github.com/yhanada/goslash-sample-gae