Files
abot/group_auto/group_member_change.py
2025-03-05 09:01:08 +08:00

117 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import redis
import xml.etree.ElementTree as ET
from wcferry import Wcf
class GroupMemberChange:
def __init__(self, wcf: Wcf, redis_pool: redis.ConnectionPool):
self.wcf = wcf # 假设 wcf 对象在此类中初始化
self.redis_pool = redis_pool
# 初始化本地缓存字典,使用 group_id 作为键
self.local_membercounts = {}
self.local_members = {}
def _get_redis_connection(self):
"""从连接池获取 Redis 连接"""
return redis.Redis(connection_pool=self.redis_pool)
def get_current_members(self, group_id):
""" 获取当前群成员信息 """
print(f"Fetching current members for group_id: {group_id}")
members = self.wcf.get_chatroom_members(group_id) # 假设返回的数据格式是 {wxid1: 昵称1, wxid2: 昵称2, ...}
print(f"Current members: {members}")
return members
def get_previous_data_from_redis(self, group_id):
""" 从 Redis 获取上次的数据 """
membercount_key = f"group:group_member_count:{group_id}"
members_key = f"group:group_members:{group_id}"
# 读取 Redis 中的数据
print(f"Fetching previous data from Redis for group_id: {group_id}")
membercount_previous = self._get_redis_connection().get(membercount_key)
members_previous = self._get_redis_connection().hgetall(members_key) # 获取上次的成员信息
print(f"Previous membercount: {membercount_previous}, Previous members: {members_previous}")
return membercount_previous, members_previous
def process_message(self, group_id, xml_data_current):
""" 处理消息并更新 Redis """
root_current = ET.fromstring(xml_data_current)
membercount_current = root_current.find('membercount').text
result = [] # 初始化文案列表
# 检查是否存在本地缓存数据,如果不存在,则从 Redis 获取
if group_id not in self.local_membercounts or group_id not in self.local_members:
print("No local data, fetching from Redis")
membercount_previous, members_previous = self.get_previous_data_from_redis(group_id)
# 如果没有上次的数据,说明是第一次处理,直接存储本次数据
if membercount_previous is None or not members_previous:
print("First time processing, saving current data to Redis")
members_current = self.get_current_members(group_id)
self._get_redis_connection().set(f"group:group_member_count:{group_id}", membercount_current)
self._get_redis_connection().delete(f"group:group_members:{group_id}")
self._get_redis_connection().hset(f"group:group_members:{group_id}",
mapping=members_current) # 存储当前成员信息
# 更新本地缓存
self.local_membercounts[group_id] = membercount_current
self.local_members[group_id] = members_current
result.append("$NO_CHANGE$")
return "\n".join(result)
else:
# 如果 Redis 中有数据,就更新本地缓存
self.local_membercounts[group_id] = membercount_previous
self.local_members[group_id] = members_previous
else:
# 使用本地缓存的数据进行比较
membercount_previous = self.local_membercounts[group_id]
members_previous = self.local_members[group_id]
# 比较 membercount 是否发生变化
if membercount_current != membercount_previous:
print(f"Membercount changed: {membercount_previous} -> {membercount_current}")
members_current = self.get_current_members(group_id)
# TODO 如果用户达到了500人则删除该群自动添加内容
# 比较成员,仅使用 wxid 进行比较
members_current_set = set(members_current.keys())
members_previous_set = set(members_previous.keys())
added_members = members_current_set - members_previous_set
removed_members = members_previous_set - members_current_set
# 添加变化成员的文案
for wxid in added_members:
nickname = members_current[wxid]
result.append(f"检测到\n {nickname}{wxid}\n加入群聊")
for wxid in removed_members:
nickname = members_previous[wxid]
result.append(f"检测到\n {nickname}{wxid}\n退出群聊")
# 更新本地缓存
print(f"Updating local cache with current membercount and members")
self.local_membercounts[group_id] = membercount_current
self.local_members[group_id] = members_current
print(f"Current membercount: {membercount_current}, Current members: {members_current}")
print(
f"Local Current membercount: {self.local_membercounts[group_id]}, Local Current members: {self.local_members[group_id]}")
# 更新 Redis 数据
print(f"Updating Redis with current membercount and members")
self._get_redis_connection.set(f"group:group_member_count:{group_id}", membercount_current)
self._get_redis_connection.delete(f"group:group_members:{group_id}")
# 更新 Redis 中的成员信息,确保在成员变化时也更新
self._get_redis_connection.hset(f"group:group_members:{group_id}", mapping=members_current)
else:
result.append("$NO_CHANGE$")
# 返回拼接后的结果
return "\n".join(result)