飞书现在被广泛应用,本司也不例外,飞书机器人功能可扩展性还是不错的,这几天研究了一下,发现官方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的部分吧。