213 lines
6.1 KiB
Go
213 lines
6.1 KiB
Go
package cmd
|
||
|
||
import (
|
||
"fmt"
|
||
"regexp"
|
||
"strconv"
|
||
"strings"
|
||
|
||
zero "github.com/wdvxdr1123/ZeroBot"
|
||
"github.com/wdvxdr1123/ZeroBot/message"
|
||
)
|
||
|
||
const (
|
||
robotNotifyModeNormal = "普通"
|
||
robotNotifyModeAtAll = "艾特全体"
|
||
robotNotifyModeEssence = "群精华"
|
||
)
|
||
|
||
var qqCodePattern = regexp.MustCompile(`qq=(\d+)`)
|
||
|
||
func init() {
|
||
zero.OnCommand("群通知", zero.SuperUserPermission).Handle(handleRobotGroupNotify)
|
||
zero.OnCommand("通知群列表", zero.SuperUserPermission).Handle(handleRobotNotifyGroupList)
|
||
zero.OnCommand("全群拉黑", zero.SuperUserPermission).Handle(handleRobotBlacklistAdd)
|
||
zero.OnCommand("全群解黑", zero.SuperUserPermission).Handle(handleRobotBlacklistRemove)
|
||
zero.OnCommand("黑名单列表", zero.SuperUserPermission).Handle(handleRobotBlacklistList)
|
||
|
||
zero.OnRequest().Handle(handleRobotBlacklistRequest)
|
||
zero.OnNotice().Handle(handleRobotBlacklistNotice)
|
||
}
|
||
|
||
func handleRobotGroupNotify(ctx *zero.Ctx) {
|
||
cfg := loadRobotGroupConfig()
|
||
if len(cfg.NotifyGroupIDs) == 0 {
|
||
ctx.Send("未配置通知群,请先编辑 public/config/robot_groups.json 的 notify_group_ids")
|
||
return
|
||
}
|
||
|
||
mode, content := parseNotifyModeAndContent(ctx.Event.Message.String())
|
||
if content == "" {
|
||
ctx.Send("用法:/群通知 [普通|艾特全体|群精华] 内容")
|
||
return
|
||
}
|
||
|
||
success := make([]string, 0, len(cfg.NotifyGroupIDs))
|
||
for _, groupID := range cfg.NotifyGroupIDs {
|
||
switch mode {
|
||
case robotNotifyModeAtAll:
|
||
ctx.SendGroupMessage(groupID, message.Message{message.AtAll(), message.Text("\n", content)})
|
||
case robotNotifyModeEssence:
|
||
msgID := ctx.SendGroupMessage(groupID, message.Text("【群通知】\n", content))
|
||
if msgID != 0 {
|
||
ctx.SetGroupEssenceMessage(msgID)
|
||
}
|
||
default:
|
||
ctx.SendGroupMessage(groupID, message.Text("【群通知】\n", content))
|
||
}
|
||
success = append(success, strconv.FormatInt(groupID, 10))
|
||
}
|
||
|
||
ctx.Send(fmt.Sprintf("已按[%s]发送群通知,共 %d 个群:%s", mode, len(success), strings.Join(success, ", ")))
|
||
}
|
||
|
||
func handleRobotNotifyGroupList(ctx *zero.Ctx) {
|
||
cfg := loadRobotGroupConfig()
|
||
ctx.Send(formatRobotGroups("通知群", cfg.NotifyGroupIDs) + "\n支持模式:普通、艾特全体、群精华")
|
||
}
|
||
|
||
func handleRobotBlacklistAdd(ctx *zero.Ctx) {
|
||
cfg := loadRobotGroupConfig()
|
||
if len(cfg.ManageGroupIDs) == 0 {
|
||
ctx.Send("未配置管理群,请先编辑 public/config/robot_groups.json 的 manage_group_ids")
|
||
return
|
||
}
|
||
|
||
userID := extractCommandUserID(ctx.Event.Message.String(), "全群拉黑")
|
||
if userID == 0 {
|
||
ctx.Send("用法:/全群拉黑 @某人 或 /全群拉黑 QQ号")
|
||
return
|
||
}
|
||
if userID == ctx.Event.SelfID {
|
||
ctx.Send("不能把机器人自己加入黑名单")
|
||
return
|
||
}
|
||
|
||
if err := addRobotBlacklistUser(userID); err != nil {
|
||
ctx.Send("写入黑名单失败:" + err.Error())
|
||
return
|
||
}
|
||
|
||
for _, groupID := range cfg.ManageGroupIDs {
|
||
ctx.SetGroupKick(groupID, userID, true)
|
||
}
|
||
|
||
ctx.Send(fmt.Sprintf("已将 %d 加入全群黑名单,并在 %d 个管理群执行踢出/拒绝重加", userID, len(cfg.ManageGroupIDs)))
|
||
}
|
||
|
||
func handleRobotBlacklistRemove(ctx *zero.Ctx) {
|
||
userID := extractCommandUserID(ctx.Event.Message.String(), "全群解黑")
|
||
if userID == 0 {
|
||
ctx.Send("用法:/全群解黑 @某人 或 /全群解黑 QQ号")
|
||
return
|
||
}
|
||
|
||
if err := removeRobotBlacklistUser(userID); err != nil {
|
||
ctx.Send("移出黑名单失败:" + err.Error())
|
||
return
|
||
}
|
||
|
||
ctx.Send(fmt.Sprintf("已将 %d 从全群黑名单移除", userID))
|
||
}
|
||
|
||
func handleRobotBlacklistList(ctx *zero.Ctx) {
|
||
cfg := loadRobotBlacklist()
|
||
if len(cfg.UserIDs) == 0 {
|
||
ctx.Send("当前黑名单为空")
|
||
return
|
||
}
|
||
|
||
lines := make([]string, 0, len(cfg.UserIDs))
|
||
for _, userID := range cfg.UserIDs {
|
||
lines = append(lines, strconv.FormatInt(userID, 10))
|
||
}
|
||
ctx.Send("当前全群黑名单:\n" + strings.Join(lines, "\n"))
|
||
}
|
||
|
||
func handleRobotBlacklistRequest(ctx *zero.Ctx) {
|
||
cfg := loadRobotGroupConfig()
|
||
if ctx.Event.RequestType != "group" {
|
||
return
|
||
}
|
||
if !isConfiguredGroup(ctx.Event.GroupID, cfg.ManageGroupIDs) {
|
||
return
|
||
}
|
||
if !isRobotBlacklisted(ctx.Event.UserID) {
|
||
return
|
||
}
|
||
|
||
ctx.SetGroupAddRequest(ctx.Event.Flag, ctx.Event.SubType, false, "该账号已被机器人拉黑")
|
||
}
|
||
|
||
func handleRobotBlacklistNotice(ctx *zero.Ctx) {
|
||
cfg := loadRobotGroupConfig()
|
||
if ctx.Event.NoticeType != "group_increase" {
|
||
return
|
||
}
|
||
if !isConfiguredGroup(ctx.Event.GroupID, cfg.ManageGroupIDs) {
|
||
return
|
||
}
|
||
if !isRobotBlacklisted(ctx.Event.UserID) || ctx.Event.UserID == ctx.Event.SelfID {
|
||
return
|
||
}
|
||
|
||
ctx.SetGroupKick(ctx.Event.GroupID, ctx.Event.UserID, true)
|
||
ctx.SendGroupMessage(ctx.Event.GroupID, message.Text("已自动移除黑名单成员:", strconv.FormatInt(ctx.Event.UserID, 10)))
|
||
}
|
||
|
||
func extractCommandBody(raw, command string) string {
|
||
text := strings.TrimSpace(raw)
|
||
text = strings.TrimPrefix(text, "/")
|
||
text = strings.TrimSpace(text)
|
||
text = strings.TrimPrefix(text, command)
|
||
return strings.TrimSpace(text)
|
||
}
|
||
|
||
func extractCommandUserID(raw, command string) int64 {
|
||
if matches := qqCodePattern.FindStringSubmatch(raw); len(matches) == 2 {
|
||
if userID, err := strconv.ParseInt(matches[1], 10, 64); err == nil && userID > 0 {
|
||
return userID
|
||
}
|
||
}
|
||
|
||
text := extractCommandBody(raw, command)
|
||
for _, field := range strings.Fields(text) {
|
||
if userID, err := strconv.ParseInt(field, 10, 64); err == nil && userID > 0 {
|
||
return userID
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
|
||
func parseNotifyModeAndContent(raw string) (string, string) {
|
||
body := extractCommandBody(raw, "群通知")
|
||
if body == "" {
|
||
return robotNotifyModeNormal, ""
|
||
}
|
||
|
||
parts := strings.Fields(body)
|
||
if len(parts) == 0 {
|
||
return robotNotifyModeNormal, ""
|
||
}
|
||
|
||
switch parts[0] {
|
||
case robotNotifyModeNormal, robotNotifyModeAtAll, robotNotifyModeEssence:
|
||
return parts[0], strings.TrimSpace(strings.Join(parts[1:], " "))
|
||
default:
|
||
return robotNotifyModeNormal, body
|
||
}
|
||
}
|
||
|
||
func formatRobotGroups(title string, groups []int64) string {
|
||
if len(groups) == 0 {
|
||
return title + ":未配置"
|
||
}
|
||
|
||
lines := make([]string, 0, len(groups)+1)
|
||
lines = append(lines, title+":")
|
||
for _, groupID := range groups {
|
||
lines = append(lines, strconv.FormatInt(groupID, 10))
|
||
}
|
||
return strings.Join(lines, "\n")
|
||
}
|