go-wxhelper/model/message.go

160 lines
4.1 KiB
Go
Raw Normal View History

2023-09-21 17:33:59 +08:00
package model
2023-12-04 14:17:32 +08:00
import (
"encoding/xml"
"github.com/duke-git/lancet/v2/slice"
2023-12-04 14:17:32 +08:00
"go-wechat/types"
"regexp"
2023-12-04 14:17:32 +08:00
"strings"
)
2023-09-21 17:33:59 +08:00
// Message
// @description: 消息
type Message struct {
2023-12-04 14:17:32 +08:00
MsgId int64 `json:"msgId"`
2023-09-21 17:33:59 +08:00
CreateTime int `json:"createTime"`
Content string `json:"content"`
2023-12-04 14:17:32 +08:00
DisplayFullContent string `json:"displayFullContent"`
2023-09-21 17:33:59 +08:00
FromUser string `json:"fromUser"`
2023-12-04 14:17:32 +08:00
GroupUser string `json:"-"`
2023-09-21 17:33:59 +08:00
MsgSequence int `json:"msgSequence"`
Pid int `json:"pid"`
Signature string `json:"signature"`
ToUser string `json:"toUser"`
Type types.MessageType `json:"type"`
2023-12-11 10:44:23 +08:00
Raw string `json:"raw"`
2023-09-21 17:33:59 +08:00
}
2023-12-04 14:17:32 +08:00
// systemMsgDataXml
// @description: 微信系统消息的xml结构
type systemMsgDataXml struct {
SysMsg sysMsg `xml:"sysmsg"`
Type string `xml:"type,attr"`
}
// atMsgDataXml
// @description: 微信@消息的xml结构
type atMsgDataXml struct {
XMLName xml.Name `xml:"msgsource"`
Text string `xml:",chardata"`
AtUserList string `xml:"atuserlist"`
Silence string `xml:"silence"`
MemberCount string `xml:"membercount"`
Signature string `xml:"signature"`
TmpNode struct {
Text string `xml:",chardata"`
PublisherID string `xml:"publisher-id"`
} `xml:"tmp_node"`
}
2023-12-04 14:17:32 +08:00
// sysMsg
// @description: 消息主体
type sysMsg struct{}
2023-12-07 22:38:49 +08:00
func (m Message) IsGroup() bool {
return strings.HasSuffix(m.FromUser, "@chatroom")
}
2023-12-04 14:17:32 +08:00
// IsPat
// @description: 是否是拍一拍消息
// @receiver m
// @return bool
func (m Message) IsPat() bool {
// 解析xml
var d systemMsgDataXml
if err := xml.Unmarshal([]byte(m.Content), &d); err != nil {
return false
}
return m.Type == types.MsgTypeRecalled && d.Type == "pat"
}
// IsRevokeMsg
// @description: 是否是撤回消息
// @receiver m
// @return bool
func (m Message) IsRevokeMsg() bool {
// 解析xml
var d systemMsgDataXml
if err := xml.Unmarshal([]byte(m.Content), &d); err != nil {
return false
}
return m.Type == types.MsgTypeRecalled && d.Type == "revokemsg"
}
// IsNewUserJoin
// @description: 是否是新人入群
// @receiver m
// @return bool
func (m Message) IsNewUserJoin() bool {
sysFlag := m.Type == types.MsgTypeSys && strings.Contains(m.Content, "\"邀请\"") && strings.Contains(m.Content, "\"加入了群聊")
if sysFlag {
return true
}
// 解析另一种情况
var d systemMsgDataXml
if err := xml.Unmarshal([]byte(m.Content), &d); err != nil {
return false
}
return m.Type == types.MsgTypeSys && d.Type == "delchatroommember"
}
// IsAt
// @description: 是否是At机器人的消息
// @receiver m
// @return bool
func (m Message) IsAt() bool {
return strings.HasSuffix(m.DisplayFullContent, "在群聊中@了你")
}
2023-12-11 10:44:23 +08:00
// IsAtAll
// @description: 是否是At所有人的消息
// @receiver m
// @return bool
func (m Message) IsAtAll() bool {
// 解析raw里面的xml
var d atMsgDataXml
if err := xml.Unmarshal([]byte(m.Signature), &d); err != nil {
return false
}
// 转换@用户列表为数组
atUserList := strings.Split(d.AtUserList, ",")
// 判断是否包含@所有人
return slice.Contain(atUserList, "notify@all")
}
2023-12-11 10:44:23 +08:00
// IsPrivateText
// @description: 是否是私聊消息
// @receiver m
// @return bool
func (m Message) IsPrivateText() bool {
// 发信人不以@chatroom结尾且消息类型为文本
return !strings.HasSuffix(m.FromUser, "chatroom") && m.Type == types.MsgTypeText
}
// CleanContentStartWith
// @description: 判断是否包含指定消息前缀
// @receiver m
// @param prefix
// @return bool
func (m Message) CleanContentStartWith(prefix string) bool {
content := m.Content
// 如果是@消息,过滤掉@的内容
if m.IsAt() {
re := regexp.MustCompile(`@([^| ]+)`)
matches := re.FindStringSubmatch(content)
if len(matches) > 0 {
// 过滤掉第一个匹配到的
content = strings.Replace(content, matches[0], "", 1)
}
}
// 去掉最前面的空格
content = strings.TrimLeft(content, "")
content = strings.TrimLeft(content, " ")
return strings.HasPrefix(content, prefix)
}