diff --git a/db/contacts_db.py b/db/contacts_db.py index a2422ef..3dec4ad 100644 --- a/db/contacts_db.py +++ b/db/contacts_db.py @@ -331,116 +331,71 @@ class ContactsDBOperator(BaseDBOperator): self.LOG.error(f"获取所有联系人名称映射失败: {e}") return {} def save_chatroom_member_simple(self, chatroom_id: str, member_details: List[Dict]) -> bool: - """保存简化版的群成员信息到数据库 - + """ + 保存群成员简要信息到数据库,兼容不同数据结构 Args: chatroom_id: 群聊ID - member_details: 群成员信息列表,格式为: - [{'UserName': str, 'NickName': str, 'InviterUserName': str, - 'ChatroomMemberFlag': int, 'DisplayName': str}] - + member_details: 群成员信息列表 Returns: bool: 是否成功保存 """ - if not member_details or not chatroom_id: - self.LOG.warning(f"没有群聊{chatroom_id}的成员信息需要保存") - return False + if not member_details: + self.LOG.warning(f"群 {chatroom_id} 没有成员数据需要保存") + return True try: for member in member_details: - # 处理新的数据结构 - wxid = "" - if "UserName" in member: - if isinstance(member["UserName"], dict): - wxid = member["UserName"].get("string", "") - else: - wxid = member.get("UserName", "") - elif "wxid" in member: - wxid = member.get("wxid", "") - - if not wxid: - continue - - # 提取昵称 - nick_name = "" - if "NickName" in member: - if isinstance(member["NickName"], dict): - nick_name = member["NickName"].get("string", "") - else: - nick_name = member.get("NickName", "") - elif "nickName" in member: - nick_name = member.get("nickName", "") - - # 提取邀请人 - inviter_user_name = "" - if "InviterUserName" in member: - inviter_user_name = member.get("InviterUserName", "") - elif "inviterUserName" in member: - inviter_user_name = member.get("inviterUserName", "") - - # 提取成员标志 - member_flag = 0 - if "ChatroomMemberFlag" in member: - member_flag = member.get("ChatroomMemberFlag", 0) - elif "memberFlag" in member: - member_flag = member.get("memberFlag", 0) - - # 判断是否为群主 - is_owner = 0 - if chatroom_id and wxid: - # 查询群信息,检查是否为群主 - chat_room_owner_sql = """ - SELECT chat_room_owner FROM t_chatrooms - WHERE chatroom_id = %s - """ - chat_room_owner_result = self.execute_query(chat_room_owner_sql, (chatroom_id,), fetch_one=True) - if chat_room_owner_result and chat_room_owner_result.get('chat_room_owner') == wxid: - is_owner = 1 + # 兼容微信协议风格的数据结构 + def get_str(field, default=""): + val = member.get(field, default) + if isinstance(val, dict): + return val.get("string", default) + return val if val is not None else default - # 构建数据 data = { 'chatroom_id': chatroom_id, - 'wxid': wxid, - 'nick_name': nick_name, - 'display_name': member.get('DisplayName', ''), - 'inviter_user_name': inviter_user_name, - 'member_flag': member_flag, - 'big_head_img_url': member.get('bigHeadImgUrl', ''), - 'small_head_img_url': member.get('smallHeadImgUrl', ''), - 'is_owner': is_owner, - 'is_admin': 1 if member_flag == 2049 else 0, # 根据memberFlag判断是否为管理员 - # 其他字段使用默认值 - 'sex': 0, - 'signature': '', - 'alias': '', - 'country': '', - 'province': '', - 'city': '', - 'label_list': '', - 'phone_num_list': '', - 'py_initial': '', - 'quan_pin': '', - 'remark_py_initial': '', - 'remark_quan_pin': '' + 'wxid': get_str('UserName'), + 'nick_name': get_str('NickName'), + 'display_name': get_str('DisplayName'), + 'inviter_user_name': get_str('InviterUserName'), + 'member_flag': member.get('MemberFlag', 0), + 'big_head_img_url': get_str('BigHeadImgUrl'), + 'small_head_img_url': get_str('SmallHeadImgUrl'), + 'is_owner': 1 if member.get('IsOwner', False) else 0, + 'is_admin': 1 if member.get('IsAdmin', False) else 0, + 'sex': member.get('Sex', 0), + 'signature': get_str('Signature'), + 'alias': get_str('Alias'), + 'country': get_str('Country'), + 'province': get_str('Province'), + 'city': get_str('City'), + 'label_list': '', # 可根据需要补充 + 'phone_num_list': '', # 可根据需要补充 + 'py_initial': get_str('Pyinitial'), + 'quan_pin': get_str('QuanPin'), + 'remark_py_initial': get_str('RemarkPyinitial'), + 'remark_quan_pin': get_str('RemarkQuanPin'), } - # 构建SQL语句 fields = ', '.join(data.keys()) placeholders = ', '.join(['%s'] * len(data)) values = tuple(data.values()) + update_clause = ', '.join([f"{k}=VALUES({k})" for k in data.keys() if k not in ('chatroom_id', 'wxid')]) + sql = f""" - REPLACE INTO t_chatroom_member ({fields}) + INSERT INTO t_chatroom_member ({fields}) VALUES ({placeholders}) + ON DUPLICATE KEY UPDATE {update_clause} """ self.execute_update(sql, values) - self.LOG.info(f"成功保存群聊{chatroom_id}的{len(member_details)}个成员信息") + self.LOG.info(f"成功保存群 {chatroom_id} 的 {len(member_details)} 个成员信息") return True except Exception as e: - self.LOG.error(f"保存群聊{chatroom_id}的成员信息失败: {e}") + self.LOG.error(f"保存群 {chatroom_id} 成员信息失败: {e}") return False def save_chatroom_member_detail(self, chatroom_id: str, member_details: List[Dict]) -> bool: """保存群成员详细信息到数据库 @@ -556,77 +511,43 @@ class ContactsDBOperator(BaseDBOperator): return False def save_chatroom_info(self, chatroom_data: dict) -> bool: - """保存群信息到数据库""" + """保存群信息到数据库,兼容微信协议风格字段""" try: - # 处理新的数据结构 - user_name = "" - if isinstance(chatroom_data, dict): - if "UserName" in chatroom_data and isinstance(chatroom_data["UserName"], dict): - user_name = chatroom_data["UserName"].get("string", "") - elif "chatroomId" in chatroom_data: - user_name = chatroom_data.get("chatroomId", "") - - if not user_name: - self.LOG.warning("无法获取群聊ID,保存失败") - return False - - # 提取群聊名称 - nick_name = "" - if "NickName" in chatroom_data and isinstance(chatroom_data["NickName"], dict): - nick_name = chatroom_data["NickName"].get("string", "") - elif "chatroomName" in chatroom_data: - nick_name = chatroom_data.get("chatroomName", "") - - # 提取群主信息 - chat_room_owner = "" - if "ChatRoomOwner" in chatroom_data: - chat_room_owner = chatroom_data.get("ChatRoomOwner", "") - - # 提取群通知设置 - chat_room_notify = 0 - if "ChatRoomNotify" in chatroom_data: - chat_room_notify = chatroom_data.get("ChatRoomNotify", 0) - - # 提取群头像 - small_head_img_url = "" - if "SmallHeadImgUrl" in chatroom_data: - small_head_img_url = chatroom_data.get("SmallHeadImgUrl", "").strip() - - # 提取群成员列表 - member_list = [] - if "NewChatroomData" in chatroom_data and "ChatRoomMember" in chatroom_data["NewChatroomData"]: - member_list = chatroom_data["NewChatroomData"].get("ChatRoomMember", []) - elif "memberList" in chatroom_data: - member_list = chatroom_data.get("memberList", []) - + def get_str(field, default=""): + val = chatroom_data.get(field, default) + if isinstance(val, dict): + return val.get("string", default) + return val if val is not None else default + data = { - 'chatroom_id': user_name, - 'nick_name': nick_name, - 'py_initial': chatroom_data.get('Pyinitial', {}).get('string', ''), - 'quan_pin': chatroom_data.get('QuanPin', {}).get('string', ''), + 'chatroom_id': get_str('UserName'), + 'nick_name': get_str('NickName'), + 'py_initial': get_str('Pyinitial'), + 'quan_pin': get_str('QuanPin'), 'sex': chatroom_data.get('Sex', 0), - 'remark': chatroom_data.get('Remark', {}).get('string', ''), - 'remark_py_initial': chatroom_data.get('RemarkPyinitial', {}).get('string', ''), - 'remark_quan_pin': chatroom_data.get('RemarkQuanPin', {}).get('string', ''), - 'chat_room_notify': chat_room_notify, - 'chat_room_owner': chat_room_owner, - 'small_head_img_url': small_head_img_url, - 'member_list': json.dumps(member_list) + 'remark': get_str('Remark'), + 'remark_py_initial': get_str('RemarkPyinitial'), + 'remark_quan_pin': get_str('RemarkQuanPin'), + 'chat_room_notify': chatroom_data.get('ChatRoomNotify', 0), + 'chat_room_owner': chatroom_data.get('ChatRoomOwner', ''), + 'small_head_img_url': chatroom_data.get('SmallHeadImgUrl', ''), + # 成员列表可选存储为JSON字符串 + 'member_list': json.dumps(chatroom_data.get('NewChatroomData', {}).get('ChatRoomMember', []), ensure_ascii=False) } - + fields = ', '.join(data.keys()) placeholders = ', '.join(['%s'] * len(data)) - update_clause = ', '.join([f"{k}=VALUES({k})" for k in data.keys() if k != 'chatroom_id']) values = tuple(data.values()) - + update_clause = ', '.join([f"{k}=VALUES({k})" for k in data.keys() if k != 'chatroom_id']) + sql = f""" INSERT INTO t_chatrooms ({fields}) VALUES ({placeholders}) ON DUPLICATE KEY UPDATE {update_clause} """ - + self.execute_update(sql, values) - self.LOG.info(f"成功保存群聊 {data['chatroom_id']} 信息") + self.LOG.info(f"成功保存群聊信息: {data['chatroom_id']}") return True except Exception as e: self.LOG.error(f"保存群聊信息失败: {e}") diff --git a/robot.py b/robot.py index 111bf95..86b11e1 100644 --- a/robot.py +++ b/robot.py @@ -360,25 +360,20 @@ class Robot(Job): # 保存群信息到数据库 self.contacts_db.save_chatroom_info(chatroom_info) - # 保存群成员信息 + # 保存群成员信息 if "NewChatroomData" in chatroom_info and "ChatRoomMember" in chatroom_info["NewChatroomData"]: member_list = chatroom_info["NewChatroomData"]["ChatRoomMember"] + # 兼容逻辑已放到save_chatroom_member_simple内部 self.contacts_db.save_chatroom_member_simple(group_id, member_list) # 更新联系人缓存 for member in member_list: - wxid = "" - if isinstance(member.get("UserName"), dict): - wxid = member["UserName"].get("string", "") - else: - wxid = member.get("UserName", "") - - nick_name = "" - if isinstance(member.get("NickName"), dict): - nick_name = member["NickName"].get("string", "") - else: - nick_name = member.get("NickName", "") - + wxid = member.get("UserName", "") + if isinstance(wxid, dict): + wxid = wxid.get("string", "") + nick_name = member.get("NickName", "") + if isinstance(nick_name, dict): + nick_name = nick_name.get("string", "") if wxid: self.allContacts[wxid] = nick_name