diff --git a/robot.py b/robot.py index 5482cb9..6d0d5d4 100644 --- a/robot.py +++ b/robot.py @@ -29,6 +29,7 @@ from utils.robot_cmd.robot_command import GroupBotManager, Feature, PermissionSt from utils.sehuatang.shehuatang import pdf_file_path from utils.sehuatang.shehuatang_undetected import pdf_file_path_undetected from utils.wechat.contact_manager import ContactManager +from utils.wechat.member_monitor import ChatroomMemberMonitor from utils.wechat.message_to_db import MessageStorage from wechat_ipad import WechatAPIClient from wechat_ipad.models.appmsg_xml import LINK_XML_NEWS @@ -203,7 +204,7 @@ class Robot: self.contact_manager.set_contacts(self.allContacts, friends, self.head_images, self.all_chatroom_members) self.message_storage = MessageStorage(self.ipad_bot) - + self.member_monitor = ChatroomMemberMonitor(self.ipad_bot) # # 获取扩展信息,显示相关内容 ext_profile = await self.ipad_bot.get_profile_info_ext() self.ipad_bot.profile_ext = ext_profile @@ -272,6 +273,12 @@ class Robot: # 只有当 Ret 不等于 0 或者 不包含 KeyBuf 时才打印 if not (isinstance(data_temp, dict) and data_temp.get("Ret") == 0 and "KeyBuf" in data_temp): self.LOG.debug(f"MESSAGE:{data_temp}") + changed_groups = self.member_monitor.parse_mod_contacts_msg(data_temp) + if changed_groups: + self.LOG.info(f"监测到群成员变动消息,涉及群: {changed_groups}") + for group_id in changed_groups: + xx = asyncio.create_task(self.member_monitor.check_and_handle_changes(group_id)) + # 使用异步睡眠替代忙等待循环 await asyncio.sleep(2) diff --git a/utils/wechat/member_monitor.py b/utils/wechat/member_monitor.py new file mode 100644 index 0000000..2e6ee8b --- /dev/null +++ b/utils/wechat/member_monitor.py @@ -0,0 +1,232 @@ +import asyncio +from typing import List, Dict, Optional, Tuple, Set +from loguru import logger + +from wechat_ipad import WechatAPIClient +from db.connection import DBConnectionManager +from db.contacts_db import ContactsDBOperator + + +class ChatroomMemberMonitor: + """ + 群成员变动监控工具类 + """ + def __init__(self, ipad_bot: WechatAPIClient): + self.ipad_bot = ipad_bot + self.logger = logger + # 获取 DBManager 单例 + self.db_manager = DBConnectionManager.get_instance() + self.db = ContactsDBOperator(self.db_manager) + + async def check_and_handle_changes(self, group_id: str): + """ + 检查指定群的成员变动并处理 + :param group_id: 群聊ID (xxx@chatroom) + """ + self.logger.info(f"开始检查群 {group_id} 成员变动...") + + # 1. 获取最新群成员列表 (API) + try: + api_members = await self.ipad_bot.get_chatroom_member_list(group_id) + if not api_members: + self.logger.warning(f"API获取群 {group_id} 成员列表为空") + return + except Exception as e: + self.logger.error(f"API获取群 {group_id} 成员列表失败: {e}") + return + + # 2. 获取缓存中的群成员列表 (DB) + db_members = self.db.get_chatroom_member_list(group_id) + + # 3. 对比分析 + changes = self._analyze_changes(api_members, db_members) + + # 4. 逻辑处理 + if changes['has_changes']: + await self._process_changes(group_id, changes, api_members) + + # 5. 更新缓存 (将最新的列表保存到数据库) + # 注意:这里我们使用 save_chatroom_member_simple 更新所有成员 + # 为了保持一致性,可以选择先删除旧的再插入,或者依赖 save_chatroom_member_simple 的 ON DUPLICATE KEY UPDATE + # 考虑到有人离开,单纯 update 可能不够(离开的人还在库里),所以应该处理删除逻辑 + # save_chatroom_member_simple 主要是插入/更新,不会删除不存在的人 + + # 所以需要从数据库中删除已经离开的成员 + if changes['removed']: + removed_wxids = [m['wxid'] for m in changes['removed']] + self._remove_members_from_db(group_id, removed_wxids) + + # 保存/更新现有的成员 + if api_members: + self.db.save_chatroom_member_simple(group_id, api_members) + self.logger.info(f"群 {group_id} 成员缓存已更新") + else: + self.logger.info(f"群 {group_id} 成员无变化") + + def _analyze_changes(self, api_members: List[Dict], db_members: List[Dict]) -> Dict: + """ + 对比API数据和DB数据,找出差异 + """ + # 构建 API 成员字典 {wxid: member_info} + # api_member keys: UserName, NickName, DisplayName, ... + api_map = {} + for m in api_members: + wxid = m.get('UserName') + if wxid: + api_map[wxid] = { + 'wxid': wxid, + 'nick_name': m.get('NickName', ''), + 'display_name': m.get('DisplayName', ''), + # 可以在这里添加更多需要对比的字段 + } + + # 构建 DB 成员字典 {wxid: member_info} + # db_member keys: wxid, nick_name, display_name, ... + db_map = {} + for m in db_members: + wxid = m.get('wxid') + if wxid: + db_map[wxid] = { + 'wxid': wxid, + 'nick_name': m.get('nick_name', ''), + 'display_name': m.get('display_name', ''), + } + + added = [] + removed = [] + modified = [] + + # 检查新增和修改 + for wxid, api_m in api_map.items(): + if wxid not in db_map: + added.append(api_m) + else: + db_m = db_map[wxid] + # 检查群昵称是否修改 + # 逻辑:如果API的DisplayName与DB不同,或者(API没有DisplayName且NickName与DB不同) + # 简单起见,对比 display_name 和 nick_name + # 注意:API返回的 DisplayName 为空字符串时,通常表示未设置群昵称,此时展示的是 NickName + + # 对比 display_name (群昵称) + api_disp = api_m['display_name'] + db_disp = db_m['display_name'] + + # 对比 nick_name (微信昵称) - 虽然题目主要关注"用户群昵称修改",但昵称变了也算信息变更 + api_nick = api_m['nick_name'] + db_nick = db_m['nick_name'] + + if api_disp != db_disp: + modified.append({ + 'wxid': wxid, + 'type': 'display_name_change', + 'old': db_disp, + 'new': api_disp, + 'member': api_m + }) + elif api_nick != db_nick: # 可选:如果只关心群昵称,可以注释掉这个elif + modified.append({ + 'wxid': wxid, + 'type': 'nick_name_change', + 'old': db_nick, + 'new': api_nick, + 'member': api_m + }) + + # 检查减少 + for wxid, db_m in db_map.items(): + if wxid not in api_map: + removed.append(db_m) + + has_changes = bool(added or removed or modified) + + return { + 'has_changes': has_changes, + 'added': added, + 'removed': removed, + 'modified': modified + } + + async def _process_changes(self, group_id: str, changes: Dict, api_members: List[Dict]): + """ + 处理具体的变动逻辑 + """ + news = [] + + # 1. 用户减少 + for m in changes['removed']: + name = m.get('display_name') or m.get('nick_name') or m.get('wxid') + self.logger.info(f"[成员减少] 群 {group_id}: 用户 {name} ({m['wxid']}) 已退出或被移除") + news.append(f"❌ 成员减少: {name}") + + # 2. 用户增多 + for m in changes['added']: + name = m.get('display_name') or m.get('nick_name') or m.get('wxid') + self.logger.info(f"[成员新增] 群 {group_id}: 用户 {name} ({m['wxid']}) 已加入") + news.append(f"🆕 成员新增: {name}") + + # 3. 用户群昵称修改 + for m in changes['modified']: + wxid = m['wxid'] + name = m['member'].get('nick_name') + if m['type'] == 'display_name_change': + self.logger.info(f"[昵称修改] 群 {group_id}: 用户 {name} ({wxid}) 群昵称从 '{m['old']}' 修改为 '{m['new']}'") + news.append(f"📝 昵称修改: {name} ({m['old']} -> {m['new']})") + elif m['type'] == 'nick_name_change': + self.logger.info(f"[昵称修改] 群 {group_id}: 用户 {name} ({wxid}) 微信昵称从 '{m['old']}' 修改为 '{m['new']}'") + # 微信昵称修改通常不通报,除非特别要求 + # news.append(f"📝 微信昵称修改: {m['old']} -> {m['new']}") + + if news: + msg_content = "📋 群成员变动通知:\n" + "\n".join(news) + try: + await self.ipad_bot.send_text_message(group_id, msg_content) + self.logger.info(f"已发送群成员变动通知到 {group_id}") + except Exception as e: + self.logger.error(f"发送群成员变动通知失败: {e}") + + def _remove_members_from_db(self, group_id: str, wxid_list: List[str]): + """ + 从数据库中删除指定的群成员 + """ + if not wxid_list: + return + + try: + # 构造 SQL 删除语句 + # 注意:ContactsDB 类可能没有直接删除特定成员的方法,这里我们需要手动执行 SQL 或者扩展 ContactsDB + # 查看 contacts_db.py 发现有 execute_update 方法,但通常建议封装在 DB 类中 + # 这里直接使用 execute_update 如果权限允许,或者我们假设 db 有这个能力 + + placeholders = ', '.join(['%s'] * len(wxid_list)) + sql = f"DELETE FROM t_chatroom_member WHERE chatroom_id = %s AND wxid IN ({placeholders})" + params = [group_id] + wxid_list + + self.db.execute_update(sql, tuple(params)) + self.logger.info(f"从数据库移除 {len(wxid_list)} 个成员: {wxid_list}") + except Exception as e: + self.logger.error(f"从数据库移除成员失败: {e}") + + def parse_mod_contacts_msg(self, msg_content: Dict) -> List[str]: + """ + 解析 ModContacts 消息,提取受影响的群ID + :param msg_content: 消息内容的字典 (例如 message.txt 中的内容) + :return: 涉及的群ID列表 + """ + group_ids = set() + mod_contacts = msg_content.get('ModContacts', []) + if not mod_contacts: + return [] + + for contact in mod_contacts: + user_name_obj = contact.get('UserName', {}) + # 兼容不同的数据结构,有的可能是直接字符串,有的是 {'string': '...'} + user_name = "" + if isinstance(user_name_obj, dict): + user_name = user_name_obj.get('string', '') + elif isinstance(user_name_obj, str): + user_name = user_name_obj + + if user_name.endswith('@chatroom'): + group_ids.add(user_name) + + return list(group_ids) diff --git a/utils/wechat/message.txt b/utils/wechat/message.txt new file mode 100644 index 0000000..83ee44c --- /dev/null +++ b/utils/wechat/message.txt @@ -0,0 +1 @@ +2026-01-19 14:56:28.366 | DEBUG | robot:_wechat_ipad_core:274 - MESSAGE:{'ModUserInfos': None, 'ModContacts': [{'UserName': {'string': '56594698995@chatroom'}, 'NickName': {'string': 'WeChat Robot'}, 'PyInitial': {'string': 'WECHATROBOT'}, 'QuanPin': {'string': 'WeChatRobot'}, 'Sex': 0, 'ImgBuf': {'iLen': 0}, 'BitMask': 4294967295, 'BitVal': 2, 'ImgFlag': 1, 'Remark': {}, 'RemarkPyinitial': {}, 'RemarkQuanPin': {}, 'ContactType': 0, 'RoomInfoCount': 0, 'DomainList': [{}], 'ChatRoomNotify': 0, 'AddContactScene': 0, 'PersonalCard': 0, 'HasWeiXinHdHeadImg': 0, 'VerifyFlag': 0, 'Level': 0, 'Source': 0, 'ChatRoomOwner': 'wxid_b28npmhznnwl12', 'WeiboFlag': 0, 'AlbumStyle': 0, 'AlbumFlag': 0, 'SnsUserInfo': {'SnsFlag': 0, 'SnsBgobjectId': 0, 'SnsFlagEx': 0}, 'CustomizedInfo': {'BrandFlag': 0}, 'AdditionalContactList': {'LinkedinContactItem': {}}, 'ChatroomMaxCount': 10624, 'DeleteFlag': 0, 'Description': '\x08�\x01\x12\x1c\n\x13wxid_b28npmhznnwl120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_7bpstqonj922120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_45qclaghhim5220\x01@\x00�\x01\x00\x12\x10\n\x07hengist0\t@\x00�\x01\x00\x12\x1c\n\x13wxid_28vy4rytnl5a120\x01@\x00�\x01\x00\x12\x17\n\rxiehuaping6680�\x10@\x00�\x01\x00\x12\x16\n\rweipeng_Angus0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_ur8bdioku6k0210\x01@\x00�\x01\x00\x12\x18\n\x0eiversonyanghan0�@@\x00�\x01\x00\x12\x14\n\nq2546693290�@@\x00�\x01\x00\x12\x1c\n\x13wxid_3vsb0fy2idri220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_jcdu1qygioqs220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_gkgrj231lhoa120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_7dky6wp3hg9u220\x01@\x00�\x01\x00\x12\x17\n\rlzm15114166560�@@\x00�\x01\x00\x12\x1d\n\x13wxid_qgml5g7x6o3r220�@@\x00�\x01\x00\x12\x11\n\x08lw9918260\x01@\x00�\x01\x00\x12\x13\n\nz6143872660\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_613jq8n1n6bg120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_d52rxumg20z0220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_gkku6w4sg4je220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_8m7go53ytrya220\x01@\x00�\x01\x00\x12\x11\n\x08moyinlgq0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_gqhxp9ipfxv2220\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_5qfinnohy0yk290�@@\x00�\x01\x00\x12\x1c\n\x13wxid_6q3ar4xb7m19220\t@\x00�\x01\x00\x12\x1c\n\x13wxid_7lrsknh1zvpw220\x01@\x00�\x01\x00\x12\x1c\n\x12wxid_93418234201120�@@\x00�\x01\x00\x12\x1c\n\x13wxid_ovdiwcveyc9x220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_8m3h0yofz6dr220\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_q9g3216s6tdo720�@@\x00�\x01\x00\x12\x10\n\x07fengch10\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_gol6pf6fq4se210\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_8w7uvwatvyhi220\x01@\x00�\x01\x00\x12\x12\n\tjieke62570\x11@\x00�\x01\x00\x12\x1c\n\x13wxid_5rdsdy7uf8th120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_a0jwxfkuq9o4120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_z7qkrszzrfu0220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_wcz8ygnlj3kk220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_i0llb0sn41cs210\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_cieka88s98pg290\x01@\x00�\x01\x00\x12\x19\n\x0fweipeng198510120�@@\x00�\x01\x00\x12\x1c\n\x13wxid_nkl05ua5519u210\x01@\x00�\x01\x00\x12\x12\n\txueqiqius0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_bfxrmdtepwx1120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_ceqges4ueykg220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_rm8cr2qjf45n120\x11@\x00�\x01\x00\x12\x1c\n\x13wxid_ubo0cy5xh4px220\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_d439rfxsetl2110�@@\x00�\x01\x00\x12\x10\n\x07mumutoy0\x01@\x00�\x01\x00\x12\x14\n\x0bcjl264079640\t@\x00�\x01\x00\x12\x1c\n\x13wxid_751hg5yu70rf220\x01@\x00�\x01\x00\x12\x12\n\ti______ck0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_c7vgz2gd7uml220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_93d0t3p61s06220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_ascibcwgliyk220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_sj8wz01la47v220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_yl84hx6o9svi220\x01@\x00�\x01\x00\x12\x11\n\x08a78917490\x01@\x00�\x01\x00\x12\x11\n\x07orrinjj0�@@\x00�\x01\x00\x12\x1c\n\x13wxid_f92ilzlsjlka220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_0ycf7d3d506t220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_sqsom5i07fd4220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_cur3larj3ikj120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_wx4l3fhkudu0220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_1s8pwoa9rl6f210\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_vqkeovas303o220\x01@\x00�\x01\x00\x12\x10\n\x07jundayw0\t@\x00�\x01\x00\x12\x1b\n\x12wxid_71360213601120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_ljv0fz399msu220\x01@\x00�\x01\x00\x12\x10\n\x07Jyunere0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_xwemtsyy8fxr220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_0uwy2vxgw57v220\x01@\x00�\x01\x00\x12\x12\n\tqq50005210\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_260emr01m55d220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_yfqkjgku4hgm220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_a7olcpwehqnh220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_72ow1edm3kea220\x01@\x00�\x01\x00\x12\x13\n\nhuage100600\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_01tuau75pj1w220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_rxr1t6rgy663220\x01@\x00�\x01\x00\x12\x11\n\x08rayxu0010\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_7wnuussanu6s210\x11@\x00�\x01\x00\x12\x1c\n\x13wxid_gn9vcg4a5fgp220\x11@\x00�\x01\x00\x12\x1b\n\x12juhuakaipinggai0020\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_royxrybbzq5j220\x01@\x00�\x01\x00\x12\x15\n\x0cxiao813977830\x01@\x00�\x01\x00\x12\x10\n\x07allofee0\t@\x00�\x01\x00\x12\x1c\n\x13wxid_yyo4v1mtwra6220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_p2bos0iwsbg9220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_j846ymvp431j120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_mn36thj7nujx220\x01@\x00�\x01\x00\x12\x11\n\x08zbigbird0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_h8e0wsyosnwb220\x01@\x00�\x01\x00\x12\x13\n\nyl199308220\x01@\x00�\x01\x00\x12\x14\n\x0byang_guang_0\x01@\x00�\x01\x00\x12\x16\n\rshoujilei33790\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_pn9dhmuthc2v220�@@\x00�\x01\x00\x12\x1d\n\x13wxid_jn599o1zscbj220�@@\x00�\x01\x00\x12\x1c\n\x13wxid_cjtx8ouwtv9n210\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_vy6sir5dchx4220\x01@\x00�\x01\x00\x12\x10\n\x07cgd93930\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_lmimu17ixpbc210\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_ngux2qfqjmuj220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_kr8wlfz7eb2i220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_y17nryqd5ia3220\x01@\x00�\x01\x00\x12\x1c\n\x12wxid_79173591730120�@@\x00�\x01\x00\x12\x1c\n\x13wxid_neg6p4c62len220\x01@\x00�\x01\x00\x12\x10\n\x07t_glove0\x01@\x00�\x01\x00\x12\x13\n\noooeovlooo0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_z3ry87638gws320\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_p1oxwu3nd166220\x19@\x00�\x01\x00\x12\x16\n\rcaiwanlingcwl0\x01@\x00�\x01\x00\x12\x10\n\x07anvaest0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_xxci433b377z210\x01@\x00�\x01\x00\x12\x12\n\tIceCry6130\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_ygk83i2r1son220�@@\x00�\x01\x00\x12\x13\n\nJason223090\x01@\x00�\x01\x00\x12\x11\n\x08Rs_Close0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_27eirern20rf210\x01@\x00�\x01\x00\x12\x12\n\tyuhai02070\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_w0l2tecoao7s120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_2ci458bc6nq2220\t@\x00�\x01\x00\x12\x1c\n\x13wxid_q8h65hcwg1au220\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_ncpfzn22lfea220�@@\x00�\x01\x00\x12\x1b\n\x12wxid_29057190613120\x11@\x00�\x01\x00\x12\x17\n\x0etaotaolinangel0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_0a3mxmfywr8h220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_2lhx7btefa0d220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_7fvd551co49e220\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_ss80k7krfrny210�@@\x00�\x01\x00\x12\x16\n\rAinidechouren0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_x1ihnent6tja210\x01@\x00�\x01\x00\x12\x1f\n\x13wxid_vprfp0sk2o7y220���\x03@\x00�\x01\x00\x12\x15\n\x0cliu6750613700\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_h8huak2oddw2210\x01@\x00�\x01\x00\x12\x0f\n\x06X-soda0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_bzfe8nljjiut220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_czirx17x34lm220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_bs86nlwhmblw220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_lvr6jsapco5d220\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_bnhk86sf8kpw220�@@\x00�\x01\x00\x12\x10\n\x07scottuk0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_y89gujlu6ed4220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_d1l7bybc3bun220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_2pw7xkmr1fqz220\x01@\x00�\x01\x00\x12\x1b\n\x12wxid_76874268763120\x01@\x00�\x01\x00\x12\x10\n\x07wan74260\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_5v7cey0mar9q220\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_t8p67vpimx0d220�@@\x00�\x01\x00\x12\x13\n\nQ8442990350\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_dg5xnz4s39ea210\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_uy2nvj1es6fa220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_pgrtm7al7hja120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_g4p84xthi1qt220\x01@\x00�\x01\x00\x12\x10\n\x07hecarli0\t@\x00�\x01\x00\x12\x1c\n\x13wxid_kbur705rdkt7220\x01@\x00�\x01\x00\x12\x14\n\x0bchengke19910\x01@\x00�\x01\x00\x12\x15\n\x0cpei3896628320\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_3ndsct6d4dpn220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_gvh0lj2bqgk3120\x01@\x00�\x01\x00\x12\x11\n\x08sencn0010\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_sh3e2dicv2j1220\x11@\x00�\x01\x00\x12\x1d\n\x13wxid_nk2aqc0mrfdb220�@@\x00�\x01\x00\x12\x1c\n\x13wxid_qsodqeep234e220\x01@\x00�\x01\x00\x12\x17\n\x0efengchenhao0020\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_s0aqakkybuek220\x19@\x00�\x01\x00\x12\x1c\n\x12wodeyouxiangyuyuan0�@@\x00�\x01\x00\x12\x1c\n\x13wxid_ukjx9z9wv8sl220\x01@\x00�\x01\x00\x12\x11\n\x08juliy3330\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_0jnwhnvi1u0d220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_01gk363emfno220\x01@\x00�\x01\x00\x12\x10\n\x07NYLiuZC0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_e6es87wvw19u220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_0c1entrdaiad220\x01@\x00�\x01\x00\x12\x1b\n\x12wxid_19203891960120\t@\x00�\x01\x00\x12\x1c\n\x13wxid_pv09ly03dih2210\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_s6gshn8zhxms720\x01@\x00�\x01\x00\x12\x0f\n\x06fj_cqv0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_ij6r44u5e438290\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_243qcni3r6z3220�@@\x00�\x01\x00\x12\x1c\n\x13wxid_yrsl9joj8ise220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_7eadcgb6a50a210\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_kiymanw33ec5220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_0uy71ovzj4an220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_cqoaubiun76m220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_10sjbvsfb7wv220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_vg6uoeoprom5210\x01@\x00�\x01\x00\x12\x14\n\x0bmm24lizheng0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_m7lw5243o1h5220\x01@\x00�\x01\x00\x12\x1c\n\x12wxid_38262282622120�@@\x00�\x01\x00\x12\x1c\n\x13wxid_tee841t4hika220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_ax1e145kufqc220\x01@\x00�\x01\x00\x12\x14\n\x0bwangzi_87880\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_n9o58gpxs1gm220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_y6bh6w5o3jut220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_gvr9a3le939h220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_ppmfbcc7wcaq220\x01@\x00�\x01\x00\x12\x1d\n\x13wxid_xw9hl7rgz4tx220�@@\x00�\x01\x00\x12\x1c\n\x13wxid_l4dl6rd07yk9220\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_s0kclz1rpoek220\x01@\x00�\x01\x00\x12\x11\n\x08depth7100\x01@\x00�\x01\x00\x12\x0f\n\x06cxgwbk0\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_i73nrnun919k120\x01@\x00�\x01\x00\x12\x1c\n\x13wxid_cpc62y9t7ehs220\x01@\x00�\x01\x00\x12\x1b\n\x12wxid_nu7hfab1vn5220\x01@\x00�\x01\x00\x12\x0f\n\x06denbyn0\x01@\x00�\x01\x00\x12\x18\n\x0efletcher0253090�@@\x00�\x01\x00\x12\x1c\n\x13wxid_y7rn91nab9zg220\x01@\x00�\x01\x00\x18\x01"\x00(\x008\x00', 'ChatroomStatus': 13, 'Extflag': 0, 'ChatRoomBusinessType': 0}], 'DelContacts': None, 'ModUserImgs': None, 'FunctionSwitchs': None, 'UserInfoExts': None, 'AddMsgs': None, 'ContinueFlag': 2097408, 'KeyBuf': {'iLen': 354, 'buffer': 'CC8SCAgBELK9zIsDEgQIZRAAEgYIAhDk5B8SBAhmEAASBAgNEAASBQjMARAAEggIAxCOvcyLAxIECGcQABIICAsQtL3MiwMSBAhvEAASBAgEEAASBAhoEAASBAgFEAASBAhpEAASBAgHEAASBAhrEAASBAgIEAASBAhsEAASBAgJEAASBAhtEAASCAgWELG1zIsDEgQIBhAAEgQIehAAEgQIahAAEgQIEBAAEgQIERAAEgQIchAAEggIDhDJgcyLAxIECHAQABIGCBMQreQCEgQIGhAAEgYIGxDk5B8SCAgYEJOrt8sGEggIFxCu+PvKBhIGCBkQ5OQfEgQIChAAEgkIyQEQk6u3ywYSBQjNARAAEgkIygEQq/izywYSCQjLARCbq7fLBhIFCM4BEGUSBQjPARAAEgQIFBAAEgQIFRAAEgkI6AcQ4fu2ywYSCQjpBxCairfLBhIJCNMPEJKTt8sG'}, 'Status': 1, 'Continue': 697507902, 'Time': 1768805787, 'UnknownCmdId': '', 'Remarks': '出现未解析的CmdId类型数据,请联系客服人员处理。'}