napcat: NapCatQQ (OneBot 11) Go SDK, initial release
This commit is contained in:
160
event.go
Normal file
160
event.go
Normal file
@ -0,0 +1,160 @@
|
||||
package napcat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Event 是收到的一条 OneBot 事件。按 PostType 取对应的子事件指针。
|
||||
type Event struct {
|
||||
Time int64 `json:"time"`
|
||||
SelfID int64 `json:"self_id"`
|
||||
PostType string `json:"post_type"`
|
||||
Raw json.RawMessage `json:"-"`
|
||||
|
||||
Message *MessageEvent // post_type == "message" / "message_sent"
|
||||
Notice *NoticeEvent // post_type == "notice"
|
||||
Request *RequestEvent // post_type == "request"
|
||||
Meta *MetaEvent // post_type == "meta_event"
|
||||
}
|
||||
|
||||
type BaseEvent struct {
|
||||
Time int64 `json:"time"`
|
||||
SelfID int64 `json:"self_id"`
|
||||
PostType string `json:"post_type"`
|
||||
}
|
||||
|
||||
// MessageEvent 是私聊/群聊消息事件。bot 自己发出的消息以 message_sent 上报。
|
||||
type MessageEvent struct {
|
||||
BaseEvent
|
||||
MessageType string `json:"message_type"` // private | group
|
||||
SubType string `json:"sub_type"` // friend/group/normal/anonymous/notice
|
||||
MessageID int64 `json:"message_id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
GroupID int64 `json:"group_id"`
|
||||
TargetID int64 `json:"target_id"` // 群临时会话目标
|
||||
TempSource int64 `json:"temp_source"` // 群临时会话来源
|
||||
Message json.RawMessage `json:"message"` // 段数组或 CQ 码字符串
|
||||
RawMessage string `json:"raw_message"`
|
||||
Font int64 `json:"font"`
|
||||
Sender Sender `json:"sender"`
|
||||
}
|
||||
|
||||
// NoticeEvent 是通知事件(撤回、入群、禁言、戳一戳等)。
|
||||
// 未映射的字段收进 Extra,避免 NapCat 增加字段时丢数据。
|
||||
type NoticeEvent struct {
|
||||
BaseEvent
|
||||
NoticeType string `json:"notice_type"`
|
||||
SubType string `json:"sub_type"`
|
||||
GroupID int64 `json:"group_id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
OperatorID int64 `json:"operator_id"`
|
||||
TargetID int64 `json:"target_id"`
|
||||
MessageID int64 `json:"message_id"`
|
||||
Duration int64 `json:"duration"` // 禁言时长(秒)
|
||||
File *FileNotice `json:"file"`
|
||||
HonorType string `json:"honor_type"`
|
||||
CardNew string `json:"card_new"`
|
||||
CardOld string `json:"card_old"`
|
||||
|
||||
Extra map[string]any `json:"-"`
|
||||
}
|
||||
|
||||
func (n *NoticeEvent) UnmarshalJSON(data []byte) error {
|
||||
type alias NoticeEvent
|
||||
var a alias
|
||||
if err := json.Unmarshal(data, &a); err != nil {
|
||||
return err
|
||||
}
|
||||
*n = NoticeEvent(a)
|
||||
|
||||
var m map[string]any
|
||||
if err := json.Unmarshal(data, &m); err == nil {
|
||||
for k := range knownNoticeKeys {
|
||||
delete(m, k)
|
||||
}
|
||||
if len(m) > 0 {
|
||||
n.Extra = m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var knownNoticeKeys = map[string]struct{}{
|
||||
"time": {}, "self_id": {}, "post_type": {}, "notice_type": {}, "sub_type": {},
|
||||
"group_id": {}, "user_id": {}, "operator_id": {}, "target_id": {},
|
||||
"message_id": {}, "duration": {}, "file": {}, "honor_type": {},
|
||||
"card_new": {}, "card_old": {},
|
||||
}
|
||||
|
||||
// FileNotice 是群文件上传/离线文件通知里的文件信息。
|
||||
type FileNotice struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Size int64 `json:"size"`
|
||||
BusID int64 `json:"busid"`
|
||||
}
|
||||
|
||||
// RequestEvent 是好友/群请求事件(加好友、加群、被邀请入群)。
|
||||
type RequestEvent struct {
|
||||
BaseEvent
|
||||
RequestType string `json:"request_type"` // friend | group
|
||||
SubType string `json:"sub_type"` // group 时为 add/invite
|
||||
UserID int64 `json:"user_id"`
|
||||
GroupID int64 `json:"group_id"`
|
||||
Comment string `json:"comment"`
|
||||
Flag string `json:"flag"`
|
||||
}
|
||||
|
||||
// MetaEvent 是元事件(连接生命周期与心跳)。
|
||||
type MetaEvent struct {
|
||||
BaseEvent
|
||||
MetaType string `json:"meta_event_type"` // lifecycle | heartbeat
|
||||
SubType string `json:"sub_type"` // connect/enable/disable
|
||||
HeartbeatInterval int64 `json:"interval"`
|
||||
Status *Status `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func decodeEvent(data []byte) (*Event, error) {
|
||||
var probe struct {
|
||||
PostType string `json:"post_type"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &probe); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if probe.PostType == "" {
|
||||
return nil, fmt.Errorf("napcat: missing post_type: %s", truncate(data))
|
||||
}
|
||||
ev := &Event{Raw: append(json.RawMessage(nil), data...)}
|
||||
var base BaseEvent
|
||||
_ = json.Unmarshal(data, &base)
|
||||
ev.Time, ev.SelfID, ev.PostType = base.Time, base.SelfID, probe.PostType
|
||||
|
||||
switch probe.PostType {
|
||||
case "message", "message_sent":
|
||||
var m MessageEvent
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ev.Message = &m
|
||||
case "notice":
|
||||
var n NoticeEvent
|
||||
if err := json.Unmarshal(data, &n); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ev.Notice = &n
|
||||
case "request":
|
||||
var r RequestEvent
|
||||
if err := json.Unmarshal(data, &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ev.Request = &r
|
||||
case "meta_event":
|
||||
var m MetaEvent
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ev.Meta = &m
|
||||
}
|
||||
return ev, nil
|
||||
}
|
||||
Reference in New Issue
Block a user