mirror of
https://github.com/awfufu/go-hurobot.git
synced 2026-03-01 13:39:42 +08:00
refactor: Refactored the qbot.Message struct to make it easier for upper layers to access the message type
This commit is contained in:
15
cmds/cmds.go
15
cmds/cmds.go
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
18
cmds/sh.go
18
cmds/sh.go
@@ -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:], " ")))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ↑
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
|
||||
Reference in New Issue
Block a user