ginを使ってslackのSlashCommandsを実行した時のapiサーバーを作っていた。
slackは指定したapiに対して以下のような情報をpostしてくれる
(当初bodyで飛んできていると思い込んでおり、この形でpostされていることに気づくのに時間がかかった)
token=gIkuvaNzQIHg97ATvDxqgjtO
&team_id=T0001
&team_domain=example
&enterprise_id=E0001
&enterprise_name=Globular%20Construct%20Inc
&channel_id=C2147483705
&channel_name=test
&user_id=U2147483697
&user_name=Steve
&command=/weather
&text=94070
&response_url=https://hooks.slack.com/commands/1234/5678
&trigger_id=13345224609.738474920.8088930838d88f008e0
参考: https://api.slack.com/interactivity/slash-commands
上記の内容を以下のように受け取ろうとしていた。
type Body struct {
Token string `json:"token"`
TeamID string `json:"team_id"`
TeamDomain string `json:"team_domain"`
ChannelID string `json:"channel_id"`
ChannelName string `json:"channel_name"`
UserID string `json:"user_id"`
UserName string `json:"user_name"`
Command string `json:"command"`
Text string `json:"text"`
ResponseURL string `json:"response_url"`
TriggerID string `json:"trigger_id"`
}
func Post(c *gin.Context) {
var body Body
err := c.BindJSON(&body)
// some code
}
実行すると、BindJSONに失敗して以下のようなエラーがでた。
invalid character 'o' in literal true (expecting 'r')
これがslackから飛んで来ているが、見てわかる通り、JSONじゃない。
token=gIkuvaNzQIHg97ATvDxqgjtO
&team_id=T0001
&team_domain=example
&enterprise_id=E0001
&enterprise_name=Globular%20Construct%20Inc
&channel_id=C2147483705
&channel_name=test
&user_id=U2147483697
&user_name=Steve
&command=/weather
&text=94070
&response_url=https://hooks.slack.com/commands/1234/5678
&trigger_id=13345224609.738474920.8088930838d88f008e0
ginでQueryStringを構造体にbindするには、ShouldBindやBindが使える。
(ShouldBind、Bindはエラーハンドリングを自分でやるかどうかで使い分ける)
以下のように書き換えたらちゃんとslackから飛んで来たパラメータが受け取れた。
type Body struct {
Token string `form:"token"`
TeamID string `form:"team_id"`
TeamDomain string `form:"team_domain"`
ChannelID string `form:"channel_id"`
ChannelName string `form:"channel_name"`
UserID string `form:"user_id"`
UserName string `form:"user_name"`
Command string `form:"command"`
Text string `form:"text"`
ResponseURL string `form:"response_url"`
TriggerID string `form:"trigger_id"`
}
func Post(c *gin.Context) {
var body Body
err := c.Bind(&body)
// some code