🗽
Slack コマンドを dump する方法
目的
Slack コマンドの HTTP リクエストをまるごと dump したいです。
この記事では認証について扱わないです。
dump するためのローカルサーバ
とりあえずHTTPリクエストを dump するためのローカルサーバ(Go)を立てます。
ソースコード
package main
import (
"fmt"
"net/http"
"net/http/httputil"
"github.com/sirupsen/logrus"
)
func main() {
http.HandleFunc("/hello", helloHandler)
http.ListenAndServe(":8000", nil)
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
dumpedReq, err := httputil.DumpRequest(r, true)
if err != nil {
logrus.Error(err)
}
fmt.Println(string(dumpedReq))
w.Write([]byte("Hello, world!"))
}
起動
$ go run ./...
Slackのリモートサーバから叩けるように ngrok で公開
Slack コマンドは、ローカルではなく、Slackbot というクライアントから Slack 側のサーバで送られるようなので、ローカルサーバ(localhost)は Webhook 用の URL に設定することはできません。
ngrok を使って、リモートサーバから叩けるようにローカルサーバを一時的に公開します(終わったらさっさと切りましょう)。
$ ngrok http 8000
HTTPS URL をコピーします (これを URL A
と置きます)。
Slack アプリ+コマンドを作成
作ったアプリをインストールする。
先ほど作成した URL A
を slash コマンドの URL に設定します。
実際に Slack でコマンドを実行します。
/hello
ローカルサーバに dump されたリクエストが表示される
ローカルサーバに dump されたリクエストが表示されます。
(セキュリティ観点からいくつか隠していますが、実際は全て確認できます)
POST /hello HTTP/1.1
Host: <hostname>
Accept: application/json,*/*
Accept-Encoding: gzip,deflate
Content-Length: 100
Content-Type: application/x-www-form-urlencoded
User-Agent: Slackbot 1.0 (+https://api.slack.com/robots)
X-Forwarded-For: <ip address>
X-Forwarded-Proto: https
X-Slack-Request-Timestamp: <timestamp>
X-Slack-Signature: v0=<長い文字列>
token=<token>&team_id=<team_id>&team_domain=<team_domain>&channel_id=<channel_id>&channel_name=general&user_id=<slack user id>&user_name=zawawahoge&command=%2Fhello&text=&api_app_id=<api_app_id>&is_enterprise_install=false&response_url=https%3A%2F%2Fhooks.slack.com....&trigger_id=<trigger_id>
まとめ
ローカルに立てたサーバを ngrok で公開し、SlackコマンドのURLとして設定すると、Slackbot からのリクエストを確認できます。
おまけ
Slack コマンドを受けるサーバはこのままだと、どこからも叩かれる危険なサーバになるので、実際のサーバでは、何らかの方法でリクエストを認証する必要があります。
そのために、 X-SlackSignature
というものがあり、 HMAC を用いてデータ完全性や信頼性をチェックすることができます。
(この辺もおいおい記事にします。)
Discussion