完成@消息和私聊消息筛选

This commit is contained in:
hxuanyu 2025-08-12 16:59:34 +08:00
parent 8e98c68f3f
commit 0d04b8288d
3 changed files with 101 additions and 18 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
__pycache__/main.cpython-313.pyc __pycache__/main.cpython-313.pyc
ref/

14
_conf_schema.json Normal file
View File

@ -0,0 +1,14 @@
{
"group_whitelist": {
"description": "允许中转的群聊ID白名单仅处理这些群的消息",
"type": "list",
"hint": "填写需要允许中转的群号,多个群号用英文逗号分隔",
"default": []
},
"private_blacklist": {
"description": "不允许中转的私聊账号黑名单(这些账号的私聊消息将被忽略)",
"type": "list",
"hint": "填写需要屏蔽的用户ID多个ID用英文逗号分隔",
"default": []
}
}

104
main.py
View File

@ -1,24 +1,92 @@
from astrbot.api.event import filter, AstrMessageEvent, MessageEventResult from astrbot.api.event import AstrMessageEvent
from astrbot.api.event.filter import event_message_type, EventMessageType
from astrbot.api.star import Context, Star, register from astrbot.api.star import Context, Star, register
from astrbot.api import logger from astrbot.api import logger
import astrbot.api.message_components as Comp
@register("helloworld", "YourName", "一个简单的 Hello World 插件", "1.0.0")
class MyPlugin(Star): def _check_at_bot(message_obj) -> bool:
def __init__(self, context: Context): """
检测群聊消息是否@了当前机器人
依据: plugin.md AstrBotMessage 及消息链定义:
- message_obj.message BaseMessageComponent 列表
- At(qq=...) @ 消息段message_obj.self_id 为机器人的标识 ID
当消息链中存在 At 且其 qq 等于 self_id 判定为@了机器人
忽略 AtAll(@全体)
"""
try:
self_id = str(getattr(message_obj, "self_id", "")) or ""
segments = getattr(message_obj, "message", []) or []
except Exception:
return False
if not self_id or not isinstance(segments, list):
return False
for seg in segments:
# 适配对象消息段
try:
if isinstance(seg, Comp.At):
# 排除 @all
if isinstance(seg, Comp.AtAll):
continue
if str(seg.qq) == self_id:
return True
except Exception:
pass
# 适配字典形式的消息段(稳健性处理)
try:
if isinstance(seg, dict):
seg_type = str(seg.get("type", "")).lower()
data = seg.get("data", {}) or {}
if seg_type == "at":
qq = str(data.get("qq", ""))
if qq and qq.lower() != "all" and qq == self_id:
return True
except Exception:
pass
return False
@register("relay", "YourName", "消息中转插件", "1.0.0")
class RelayPlugin(Star):
def __init__(self, context: Context, config=None):
super().__init__(context) super().__init__(context)
self.config = config or {}
# 读取群聊白名单和私聊黑名单,全部转为字符串集合,避免类型不一致
self.group_whitelist = set(str(x) for x in self.config.get("group_whitelist", []))
self.private_blacklist = set(str(x) for x in self.config.get("private_blacklist", []))
logger.info(f"[RelayPlugin] 群聊白名单: {self.group_whitelist}")
logger.info(f"[RelayPlugin] 私聊黑名单: {self.private_blacklist}")
async def initialize(self): @event_message_type(EventMessageType.GROUP_MESSAGE)
"""可选择实现异步的插件初始化方法,当实例化该插件类之后会自动调用该方法。""" async def on_group_message(self, event: AstrMessageEvent):
# 注册指令的装饰器。指令名为 helloworld。注册成功后发送 `/helloworld` 就会触发这个指令,并回复 `你好, {user_name}!` group_id = str(event.message_obj.group_id)
@filter.command("helloworld") at_bot = _check_at_bot(event.message_obj)
async def helloworld(self, event: AstrMessageEvent):
"""这是一个 hello world 指令""" # 这是 handler 的描述,将会被解析方便用户了解插件内容。建议填写。 if group_id not in self.group_whitelist:
user_name = event.get_sender_name() logger.info(f"[RelayPlugin] 群聊 {group_id} 不在白名单,忽略消息")
message_str = event.message_str # 用户发的纯文本消息字符串 return
message_chain = event.get_messages() # 用户所发的消息的消息链 # from astrbot.api.message_components import * if not at_bot:
logger.info(message_chain) logger.info(f"[RelayPlugin] 群聊 {group_id} 消息未@机器人,忽略消息")
yield event.plain_result(f"Hello, {user_name}, 你发了 {message_str}!") # 发送一条纯文本消息 return
logger.info(f"[RelayPlugin] 群聊 {group_id} 消息链: {event.message_obj.message}")
# TODO: 处理函数留空
async def terminate(self): @event_message_type(EventMessageType.PRIVATE_MESSAGE)
"""可选择实现异步的插件销毁方法,当插件被卸载/停用时会调用。""" async def on_private_message(self, event: AstrMessageEvent):
sender = event.message_obj.sender
if hasattr(sender, 'id'):
sender_id = str(sender.id)
else:
sender_id = str(sender)
if sender_id in set(str(x) for x in self.private_blacklist):
logger.info(f"[RelayPlugin] 私聊 {sender_id} 在黑名单,忽略消息")
return
logger.info(f"[RelayPlugin] 私聊 {sender_id} 消息链: {event.message_obj.message}")
# TODO: 处理函数留空