286 lines
9.1 KiB
Go
286 lines
9.1 KiB
Go
package openwechat
|
||
|
||
import "strings"
|
||
|
||
// MessageHandler 消息处理函数
|
||
type MessageHandler func(msg *Message)
|
||
|
||
// MessageDispatcher 消息分发处理接口
|
||
// 跟 DispatchMessage 结合封装成 MessageHandler
|
||
type MessageDispatcher interface {
|
||
Dispatch(msg *Message)
|
||
}
|
||
|
||
// MessageContextHandler 消息处理函数
|
||
type MessageContextHandler func(ctx *MessageContext)
|
||
|
||
type MessageContextHandlerGroup []MessageContextHandler
|
||
|
||
// MessageContext 消息处理上下文对象
|
||
type MessageContext struct {
|
||
index int
|
||
abortIndex int
|
||
messageHandlers MessageContextHandlerGroup
|
||
*Message
|
||
}
|
||
|
||
// Next 主动调用下一个消息处理函数(或开始调用)
|
||
func (c *MessageContext) Next() {
|
||
c.index++
|
||
for c.index <= len(c.messageHandlers) {
|
||
if c.IsAbort() {
|
||
return
|
||
}
|
||
handle := c.messageHandlers[c.index-1]
|
||
handle(c)
|
||
c.index++
|
||
}
|
||
}
|
||
|
||
// IsAbort 判断是否被中断
|
||
func (c *MessageContext) IsAbort() bool {
|
||
return c.abortIndex > 0
|
||
}
|
||
|
||
// Abort 中断当前消息处理, 不会调用下一个消息处理函数, 但是不会中断当前的处理函数
|
||
func (c *MessageContext) Abort() {
|
||
c.abortIndex = c.index
|
||
}
|
||
|
||
// AbortHandler 获取当前中断的消息处理函数
|
||
func (c *MessageContext) AbortHandler() MessageContextHandler {
|
||
if c.abortIndex > 0 {
|
||
return c.messageHandlers[c.abortIndex-1]
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// MatchFunc 消息匹配函数,返回为true则表示匹配
|
||
type MatchFunc func(*Message) bool
|
||
|
||
// MatchFuncList 将多个MatchFunc封装成一个MatchFunc
|
||
func MatchFuncList(matchFuncs ...MatchFunc) MatchFunc {
|
||
return func(message *Message) bool {
|
||
for _, matchFunc := range matchFuncs {
|
||
if !matchFunc(message) {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
}
|
||
|
||
type matchNode struct {
|
||
matchFunc MatchFunc
|
||
group MessageContextHandlerGroup
|
||
}
|
||
|
||
type matchNodes []*matchNode
|
||
|
||
// MessageMatchDispatcher impl MessageDispatcher interface
|
||
//
|
||
// dispatcher := NewMessageMatchDispatcher()
|
||
// dispatcher.OnText(func(msg *Message){
|
||
// msg.ReplyText("hello")
|
||
// })
|
||
// bot := DefaultBot()
|
||
// bot.MessageHandler = DispatchMessage(dispatcher)
|
||
type MessageMatchDispatcher struct {
|
||
async bool
|
||
matchNodes matchNodes
|
||
}
|
||
|
||
// NewMessageMatchDispatcher Constructor
|
||
func NewMessageMatchDispatcher() *MessageMatchDispatcher {
|
||
return &MessageMatchDispatcher{}
|
||
}
|
||
|
||
// SetAsync 设置是否异步处理
|
||
func (m *MessageMatchDispatcher) SetAsync(async bool) {
|
||
m.async = async
|
||
}
|
||
|
||
// Dispatch impl MessageDispatcher
|
||
// 遍历 MessageMatchDispatcher 所有的消息处理函数
|
||
// 获取所有匹配上的函数
|
||
// 执行处理的消息处理方法
|
||
func (m *MessageMatchDispatcher) Dispatch(msg *Message) {
|
||
var group MessageContextHandlerGroup
|
||
for _, node := range m.matchNodes {
|
||
if node.matchFunc(msg) {
|
||
group = append(group, node.group...)
|
||
}
|
||
}
|
||
ctx := &MessageContext{Message: msg, messageHandlers: group}
|
||
if m.async {
|
||
go m.do(ctx)
|
||
} else {
|
||
m.do(ctx)
|
||
}
|
||
}
|
||
|
||
func (m *MessageMatchDispatcher) do(ctx *MessageContext) {
|
||
ctx.Next()
|
||
}
|
||
|
||
// RegisterHandler 注册消息处理函数, 根据自己的需求自定义
|
||
// matchFunc返回true则表示处理对应的handlers
|
||
func (m *MessageMatchDispatcher) RegisterHandler(matchFunc MatchFunc, handlers ...MessageContextHandler) {
|
||
if matchFunc == nil {
|
||
panic("MatchFunc can not be nil")
|
||
}
|
||
node := &matchNode{matchFunc: matchFunc, group: handlers}
|
||
m.matchNodes = append(m.matchNodes, node)
|
||
}
|
||
|
||
// OnText 注册处理消息类型为Text的处理函数
|
||
func (m *MessageMatchDispatcher) OnText(handlers ...MessageContextHandler) {
|
||
m.RegisterHandler(func(message *Message) bool { return message.IsText() }, handlers...)
|
||
}
|
||
|
||
// OnImage 注册处理消息类型为Image的处理函数
|
||
func (m *MessageMatchDispatcher) OnImage(handlers ...MessageContextHandler) {
|
||
m.RegisterHandler(func(message *Message) bool { return message.IsPicture() }, handlers...)
|
||
}
|
||
|
||
// OnEmoticon 注册处理消息类型为Emoticon的处理函数(表情包)
|
||
func (m *MessageMatchDispatcher) OnEmoticon(handlers ...MessageContextHandler) {
|
||
m.RegisterHandler(func(message *Message) bool { return message.IsEmoticon() }, handlers...)
|
||
}
|
||
|
||
// OnVoice 注册处理消息类型为Voice的处理函数
|
||
func (m *MessageMatchDispatcher) OnVoice(handlers ...MessageContextHandler) {
|
||
m.RegisterHandler(func(message *Message) bool { return message.IsVoice() }, handlers...)
|
||
}
|
||
|
||
// OnFriendAdd 注册处理消息类型为FriendAdd的处理函数
|
||
func (m *MessageMatchDispatcher) OnFriendAdd(handlers ...MessageContextHandler) {
|
||
m.RegisterHandler(func(message *Message) bool { return message.IsFriendAdd() }, handlers...)
|
||
}
|
||
|
||
// OnCard 注册处理消息类型为Card的处理函数
|
||
func (m *MessageMatchDispatcher) OnCard(handlers ...MessageContextHandler) {
|
||
m.RegisterHandler(func(message *Message) bool { return message.IsCard() }, handlers...)
|
||
}
|
||
|
||
// OnMedia 注册处理消息类型为Media(多媒体消息,包括但不限于APP分享、文件分享)的处理函数
|
||
func (m *MessageMatchDispatcher) OnMedia(handlers ...MessageContextHandler) {
|
||
m.RegisterHandler(func(message *Message) bool { return message.IsMedia() }, handlers...)
|
||
}
|
||
|
||
// OnFriendByNickName 注册根据好友昵称是否匹配的消息处理函数
|
||
func (m *MessageMatchDispatcher) OnFriendByNickName(nickName string, handlers ...MessageContextHandler) {
|
||
matchFunc := func(message *Message) bool {
|
||
if message.IsSendByFriend() {
|
||
sender, err := message.Sender()
|
||
return err == nil && sender.NickName == nickName
|
||
}
|
||
return false
|
||
}
|
||
m.RegisterHandler(matchFunc, handlers...)
|
||
}
|
||
|
||
// OnFriend 注册发送者为好友的处理函数
|
||
func (m *MessageMatchDispatcher) OnFriend(handlers ...MessageContextHandler) {
|
||
m.RegisterHandler(func(message *Message) bool { return message.IsSendByFriend() }, handlers...)
|
||
}
|
||
|
||
// OnGroup 注册发送者为群组的处理函数
|
||
func (m *MessageMatchDispatcher) OnGroup(handlers ...MessageContextHandler) {
|
||
m.RegisterHandler(func(message *Message) bool { return message.IsSendByGroup() }, handlers...)
|
||
}
|
||
|
||
// OnUser 注册根据消息发送者的行为是否匹配的消息处理函数
|
||
func (m *MessageMatchDispatcher) OnUser(f func(user *User) bool, handlers ...MessageContextHandler) {
|
||
mf := func(message *Message) bool {
|
||
sender, err := message.Sender()
|
||
if err != nil {
|
||
return false
|
||
}
|
||
return f(sender)
|
||
}
|
||
m.RegisterHandler(mf, handlers...)
|
||
}
|
||
|
||
// OnFriendByRemarkName 注册根据好友备注是否匹配的消息处理函数
|
||
func (m *MessageMatchDispatcher) OnFriendByRemarkName(remarkName string, handlers ...MessageContextHandler) {
|
||
f := func(user *User) bool {
|
||
return user.IsFriend() && user.RemarkName == remarkName
|
||
}
|
||
m.OnUser(f, handlers...)
|
||
}
|
||
|
||
// OnGroupByGroupName 注册根据群名是否匹配的消息处理函数
|
||
func (m *MessageMatchDispatcher) OnGroupByGroupName(groupName string, handlers ...MessageContextHandler) {
|
||
f := func(user *User) bool {
|
||
return user.IsGroup() && user.NickName == groupName
|
||
}
|
||
m.OnUser(f, handlers...)
|
||
}
|
||
|
||
// AsMessageHandler 将MessageMatchDispatcher转换为MessageHandler
|
||
func (m *MessageMatchDispatcher) AsMessageHandler() MessageHandler {
|
||
return func(msg *Message) {
|
||
m.Dispatch(msg)
|
||
}
|
||
}
|
||
|
||
type MessageSenderMatchFunc func(user *User) bool
|
||
|
||
// SenderMatchFunc 抽象的匹配发送者特征的处理函数
|
||
//
|
||
// dispatcher := NewMessageMatchDispatcher()
|
||
// matchFuncList := MatchFuncList(SenderFriendRequired(), SenderNickNameContainsMatchFunc("多吃点苹果"))
|
||
// dispatcher.RegisterHandler(matchFuncList, func(ctx *MessageContext) {
|
||
// do your own business
|
||
// })
|
||
func SenderMatchFunc(matchFuncs ...MessageSenderMatchFunc) MatchFunc {
|
||
return func(message *Message) bool {
|
||
sender, err := message.Sender()
|
||
if err != nil {
|
||
return false
|
||
}
|
||
for _, matchFunc := range matchFuncs {
|
||
if !matchFunc(sender) {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
}
|
||
|
||
// SenderFriendRequired 只匹配好友
|
||
func SenderFriendRequired() MatchFunc {
|
||
return SenderMatchFunc(func(user *User) bool { return user.IsFriend() })
|
||
}
|
||
|
||
// SenderGroupRequired 只匹配群组
|
||
func SenderGroupRequired() MatchFunc {
|
||
return SenderMatchFunc(func(user *User) bool { return user.IsGroup() })
|
||
}
|
||
|
||
// SenderMpRequired 只匹配公众号
|
||
func SenderMpRequired() MatchFunc {
|
||
return SenderMatchFunc(func(user *User) bool { return user.IsMP() })
|
||
}
|
||
|
||
// SenderNickNameEqualMatchFunc 根据用户昵称是否等于指定字符串的匹配函数
|
||
func SenderNickNameEqualMatchFunc(nickname string) MatchFunc {
|
||
return SenderMatchFunc(func(user *User) bool { return user.NickName == nickname })
|
||
}
|
||
|
||
// SenderRemarkNameEqualMatchFunc 根据用户备注是否等于指定字符串的匹配函数
|
||
func SenderRemarkNameEqualMatchFunc(remarkName string) MatchFunc {
|
||
return SenderMatchFunc(func(user *User) bool { return user.RemarkName == remarkName })
|
||
}
|
||
|
||
// SenderNickNameContainsMatchFunc 根据用户昵称是否包含指定字符串的匹配函数
|
||
func SenderNickNameContainsMatchFunc(nickname string) MatchFunc {
|
||
return SenderMatchFunc(func(user *User) bool { return strings.Contains(user.NickName, nickname) })
|
||
}
|
||
|
||
// SenderRemakeNameContainsFunc 根据用户备注名是否包含指定字符串的匹配函数
|
||
func SenderRemakeNameContainsFunc(remakeName string) MatchFunc {
|
||
return SenderMatchFunc(func(user *User) bool { return strings.Contains(user.RemarkName, remakeName) })
|
||
}
|