飞书机器人交互demo golang版

  • 发布于: 18 June 2020
  • 编辑: 628财经

飞书现在被广泛应用,本司也不例外,飞书机器人功能可扩展性还是不错的,这几天研究了一下,发现官方demo只有python版本的,不太方便go的用户拓展,所以抽时间将官方的python版改写为go版本,将每个函数都用go重新写了一下,并将代码放上来,供大家参考。

//主函数的部分如下:
package main

import (
   "encoding/json"
   "fmt"
   "io/ioutil"
   "log"
   "net/http"
)
var err error
var Port = ":8086"
var APP_ID = "cli_xxxxxxxxxxx"
var APP_SECRET = "J6pwxxxxxxxxxxxxxxgEwc"
var APP_VERIFICATION_TOKEN = "9Y7nTn5d1CxxxxxxxxxxxxxxaeYOC"
func myHandler(w http.ResponseWriter, r *http.Request) {
   var bodyContent ReqBody
   bodyData, err := ioutil.ReadAll(r.Body)
   if err != nil {
      return
   }else{
      err = json.Unmarshal(bodyData, &bodyContent)
      if bodyContent.Token != APP_VERIFICATION_TOKEN{
         fmt.Printf("verification token not match, token =%v", bodyContent.Token)
         return
      }
      if bodyContent.Type == "url_verification"{
         rsp:=handle_request_url_verify(bodyData)
         w.Header().Set("Content-Type", "application/json")
         w.WriteHeader(200)
         _, _ = w.Write(rsp)

      }else if bodyContent.Type == "event_callback"{
         if bodyContent.Event.Type=="message"{
            handle_message(bodyContent)
         }
      }
      //fmt.Printf(string(bodyData))
   }
}

func main(){
   http.HandleFunc("/", myHandler)       // 设置访问路由
   fmt.Printf("start at port%v\n",Port)
   log.Fatal(http.ListenAndServe(Port, nil))

}

其他函数的部分如下:

package main

import (
   "bytes"
   "encoding/json"
   "fmt"
   "io/ioutil"
   "net/http"
)

type ReqBody struct {
   UUID  string `json:"uuid"`
   Event struct {
      AppID            string `json:"app_id"`
      ChatType         string `json:"chat_type"`
      IsMention        bool   `json:"is_mention"`
      LarkVersion      string `json:"lark_version"`
      MessageID        string `json:"message_id"`
      MsgType          string `json:"msg_type"`
      OpenChatID       string `json:"open_chat_id"`
      OpenID           string `json:"open_id"`
      OpenMessageID    string `json:"open_message_id"`
      ParentID         string `json:"parent_id"`
      RootID           string `json:"root_id"`
      TenantKey        string `json:"tenant_key"`
      Text             string `json:"text"`
      TextWithoutAtBot string `json:"text_without_at_bot"`
      Type             string `json:"type"`
      UserAgent        string `json:"user_agent"`
      UserOpenID       string `json:"user_open_id"`
   } `json:"event"`
   Token string `json:"token"`
   Ts    string `json:"ts"`
   Type  string `json:"type"`
   Challenge string `json:"challenge"`
}

type Challenge struct {
   Challenge string `json:"challenge"`
   Token     string `json:"token"`
   Type      string `json:"type"`
}
type Challenge1 struct {
   Challenge string `json:"challenge"`
}

type Tenant_access struct {
   Code              int    `json:"code"`
   Msg               string `json:"msg"`
   TenantAccessToken string `json:"tenant_access_token"`
   Expire            int    `json:"expire"`
}

type Send_meg struct {
   OpenID  string `json:"open_id"`
   MsgType string `json:"msg_type"`
   Content struct {
      Text string `json:"text"`
   } `json:"content"`
}

type Access_token struct {
   App_id string `json:"app_id"`
   App_secret string `json:"app_secret"`
}
type Send_callback struct {
   Code int    `json:"code"`
   Msg  string `json:"msg"`
   Data struct {
      MessageID string `json:"message_id"`
   } `json:"data"`
}

func handle_request_url_verify(post_obj_byte []byte)[]byte{

   var post_obj Challenge
   var challenge Challenge1
   err = json.Unmarshal(post_obj_byte, &post_obj)
   challenge.Challenge = post_obj.Challenge
   rsp,_ := json.Marshal(challenge)
   return rsp
}

func get_tenant_access_token()string{
   var jsonData Access_token
   var bodyContent Tenant_access
   url := "http://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/"
   jsonData.App_id=APP_ID
   jsonData.App_secret=APP_SECRET
   jsonStr,err := json.Marshal(jsonData)
   req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
   req.Header.Set("Content-Type", "application/json")
   client := &http.Client{}
   resp, err := client.Do(req)
   if err != nil {
      // handle error
   }
   defer resp.Body.Close()
   //statuscode := resp.StatusCode
   //hea := resp.Header
   body, _ := ioutil.ReadAll(resp.Body)
   err = json.Unmarshal(body, &bodyContent)
if bodyContent.Code != 0{
   fmt.Printf("get tenant_access_token error, code =%v", bodyContent.Code)
}
   //fmt.Println(string(body))
   //fmt.Println(statuscode)
   //fmt.Println(hea)
   return bodyContent.TenantAccessToken
}


func send_message(token string, open_id string, text string) {
   url := "http://open.feishu.cn/open-apis/message/v4/send/"
   var send_meg Send_meg
   var bodyContent Send_callback
   send_meg.OpenID = open_id
   send_meg.MsgType = "text"
   send_meg.Content.Text = text
   jsonStr, err := json.Marshal(send_meg)
   req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
   req.Header.Set("Content-Type", "application/json")
   req.Header.Set("Authorization", "Bearer " + token)
   client := &http.Client{}
   resp, err := client.Do(req)
   if err != nil {
      // handle error
   }
   defer resp.Body.Close()
   body, _ := ioutil.ReadAll(resp.Body)
   err = json.Unmarshal(body, &bodyContent)
   if bodyContent.Code != 0{
      fmt.Printf("get tenant_access_token error, code =%v, msg =%v", bodyContent.Code,bodyContent.Msg)
   }
}

func handle_message (Content ReqBody){
   //var w http.ResponseWriter
   if Content.Event.Type != "text"{
      fmt.Printf("unknown msg_type =%v\n", Content.Event.Type)
      //return
   }
   access_token := get_tenant_access_token()
   if access_token == ""{
      return
   }
   send_message(access_token, Content.Event.OpenID, Content.Event.Text)
   //response(w,[]byte(""))
   return
}

这个默认是不支持加密通信的,需要使用加密通信的小伙伴自己写aes的部分吧。