0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Project 25Advent Calendar 2019

Day 3

Twistのchatbotを拡張してみた

Last updated at Posted at 2019-12-02

昨日作ったchatbotがあのままだと全く実用性がないので、もうちょっとサンプルっぽくしました

昨日作ったもの
https://qiita.com/usk81/items/bfd15ec3c5ecc23d0b8f

Twistに関しては昨日作ったものの記事を参考にしてください

成果物

コメントしたものをそのまま返すようにしました

スクリーンショット 2019-12-02 23.46.22.png

Page: https://github.com/usk81/twistbot
Release: https://github.com/usk81/twistbot/releases/tag/v0.0.1-alpha2

Request Body

Request Bodyはx-www-form-urlencodedで送られているようです。
どうせなので、Structureにおこしてみました。
というか、Developerページと差異があってほぼここの解析に時間使ってました。

StructureへのデコードはGorillaSchemaを使用しました。
https://github.com/gorilla/schema

今回は対応しませんでしたが、リクエストの中にurl_ttlurl_callback というものがあります。
url_ttlにはタイムスタンプ
url_callbackにはURLが格納されています。
リクエストの返却に時間がかかる場合は、一度202で空リクエストを返して、url_ttlで設定されている制限時間内にurl_callbackにリクエストを返せばいいそうです。

type TwistOutgoingRequest struct {
	EventType         string `schema:"event_type"`
	WorkspaceID       int    `schema:"workspace_id"`
	Content           string `schema:"content"`
	UserID            int    `schema:"user_id"`
	UserName          string `schema:"user_name"`
	URLCallback       string `schema:"url_callback"`
	URLTTL            int    `schema:"url_ttl"`
	MessageID         int    `schema:"message_id"`
	ThreadID          int    `schema:"thread_id"`
	ThreadTitle       string `schema:"thread_title"`
	ChannelID         int    `schema:"channel_id"`
	ChannelName       string `schema:"channel_name"`
	CommentID         int    `schema:"comment_id"`
	ConversationID    int    `schema:"conversation_id"`
	ConversationTitle string `schema:"conversation_title"`
	VerifyToken       string `schema:"verify_token"`
}

Handler

修正前

func botHandler(w http.ResponseWriter, r *http.Request) {
	if r == nil {
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("can not get request"))
	}
	defer r.Body.Close()
	bs, _ := ioutil.ReadAll(r.Body)
	w.Write([]byte(fmt.Sprintf("header: %s, body: %s", r.Header.Get("Content-Type"), string(bs))))
}

修正後

デバッグも兼ねて、ログも仕込んでみました。
サーバのログをミドルウェア層をzapで作ったので、ソフトウェア層も揃えました。
https://github.com/uber-go/zap

message_idとかが返ってきてたので、APIでmessage取得しないといけないのかと思ってましたが、contentに平文で入ってました。

func botHandler(w http.ResponseWriter, r *http.Request) {
	lg, _ := zap.NewProduction()
	defer lg.Sync()

	if r == nil {
		lg.Error("can not get request")
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("can not get request"))
	}
	if err := r.ParseForm(); err != nil {
		lg.Warn(fmt.Sprintf("failed to parse request %s", err.Error()))
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte("request is invalid"))
	}
	var req TwistOutgoingRequest
	if err := decoder.Decode(&req, r.PostForm); err != nil {
		lg.Error(fmt.Sprintf("fail to decode parsed request %s : %#v", err.Error(), r.PostForm))
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte(err.Error()))
	}
	w.Write([]byte(req.Content))
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?