-
Notifications
You must be signed in to change notification settings - Fork 9
/
proto_action_request.go
133 lines (124 loc) · 3.92 KB
/
proto_action_request.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// OneBot Connect - 数据协议 - 动作请求
// https://12.onebot.dev/connect/data-protocol/action-request/
package libonebot
import (
"errors"
"github.com/botuniverse/go-libonebot/utils"
"github.com/mitchellh/mapstructure"
"github.com/tidwall/gjson"
"github.com/vmihailenco/msgpack/v5"
)
const (
CommMethodNone = 0 // 无通信方式 (OneBot 实现内部构造的请求)
CommMethodHTTP = 1 // HTTP 通信方式
CommMethodHTTPWebhook = 2 // HTTP Webhook 通信方式
CommMethodWS = 3 // WebSocket 通信方式
CommMethodWSReverse = 4 // 反向 WebSocket 通信方式
)
// RequestCommMethod 表示接收动作请求的通信方式.
type RequestComm struct {
Method int // 通信方式
Config interface{} // 通信方式配置
}
// Request 表示一个动作请求.
type Request struct {
Comm RequestComm // 接收动作请求的通信方式
Action string // 动作名称
Params EasierMap // 动作参数
Echo string // 动作请求的 echo 字段, 用户未指定时为空字符串
Self *Self // 机器人自身标识, 用户未指定时为 nil
}
func parseRequestFromMap(m map[string]interface{}, reqComm RequestComm) (r Request, err error) {
em := EasierMapFromMap(m)
action, err := em.GetString("action")
if err != nil {
err = errors.New("`action` 字段不存在或类型错误")
return
} else if action == "" {
err = errors.New("`action` 字段为空")
return
}
params, err := em.GetMap("params")
if err != nil {
err = errors.New("`params` 字段不存在或类型错误")
return
}
_, err1 := em.Get("echo")
echo, err2 := em.GetString("echo")
if err1 == nil && err2 != nil {
err = errors.New("`echo` 字段类型错误")
return
}
var self *Self
self_raw, err_exist := em.Get("self")
if err_exist == nil {
tmp := Self{}
err = mapstructure.Decode(self_raw, &tmp)
if err != nil || tmp.Platform == "" || tmp.UserID == "" {
err = errors.New("`self` 字段类型错误")
return
}
self = &tmp
}
r = Request{
Comm: reqComm,
Action: action,
Params: params,
Echo: echo,
Self: self,
}
return r, nil
}
func decodeRequest(actionBytes []byte, isBinary bool, reqComm RequestComm) (Request, error) {
var actionRequestMap map[string]interface{}
if isBinary {
err := msgpack.Unmarshal(actionBytes, &actionRequestMap)
if err != nil || actionRequestMap == nil {
return Request{}, errors.New("不是一个 MsgPack 映射")
}
} else {
if !gjson.ValidBytes(actionBytes) {
return Request{}, errors.New("不是合法的 JSON")
}
m, ok := gjson.Parse(utils.BytesToString(actionBytes)).Value().(map[string]interface{})
if !ok || m == nil {
return Request{}, errors.New("不是一个 JSON 对象")
}
actionRequestMap = m
}
return parseRequestFromMap(actionRequestMap, reqComm)
}
func decodeRequestList(actionBytes []byte, isBinary bool, reqComm RequestComm) ([]Request, error) {
var actionRequestMapList []map[string]interface{}
if isBinary {
err := msgpack.Unmarshal(actionBytes, &actionRequestMapList)
if err != nil || actionRequestMapList == nil {
return nil, errors.New("不是一个 MsgPack 映射数组")
}
} else {
if !gjson.ValidBytes(actionBytes) {
return nil, errors.New("不是合法的 JSON")
}
m, ok := gjson.Parse(utils.BytesToString(actionBytes)).Value().([]interface{})
if !ok || m == nil {
return nil, errors.New("不是一个 JSON 数组")
}
actionRequestMapList = make([]map[string]interface{}, 0, len(m))
for _, v := range m {
mm, ok := v.(map[string]interface{})
if !ok || mm == nil {
return nil, errors.New("不是一个 JSON 对象数组")
}
actionRequestMapList = append(actionRequestMapList, mm)
}
}
requests := make([]Request, 0, len(actionRequestMapList))
for _, actionRequestMap := range actionRequestMapList {
r, err := parseRequestFromMap(actionRequestMap, reqComm)
if err != nil {
return nil, err
}
requests = append(requests, r)
}
return requests, nil
}