Go 言語で Mattermost BOT を作成する
Mattermost と Go 言語で Bot を作ろうとして、リクエストを投げると 403 エラーが出力された。
ソースコード
package main
import (
"fmt"
"net/http"
"net/http/httputil"
"bytes"
"os"
"encoding/json"
)
type BODY struct {
channel_id string
message string
}
func HTTPPost(mes string) {
requestBody := &BODY{
channel_id: "1ngefhpjojyabd9fc7n8twt3xh",
message: "hello",
}
//リクエストbodyをjson.Marshal関数を使って作成する
jsonString, err := json.Marshal(requestBody)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
endpoint := "http://192.168.202.129:80/api/v4/posts"
req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonString))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
//ヘッダーを付与
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization","Bearer jmkk43ic3ib3tenmhycbfj7jre")
req.Header.Set("channel_id", "1ngefhpjojyabd9fc7n8twt3xh")
req.Header.Set("message", "hello")
//リクエストの内容確認
dump, _ := httputil.DumpRequestOut(req, true)
fmt.Printf("%s", dump)
//リクエストを送信
client := new(http.Client)
resp,err := client.Do(req)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer resp.Body.Close()
dumpResp, _ := httputil.DumpResponse(resp, true)
fmt.Printf("%s", dumpResp)
}
//slashコマンドを受け付ける
func slash(w http.ResponseWriter,r *http.Request) {
text := r.FormValue("text")
//fmt.Fprintf(w,"hello %v",text)
//http postする
HTTPPost(text)
}
func main() {
http.HandleFunc("/slash",slash)
http.ListenAndServe(":8090",nil)
}
出力
POST /api/v4/posts HTTP/1.1
Host: 192.168.202.129:80
User-Agent: Go-http-client/1.1
Content-Length: 2
Authorization: Bearer jmkk43ic3ib3tenmhycbfj7jre
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip
{}HTTP/1.1 403 Forbidden
Content-Length: 237
Connection: keep-alive
Content-Type: application/json
Date: Tue, 21 Dec 2021 10:39:41 GMT
Server: nginx
Vary: Accept-Encoding
X-Ratelimit-Limit: 101
X-Ratelimit-Remaining: 98
X-Ratelimit-Reset: 1
X-Request-Id: 5mxe4u7aupd4db89wpbd3wxiae
X-Version-Id: 5.36.0.5.36.0.673343c915db87d44c29a4c208aeb200.false
問題点
403 エラーなので認証がうまく通ってなさそうだった。
Header は問題なさそうだったので、チャンネル ID などの情報が載っている BODY に問題がありそう。
requestBody := &BODY{
channel_id: "1ngefhpjojyabd9fc7n8twt3xh",
message: "hello",
}
//リクエストbodyをjson.Marshal関数を使って作成する
jsonString, err := json.Marshal(requestBody)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
ここを、構造体を使わずにごり押しでやる。
jsonStr := `{"channel_id":"` + "1ngefhpjojyabd9fc7n8twt3xh" + `","message":"` + mes + `"}`
endpoint := "http://192.168.202.129:80/api/v4/posts"
req, err := http.NewRequest(
"POST",
endpoint,
bytes.NewBuffer([]byte(jsonStr)),
)
そしたらできた。