refactor: tighten group member change filtering

This commit is contained in:
liuwei
2026-04-13 13:04:58 +08:00
parent f7da70e920
commit 2a79c5cb3e

View File

@@ -18,6 +18,13 @@ class GroupMemberChangePlugin(MessagePluginInterface):
# 功能权限常量
FEATURE_KEY = "GROUP_MEMBER_CHANGE"
FEATURE_DESCRIPTION = "👥 群成员变更监控 [自动监控群成员变动并发送通知]"
SUPPORTED_TEMPLATE_TEXTS = {
'"$names$"加入了群聊',
'"$username$"邀请"$names$"加入了群聊',
'你邀请"$names$"加入了群聊',
'"$adder$"通过扫描"$from$"分享的二维码加入群聊',
'"$adder$"通过"$from$"的邀请二维码加入群聊'
}
@property
def name(self) -> str:
@@ -61,10 +68,35 @@ class GroupMemberChangePlugin(MessagePluginInterface):
def can_process(self, message: Dict[str, Any]) -> bool:
"""检查是否可以处理该消息"""
roomid = str(message.get("roomid", "") or "").strip()
if not roomid or not roomid.endswith("@chatroom"):
return False
gbm: GroupBotManager = message.get("gbm")
if gbm and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
return False
msg_type = message.get("type")
msg_type_value = getattr(msg_type, "value", msg_type)
if str(msg_type_value) not in {"10000", "10002"}:
return False
content = message.get("content")
if hasattr(content, "clean_content"):
content = content.clean_content
content = str(content or "").strip()
if not content or "<sysmsg" not in content:
return False
return True
full_msg = message.get("full_wx_msg")
if full_msg and not full_msg.from_group():
return False
root = self._parse_sysmsg_root(content)
if root is None:
return False
return self._is_supported_join_event(root)
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
"""处理接收到的消息"""
@@ -82,10 +114,8 @@ class GroupMemberChangePlugin(MessagePluginInterface):
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
return False, "没有权限"
xml_content = str(content).strip().replace("\n", "").replace("\t", "")
root = ET.fromstring(xml_content)
if root.tag != "sysmsg":
root = self._parse_sysmsg_root(content)
if root is None:
return False, "非本次需要处理消息"
# 检查是否是进群消息
@@ -146,6 +176,41 @@ class GroupMemberChangePlugin(MessagePluginInterface):
return True, "已发送进群欢迎语"
return False, "无需执行"
def _parse_sysmsg_root(self, content: str) -> Optional[ET.Element]:
xml_content = str(content or "").strip().replace("\n", "").replace("\t", "")
if not xml_content or "<sysmsg" not in xml_content:
return None
try:
root = ET.fromstring(xml_content)
except ET.ParseError:
return None
if root.tag != "sysmsg":
return None
return root
def _is_supported_join_event(self, root: ET.Element) -> bool:
if root.attrib.get("type") != "sysmsgtemplate":
return False
sys_msg_template = root.find("sysmsgtemplate")
if sys_msg_template is None:
return False
template = sys_msg_template.find("content_template")
if template is None:
return False
template_type = template.attrib.get("type")
if template_type not in {"tmpl_type_profile", "tmpl_type_profilewithrevoke"}:
return False
template_node = template.find("template")
template_text = (template_node.text or "").strip() if template_node is not None else ""
if not template_text:
return False
return any(item in template_text for item in self.SUPPORTED_TEMPLATE_TEXTS)
@property
def commands(self) -> List[str]:
"""插件支持的命令列表"""