Help us understand the problem. What is going on with this article?

Twistのchatbotを拡張してみた

昨日作った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))
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした