Skip to content

Commit

Permalink
feat: 增加ban指令,可在某个群ban掉某个用户使其发命令不响应,可通过引用消息快捷ban掉,具体指令查看文档 https://gi…
Browse files Browse the repository at this point in the history
  • Loading branch information
yqchilde authored Mar 10, 2023
1 parent 7af91f5 commit 6773d86
Show file tree
Hide file tree
Showing 12 changed files with 246 additions and 81 deletions.
9 changes: 6 additions & 3 deletions docs/command.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@
* 该指令用于启用某个插件服务,默认在当前会话聊天室
* `/禁用 [插件服务名(英文那个,发送菜单可以看到)]`
* 该指令用于禁用某个插件服务,默认在当前会话聊天室
* `/启用全部 [插件服务名(英文那个,发送菜单可以看到)]`
* `/启用全部 [插件服务名]`
* 该指令用于启用某个插件服务,对所有聊天室生效
* `/禁用全部 [插件服务名(英文那个,发送菜单可以看到)]`
* `/禁用全部 [插件服务名]`
* 该指令用于禁用某个插件服务,对所有聊天室生效

* `/ban [插件服务名] [用户微信ID]` 或 在群里引用对方消息回复`/ban [插件服务名]`即可快速ban掉
* 该指令用于ban掉某个用户在某个群里发指令响应
* `/unban [插件服务名] [用户微信ID]` 或 在群里引用对方消息回复`/unban [插件服务名]`即可快速unban掉
* 该指令用于unban掉某个用户在某个群里发指令响应
### 插件指令

[参考各插件目录下`README.md`文件](../plugins)
42 changes: 26 additions & 16 deletions engine/control/ban.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package control

import (
"errors"
"fmt"

"github.com/yqchilde/wxbot/engine/pkg/log"
Expand All @@ -9,48 +10,57 @@ import (
var banCache = make(map[string]struct{})

// Ban 禁止某人在某群使用本插件
func (m *Control) Ban(uid, gid string) {
var err error
func (m *Control) Ban(uid, gid string) error {
if gid != "" {
label := fmt.Sprintf("%s_%s_%s", m.Service, uid, gid)
m.Manager.Lock()
err = m.Manager.D.Table(m.Service + "ban").Create(&PluginBanConfig{Label: label, UserID: uid, GroupID: gid}).Error
err := m.Manager.D.Table(m.Service+"ban").Where("label = ?", label).FirstOrCreate(&PluginBanConfig{Label: label, UserID: uid, GroupID: gid}).Error
banCache[label] = struct{}{}
m.Manager.Unlock()
if err == nil {
log.Debugf("[control] plugin %s is banned in group %d for user %d.", m.Service, gid, uid)
return
if err != nil {
log.Errorf("(plugin) %s banned in group %s for user %s, failed: %v", m.Service, gid, uid, err)
return errors.New("ban失败")
}
return nil
}
// 所有群
label := fmt.Sprintf("%s_%s_%s", m.Service, uid, "all")
m.Manager.Lock()
err = m.Manager.D.Table(m.Service + "ban").Create(&PluginBanConfig{Label: label, UserID: uid, GroupID: "all"}).Error
err := m.Manager.D.Table(m.Service+"ban").Where("label = ?", label).Create(&PluginBanConfig{Label: label, UserID: uid, GroupID: "all"}).Error
banCache[label] = struct{}{}
m.Manager.Unlock()
if err == nil {
log.Debugf("[control] plugin %s is banned in all group for user %d.", m.Service, uid)
if err != nil {
log.Errorf("(plugin) %s banned in all group for user %s, failed: %v", m.Service, gid, uid, err)
return errors.New("ban失败")
}
return nil
}

// Permit 允许某人在某群使用本插件
func (m *Control) Permit(uid, gid string) {
// UnBan 允许某人在某群使用本插件
func (m *Control) UnBan(uid, gid string) error {
if gid != "" {
label := fmt.Sprintf("%s_%s_%s", m.Service, uid, gid)
m.Manager.Lock()
m.Manager.D.Table(m.Service+"ban").Where("label = ?", label).Delete(&PluginBanConfig{})
err := m.Manager.D.Table(m.Service+"ban").Where("label = ?", label).Delete(&PluginBanConfig{}).Error
delete(banCache, label)
m.Manager.Unlock()
log.Debugf("[control] plugin %s is permitted in group %d for user %d.", m.Service, gid, uid)
return
if err != nil {
log.Errorf("(plugin) %s unbanned in group %s for user %s, failed: %v", m.Service, gid, uid, err)
return errors.New("unban失败")
}
return nil
}
// 所有群
label := fmt.Sprintf("%s_%s_%s", m.Service, uid, "all")
m.Manager.Lock()
m.Manager.D.Table(m.Service+"ban").Where("label = ?", label).Delete(&PluginBanConfig{})
err := m.Manager.D.Table(m.Service+"ban").Where("label = ?", label).Delete(&PluginBanConfig{}).Error
delete(banCache, label)
m.Manager.Unlock()
log.Debugf("[control] plugin %s is permitted in all group for user %d.", m.Service, uid)
if err != nil {
log.Errorf("(plugin) %s unbanned in all group for user %s, failed: %v", m.Service, gid, uid, err)
return errors.New("unban失败")
}
return nil
}

// IsBannedIn 某人是否在某群被ban
Expand Down
36 changes: 36 additions & 0 deletions engine/control/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package control

import (
"fmt"
"strings"
"sync"

"github.com/yqchilde/wxbot/engine/pkg/log"
Expand Down Expand Up @@ -167,5 +168,40 @@ func init() {
ctx.ReplyText("关闭全局模式成功")
}
})

// 在某个群ban、unban某个用户
robot.OnCommandGroup([]string{"ban", "unban"}, robot.UserOrGroupAdmin).SetBlock(true).FirstPriority().Handle(func(ctx *robot.Ctx) {
args := strings.Split(ctx.State["args"].(string), " ")
if len(args) == 0 {
return
}

serv, wxId, grp := args[0], "", ctx.Event.FromUniqueID
if ctx.IsReference() {
wxId = ctx.Event.ReferenceMessage.ChatUser
} else {
wxId = args[1]
}

service, ok := managers.Lookup(serv)
if !ok {
ctx.ReplyTextAndAt("没有找到对应插件服务")
return
}
switch ctx.State["command"].(string) {
case "ban":
if err := service.Ban(wxId, grp); err != nil {
ctx.ReplyText(err.Error())
return
}
ctx.ReplyText("ban成功")
case "unban":
if err := service.UnBan(wxId, grp); err != nil {
ctx.ReplyText(err.Error())
return
}
ctx.ReplyText("unban成功")
}
})
})
}
2 changes: 1 addition & 1 deletion engine/robot/callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (ctx *Ctx) IsRecalled() bool {

// IsReference 判断消息类型是否是消息引用
func (ctx *Ctx) IsReference() bool {
return ctx.Event.Message != nil && ctx.Event.Message.Type == MsgTypeReference
return ctx.Event.Message != nil && ctx.Event.ReferenceMessage != nil
}

// IsAt 判断是否被@了,仅在群聊中有效,私聊也算被@了
Expand Down
35 changes: 17 additions & 18 deletions engine/robot/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ type Event struct {
FromGroupName string // 消息来源群名称
RawMessage string // 原始消息
Message *Message // 消息内容
SubscriptionMessage *Message // 订阅号消息
FriendVerify *FriendVerify // 好友验证消息
Transfer *Transfer // 转账消息
Withdraw *Withdraw // 撤回消息
GroupMemberIncrease *GroupMemberIncrease // 群成员增加消息
GroupMemberDecrease *GroupMemberDecrease // 群成员减少消息
MPMessage *Message // 订阅公众号消息
FriendVerifyMessage *FriendVerifyMessage // 好友验证消息
TransferMessage *TransferMessage // 转账消息
WithdrawMessage *WithdrawMessage // 撤回消息
ReferenceMessage *ReferenceMessage // 引用消息
}

// Message 记录消息的具体内容
Expand All @@ -28,8 +27,8 @@ type Message struct {
Content string // 消息内容
}

// FriendVerify 记录好友验证消息的具体内容
type FriendVerify struct {
// FriendVerifyMessage 记录好友验证消息的具体内容
type FriendVerifyMessage struct {
WxId string // 发送者微信id
Nick string // 发送者昵称
V1 string // 验证V1
Expand All @@ -41,8 +40,8 @@ type FriendVerify struct {
Scene string // 验证场景
}

// Transfer 记录转账消息的具体内容
type Transfer struct {
// TransferMessage 记录转账消息的具体内容
type TransferMessage struct {
FromWxId string // 发送者微信ID
MsgSource int64 // 消息来源 1:收到转账 2:对方接收转账 3:发出转账 4:自己接收转账 5:对方退还 6:自己退还
TransferType int64 // 转账类型 1:即时到账 2:延时到账
Expand All @@ -52,19 +51,19 @@ type Transfer struct {
TransferTime string // 转账时间,10位时间戳
}

// Withdraw 记录撤回消息的具体内容
type Withdraw struct {
// WithdrawMessage 记录撤回消息的具体内容
type WithdrawMessage struct {
FromType int64 // 消息来源 1:私聊 2:群聊
FromGroup string // 消息来源群ID
FromWxId string // 消息来源微信ID
MsgSource int64 // 消息来源 1:别人撤回 2:自己使用手机撤回 3:自己使用电脑撤回
Msg string // 消息内容
}

// GroupMemberIncrease 记录群成员增加消息的具体内容
type GroupMemberIncrease struct {
}

// GroupMemberDecrease 记录群成员减少消息的具体内容
type GroupMemberDecrease struct {
// ReferenceMessage 记录引用消息的具体内容
type ReferenceMessage struct {
FromUser string // 消息来源群ID
ChatUser string // 消息来源微信ID
DisplayName string // 消息来源微信昵称
Content string // 消息内容
}
24 changes: 14 additions & 10 deletions engine/robot/robot.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,9 @@ loop:
func preProcessMessageEvent(ctx *Ctx, e *Event) {
switch e.Type {
case EventPrivateChat:
if ctx.IsText() {
if ctx.IsReference() {
log.Println(fmt.Sprintf("[回调]收到私聊(%s[%s])引用消息 ==> %v", e.FromName, e.FromWxId, "引用: "+e.ReferenceMessage.Content+" 回复: "+e.Message.Content))
} else if ctx.IsText() {
log.Println(fmt.Sprintf("[回调]收到私聊(%s[%s])文本消息 ==> %v", e.FromName, e.FromWxId, e.Message.Content))
} else if ctx.IsImage() {
log.Println(fmt.Sprintf("[回调]收到私聊(%s[%s]图片消息 ==> %v", e.FromName, e.FromWxId, e.Message.Content))
Expand All @@ -252,7 +254,9 @@ func preProcessMessageEvent(ctx *Ctx, e *Event) {
log.Println(fmt.Sprintf("[回调]收到私聊(%s[%s])未整理消息 ==> %v", e.FromName, e.FromWxId, e.Message.Content))
}
case EventGroupChat:
if ctx.IsText() {
if ctx.IsReference() {
log.Println(fmt.Sprintf("[回调]收到群聊(%s[%s])>用户(%s[%s])引用消息 ==> %v", e.FromGroupName, e.FromGroup, e.FromName, e.FromWxId, "引用: "+e.ReferenceMessage.Content+" 回复: "+e.Message.Content))
} else if ctx.IsText() {
log.Println(fmt.Sprintf("[回调]收到群聊(%s[%s])>用户(%s[%s])文本消息 ==> %v", e.FromGroupName, e.FromGroup, e.FromName, e.FromWxId, e.Message.Content))
} else if ctx.IsImage() {
log.Println(fmt.Sprintf("[回调]收到群聊(%s[%s])>用户(%s[%s])图片消息 ==> %v", e.FromGroupName, e.FromGroup, e.FromName, e.FromWxId, e.Message.Content))
Expand All @@ -276,18 +280,18 @@ func preProcessMessageEvent(ctx *Ctx, e *Event) {
case EventSelfMessage:
log.Println(fmt.Sprintf("[回调]收到自己发送的消息 ==> %v", e.Message.Content))
case EventFriendVerify:
log.Println(fmt.Sprintf("[回调]收到好友验证消息, wxId:%s, nick:%s, content:%s", e.FriendVerify.WxId, e.FriendVerify.Nick, e.FriendVerify.Content))
log.Println(fmt.Sprintf("[回调]收到好友验证消息, wxId:%s, nick:%s, content:%s", e.FriendVerifyMessage.WxId, e.FriendVerifyMessage.Nick, e.FriendVerifyMessage.Content))
case EventTransfer:
if len(e.Transfer.Memo) > 0 {
log.Println(fmt.Sprintf("[回调]收到转账消息, wxId:%s, money:%s, memo:%s", e.Transfer.FromWxId, e.Transfer.Money, e.Transfer.Memo))
if len(e.TransferMessage.Memo) > 0 {
log.Println(fmt.Sprintf("[回调]收到转账消息, wxId:%s, money:%s, memo:%s", e.TransferMessage.FromWxId, e.TransferMessage.Money, e.TransferMessage.Memo))
} else {
log.Println(fmt.Sprintf("[回调]收到转账消息, wxId:%s, money:%s", e.Transfer.FromWxId, e.Transfer.Money))
log.Println(fmt.Sprintf("[回调]收到转账消息, wxId:%s, money:%s", e.TransferMessage.FromWxId, e.TransferMessage.Money))
}
case EventMessageWithdraw:
if e.Withdraw.FromType == 1 {
log.Println(fmt.Sprintf("[回调]收到撤回私聊(%s)消息", e.Withdraw.FromWxId))
} else if e.Withdraw.FromType == 2 {
log.Println(fmt.Sprintf("[回调]收到撤回群聊(%s[%s])消息", e.Withdraw.FromGroup, e.Withdraw.FromWxId))
if e.WithdrawMessage.FromType == 1 {
log.Println(fmt.Sprintf("[回调]收到撤回私聊(%s)消息", e.WithdrawMessage.FromWxId))
} else if e.WithdrawMessage.FromType == 2 {
log.Println(fmt.Sprintf("[回调]收到撤回群聊(%s[%s])消息", e.WithdrawMessage.FromGroup, e.WithdrawMessage.FromWxId))
}
case EventSystem:
log.Println(fmt.Sprintf("[回调]收到系统消息 ==> %s", e.Message.Content))
Expand Down
2 changes: 1 addition & 1 deletion examples/friendAddReq/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func init() {
engine.OnMessage().SetBlock(false).Handle(func(ctx *robot.Ctx) {
// 监听加好友事件
if ctx.IsEventFriendVerify() {
f := ctx.Event.FriendVerify
f := ctx.Event.FriendVerifyMessage
// 判断一下好友验证消息是否为"wxbot"
if strings.ToLower(f.Content) != "wxbot" {
return
Expand Down
Loading

0 comments on commit 6773d86

Please sign in to comment.