refactor: Refactored the qbot.Message struct to make it easier for upper layers to access the message type

This commit is contained in:
AkashiNeko
2025-03-13 14:09:51 +08:00
parent c50c5595f9
commit aa22682cb8
12 changed files with 169 additions and 62 deletions

View File

@@ -2,15 +2,18 @@ package cmds
import (
"go-hurobot/qbot"
"strconv"
"strings"
)
var MaxCommandLength int = 0
var cmdMap map[string]func(*qbot.Client, []string, *qbot.Message)
type CmdHandler func(*qbot.Client, []string, *qbot.Message)
var cmdMap map[string]CmdHandler
func init() {
cmdMap = map[string]func(*qbot.Client, []string, *qbot.Message){
cmdMap = map[string]CmdHandler{
"echo": cmd_echo,
"rawmsg": cmd_rawmsg,
"grok2": cmd_grok2,
@@ -42,3 +45,11 @@ func decodeSpecialChars(raw string) string {
)
return replacer.Replace(raw)
}
func str2uin64(s string) uint64 {
value, err := strconv.ParseUint(s, 10, 64)
if err != nil {
return 0
}
return value
}

View File

@@ -5,6 +5,6 @@ import (
"strings"
)
func cmd_echo(c *qbot.Client, args []string, raw *qbot.Message) {
c.SendReplyMsg(raw, strings.Join(args[1:], " "))
func cmd_echo(c *qbot.Client, args []string, msg *qbot.Message) {
c.SendReplyMsg(msg, strings.Trim(msg.Raw[4:], " \n"))
}

View File

@@ -25,12 +25,10 @@ func cmd_group(c *qbot.Client, args []string, raw *qbot.Message) {
c.SetGroupName(raw.GroupID, newName)
}
case "op":
// if len(args) < 3 {
// }
c.SendReplyMsg(raw, fmt.Sprintf("已将 %s 设为 WTF 管理员。", raw.Sender.Card))
c.SetGroupAdmin(raw.GroupID, raw.Sender.UserID, true)
c.SendReplyMsg(raw, fmt.Sprintf("已将 %s 设为 WTF 管理员。", raw.Card))
c.SetGroupAdmin(raw.GroupID, raw.UserID, true)
case "deop":
c.SendReplyMsg(raw, fmt.Sprintf("已取消 %s 的 WTF 管理员身份。", raw.Sender.Card))
c.SetGroupAdmin(raw.GroupID, raw.Sender.UserID, false)
c.SendReplyMsg(raw, fmt.Sprintf("已取消 %s 的 WTF 管理员身份。", raw.Card))
c.SetGroupAdmin(raw.GroupID, raw.UserID, false)
}
}

View File

@@ -9,7 +9,7 @@ import (
)
func cmd_psql(c *qbot.Client, args []string, raw *qbot.Message) {
if raw.Sender.UserID != config.MasterID {
if raw.UserID != config.MasterID {
c.SendReplyMsg(raw, fmt.Sprintf("%s: Permission denied", args[0]))
return
}

View File

@@ -13,13 +13,13 @@ import (
var workingDir string = ""
func cmd_sh(c *qbot.Client, args []string, raw *qbot.Message) {
if raw.Sender.UserID != config.MasterID {
c.SendReplyMsg(raw, fmt.Sprintf("%s: Permission denied", args[0]))
func cmd_sh(c *qbot.Client, args []string, msg *qbot.Message) {
if msg.UserID != config.MasterID {
c.SendReplyMsg(msg, fmt.Sprintf("%s: Permission denied", args[0]))
return
}
if len(args) <= 1 {
c.SendReplyMsg(raw, "Usage: sh <linux command>")
c.SendReplyMsg(msg, "Usage: sh <linux command>")
return
}
@@ -27,14 +27,14 @@ func cmd_sh(c *qbot.Client, args []string, raw *qbot.Message) {
if len(args) > 2 {
absPath, err := exec.Command("realpath", strings.TrimSpace(workingDir)).Output()
if err != nil {
c.SendReplyMsg(raw, err.Error())
c.SendReplyMsg(msg, err.Error())
return
}
workingDir = string(absPath)
} else {
workingDir = os.Getenv("HOME")
}
c.SendReplyMsg(raw, workingDir)
c.SendReplyMsg(msg, workingDir)
return
}
@@ -57,13 +57,13 @@ func cmd_sh(c *qbot.Client, args []string, raw *qbot.Message) {
select {
case err := <-done:
if err != nil {
c.SendReplyMsg(raw, fmt.Sprintf("%v\n%s", err, string(output)))
c.SendReplyMsg(msg, fmt.Sprintf("%v\n%s", err, string(output)))
return
}
c.SendReplyMsg(raw, string(output))
c.SendReplyMsg(msg, string(output))
case <-time.After(30 * time.Second):
cmd.Process.Kill()
c.SendReplyMsg(raw, fmt.Sprintf("命令执行超时: %s",
c.SendReplyMsg(msg, fmt.Sprintf("命令执行超时: %s",
strings.Join(args[1:], " ")))
}
}

View File

@@ -3,33 +3,21 @@ package cmds
import (
"go-hurobot/qbot"
"strconv"
"github.com/buger/jsonparser"
)
func cmd_specialtitle(c *qbot.Client, args []string, raw *qbot.Message) {
func cmd_specialtitle(c *qbot.Client, args []string, msg *qbot.Message) {
if len(args) == 1 {
c.SendReplyMsg(raw, "Usage: specialtitle <specialtitle>")
} else if len(raw.Message) > 1 && raw.Message[1].Type != "at" {
c.SendReplyMsg(raw, "群头衔一定是一个文本!")
c.SendReplyMsg(msg, "Usage: specialtitle <specialtitle>")
} else if len(msg.Array) > 1 && msg.Array[1].Type != qbot.At {
c.SendReplyMsg(msg, "群头衔一定是一个文本!")
} else if length := len([]byte(args[1])); length > 18 {
c.SendReplyMsg(raw, "头衔长度不允许超过 18 字节,当前 "+strconv.FormatInt(int64(length), 10)+" 字节")
c.SendReplyMsg(msg, "头衔长度不允许超过 18 字节,当前 "+strconv.FormatInt(int64(length), 10)+" 字节")
} else {
if len(raw.Message) > 1 {
rawJson := raw.Message[1].Data
qqstr, err := jsonparser.GetString([]byte(rawJson), "qq")
if err != nil {
c.SendReplyMsg(raw, err.Error())
return
}
qq, err := strconv.Atoi(qqstr)
if err != nil {
c.SendReplyMsg(raw, err.Error())
return
}
c.SetGroupSpecialTitle(raw.GroupID, uint64(qq), args[1])
if len(msg.Array) > 1 {
id := str2uin64(msg.Array[1].Content)
c.SetGroupSpecialTitle(msg.GroupID, id, args[1])
return
}
c.SetGroupSpecialTitle(raw.GroupID, raw.Sender.UserID, args[1])
c.SetGroupSpecialTitle(msg.GroupID, msg.UserID, args[1])
}
}

View File

@@ -8,14 +8,14 @@ import (
func customReply(c *qbot.Client, msg *qbot.Message) {
// 2025-03-08 晚上,让 bot 在某 mc 群发电加的
if msg.GroupID == 158045531 {
if strings.Contains(msg.RawMessage, "厉厉厉害害害") {
if strings.Contains(msg.Raw, "厉厉厉害害害") {
return
} else if strings.Contains(msg.RawMessage, "厉厉害害") {
c.SendGroupMsg(msg.GroupID, strings.Replace(msg.RawMessage, "厉厉害害", "可可爱爱", -1), false)
} else if strings.Contains(msg.RawMessage, "厉害害") {
c.SendGroupMsg(msg.GroupID, strings.Replace(msg.RawMessage, "厉害害", "可爱爱", -1), false)
} else if strings.Contains(msg.RawMessage, "厉害") {
c.SendGroupMsg(msg.GroupID, strings.Replace(msg.RawMessage, "厉害", "可爱", -1), false)
} else if strings.Contains(msg.Raw, "厉厉害害") {
c.SendGroupMsg(msg.GroupID, strings.Replace(msg.Raw, "厉厉害害", "可可爱爱", -1), false)
} else if strings.Contains(msg.Raw, "厉害害") {
c.SendGroupMsg(msg.GroupID, strings.Replace(msg.Raw, "厉害害", "可爱爱", -1), false)
} else if strings.Contains(msg.Raw, "厉害") {
c.SendGroupMsg(msg.GroupID, strings.Replace(msg.Raw, "厉害", "可爱", -1), false)
}
}
// 2025-03-08 ↑

View File

@@ -24,8 +24,8 @@ func getCommandName(s string) string {
}
func onMessage(c *qbot.Client, msg *qbot.Message) {
if handler := cmds.FindCommand(getCommandName(msg.RawMessage)); handler != nil {
if args, err := shlex.Split(msg.RawMessage); err == nil {
if handler := cmds.FindCommand(getCommandName(msg.Raw)); handler != nil {
if args, err := shlex.Split(msg.Raw); err == nil {
handler(c, args, msg)
}
return

View File

@@ -77,10 +77,10 @@ func (c *Client) SetGroupAdmin(groupID uint64, userID uint64, enable bool) error
return err
}
func (c *Client) SendReplyMsg(raw *Message, message string) {
if raw.GroupID == 0 {
c.SendPrivateMsg(raw.Sender.UserID, message, false)
func (c *Client) SendReplyMsg(msg *Message, message string) {
if msg.GroupID == 0 {
c.SendPrivateMsg(msg.UserID, message, false)
} else {
c.SendGroupMsg(raw.GroupID, message, false)
c.SendGroupMsg(msg.GroupID, message, false)
}
}

View File

@@ -39,9 +39,9 @@ func initPsqlDB(dsn string) error {
func saveDatabase(msg *Message) error {
return PsqlDB.Transaction(func(tx *gorm.DB) error {
user := Users{
UserID: msg.Sender.UserID,
Name: msg.Sender.Nickname,
Nickname: msg.Sender.Card,
UserID: msg.UserID,
Name: msg.Nickname,
Nickname: msg.Card,
}
if err := tx.Clauses(clause.OnConflict{
@@ -56,11 +56,11 @@ func saveDatabase(msg *Message) error {
}
newMessage := Messages{
MsgID: msg.MessageID,
UserID: msg.Sender.UserID,
MsgID: msg.MsgID,
UserID: msg.UserID,
GroupID: msg.GroupID,
Time: time.Unix(int64(msg.Time), 0),
Content: msg.RawMessage,
Content: msg.Raw,
Deleted: false,
}
if err := tx.Create(&newMessage).Error; err != nil {

View File

@@ -4,20 +4,98 @@ import (
"encoding/json"
)
func ParseMsgJson(raw *messageJson) *Message {
if raw == nil {
return nil
}
result := Message{
GroupID: raw.GroupID,
UserID: raw.Sender.UserID,
Nickname: raw.Sender.Nickname,
Card: raw.Sender.Card,
Role: raw.Sender.Role,
Time: raw.Time,
MsgID: raw.MessageID,
Raw: raw.RawMessage,
}
for _, msg := range raw.Message {
var jsonData map[string]string
err := json.Unmarshal([]byte(msg.Data), &jsonData)
if err != nil {
return nil
}
switch msg.Type {
case "text":
result.Array = append(result.Array, MsgItem{
Type: Text,
Content: jsonData["text"],
})
case "image":
result.Array = append(result.Array, MsgItem{
Type: Image,
Content: jsonData["url"],
})
case "record":
result.Array = append(result.Array, MsgItem{
Type: Record,
Content: jsonData["path"],
})
case "at":
result.Array = append(result.Array, MsgItem{
Type: At,
Content: jsonData["id"],
})
case "reply":
result.Array = append(result.Array, MsgItem{
Type: Reply,
Content: jsonData["id"],
})
case "file":
result.Array = append(result.Array, MsgItem{
Type: File,
Content: string(msg.Data),
})
case "forward":
result.Array = append(result.Array, MsgItem{
Type: Forward,
Content: string(msg.Data),
})
case "json":
result.Array = append(result.Array, MsgItem{
Type: Json,
Content: string(msg.Data),
})
default:
result.Array = append(result.Array, MsgItem{
Type: Other,
Content: string(msg.Data),
})
}
}
return &result
}
func (c *Client) handleEvents(postType *string, msgStr *[]byte, jsonMap *map[string]any) {
switch *postType {
case "meta_event":
// heartbeat, connection state..
case "notice":
// TODO
switch (*jsonMap)["notice_type"] {
case "group_recall":
// TODO
}
case "message":
switch (*jsonMap)["message_type"] {
case "private":
fallthrough
case "group":
if c.eventHandlers.onMessage != nil {
msg := &Message{}
if json.Unmarshal(*msgStr, msg) == nil {
msgJson := &messageJson{}
if json.Unmarshal(*msgStr, msgJson) != nil {
return
}
if msg := ParseMsgJson(msgJson); msg != nil {
go saveDatabase(msg)
go c.eventHandlers.onMessage(c, msg)
}

View File

@@ -27,7 +27,39 @@ type Client struct {
}
}
type MsgType int
const (
Text MsgType = 0
Image MsgType = 1
Record MsgType = 2
At MsgType = 3
Reply MsgType = 4
File MsgType = 5
Forward MsgType = 6
Json MsgType = 7
Other MsgType = -1
)
type MsgItem struct {
Type MsgType
Content string
}
type Message struct {
GroupID uint64
UserID uint64
Nickname string
Card string
Role string
Time uint64
MsgID uint64
Raw string
Array []MsgItem
}
type messageJson struct {
GroupID uint64 `json:"group_id"`
Time uint64 `json:"time"`
MessageID uint64 `json:"message_id"`