From da5ce935b95dca2e761774145fe4fdb94ac9c18d Mon Sep 17 00:00:00 2001 From: liuwei Date: Tue, 22 Apr 2025 13:43:03 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gewechat/call_back_message/message.py | 40 ++++++++++++--- robot.py | 45 +++++++++-------- utils/json_converter.py | 73 +++++++-------------------- 3 files changed, 76 insertions(+), 82 deletions(-) diff --git a/gewechat/call_back_message/message.py b/gewechat/call_back_message/message.py index ab0ce09..5f151fa 100644 --- a/gewechat/call_back_message/message.py +++ b/gewechat/call_back_message/message.py @@ -7,6 +7,7 @@ import json class MessageType(Enum): """消息类型枚举""" + UNKNOWN = 0 # 未知类型 TEXT = 1 # 文本消息 IMAGE = 3 # 图片消息 VOICE = 34 # 语音消息 @@ -27,13 +28,26 @@ class MessageType(Enum): class AppMessageType(Enum): """应用消息类型枚举""" + UNKNOWN = 0 # 未知类型 + TEXT = 1 # 文本 + IMG = 2 # 图片 + AUDIO = 3 # 音频 + VIDEO = 4 # 视频 LINK = 5 # 链接消息 - FILE = 6 # 文件消息 - FILE_NOTICE = 74 # 文件上传通知 - MINIPROGRAM = 33 # 小程序消息 - QUOTE = 57 # 引用消息 - TRANSFER = 2000 # 转账消息 - RED_PACKET = 2001 # 红包消息 + FILE = 6 # 文件 + QUOTE = 57 # 引用 + EMOJI = 8 # 表情 + LOCATION = 17 # 位置 + APP_MSG = 33 # APP消息 + MINIPROGRAM = 36 # 小程序 + TRANSFER = 2000 # 转账 + RED_PACKET = 2001 # 红包 + CARD_TICKET = 2002 # 卡券 + REAL_TIME_LOCATION_START = 17 # 实时位置共享开始 + REAL_TIME_LOCATION_STOP = 18 # 实时位置共享结束 + CARD = 42 # 名片 + VOICE_REMIND = 43 # 语音提醒 + FILE_NOTICE = 74 # 文件通知 CHANNELS = 51 # 视频号消息 @@ -217,6 +231,20 @@ class WxMessage: def from_group(self) -> bool: return self.to_user.endswith("@chatroom") + + def is_at(self, wxid) -> bool: + """是否被 @:群消息,在 @ 名单里,并且不是 @ 所有人""" + if not self.from_group(): + return False # 只有群消息才能 @ + + if not re.findall(f"[\s|\S]*({wxid})[\s|\S]*", self.msg_source): + return False # 不在 @ 清单里 + + if re.findall(r"@(?:所有人|all|All)", self.content): + return False # 排除 @ 所有人 + + return True + def get_app_message_type(self) -> Optional[AppMessageType]: """获取应用消息类型""" if self.msg_type != MessageType.APP or not self.content.xml_content: diff --git a/robot.py b/robot.py index eaf1c2d..48f606a 100644 --- a/robot.py +++ b/robot.py @@ -9,18 +9,12 @@ import random from gewechat_client import GewechatClient -from base.func_doubao import Doubao from base.func_epic import is_friday, get_free -from base.func_zhipu import ZhiPu -from base.func_chatgpt import ChatGPT from base.func_news import News -from base.func_tigerbot import TigerBot -from base.func_xinghuo_web import XinghuoWeb -from base.func_claude import Claude from configuration import Config -from constants import ChatType from gewechat.call_back_message.message import WxMessage, MessageType +from utils.json_converter import json_to_object from utils.wechat.message_to_db import MessageStorage from plugin_common.event_system import EventType, EventSystem from plugin_common.message_plugin_interface import MessagePluginInterface @@ -56,6 +50,13 @@ class Robot(Job): self.allContacts = self.get_all_contacts() self.contact_manager.set_contacts(self.allContacts) + # 获取个人信息 + obj = json_to_object(self.client.get_profile(self.app_id)) + if obj.data.wxid is None: + self.LOG.info(f"获取个人信息失败,退出程序!") + return + self.wxid = obj.data.wxid + self.LOG.info(f"DB+REDIS 连接池开始初始化") # 使用单例模式获取实例 self.db_manager = DBConnectionManager.get_instance( @@ -216,7 +217,7 @@ class Robot(Job): self.message_count_to_db() if msg.content == "PDF": self.generate_sehuatang_pdf() - if msg.content.startswith("清除群-"): + if msg.content.raw_content.startswith("清除群-"): self.gbm.handle_command(msg.roomid, msg.content) else: self.toChitchat(msg) # 闲聊 @@ -417,25 +418,25 @@ class Robot(Job): # 初始化联系人数据库操作类 contacts_db = ContactsDBOperator() - + # 将wxid列表分批处理,每批50个 batch_size = 50 for i in range(0, len(contacts_wxids), batch_size): batch_wxids = contacts_wxids[i:i + batch_size] - + # 批量获取联系人详细信息 contact_info = self.client.get_detail_info(self.app_id, batch_wxids) - + # 处理返回的数据 if contact_info and contact_info.get("ret") == 200 and "data" in contact_info: contact_data = contact_info.get("data", []) - + if contact_data: for contact in contact_data: user_name = contact.get("userName") if not user_name: continue - + try: # 判断联系人类型 contact_type = "friends" # 默认为好友类型 @@ -445,13 +446,13 @@ class Robot(Job): self.update_chatroom_member_details(user_name) elif user_name.startswith("gh_"): contact_type = "ghs" - + # 保存到数据库 contacts_db.save_contacts([contact], contact_type) - + # 添加到返回字典 contacts_dict[user_name] = contact.get("nickName") or user_name - + except Exception as e: self.LOG.error(f"处理联系人 {user_name} 失败: {e}") continue @@ -460,7 +461,7 @@ class Robot(Job): self.LOG.info(f"成功获取并保存{len(contacts_dict)}个联系人信息") return contacts_dict - + except Exception as e: self.LOG.error(f"获取联系人信息失败: {e}") return {} @@ -472,10 +473,10 @@ class Robot(Job): members_response = self.client.get_chatroom_member_list(self.app_id, chatroom_id) if members_response and members_response.get('ret') == 200: member_list = members_response.get('data', {}).get('memberList', []) - + # 提取成员wxid列表 member_wxids = [member.get('wxid') for member in member_list if member.get('wxid')] - + if member_wxids: # 按照官方接口格式传递参数 details_response = self.client.get_chatroom_member_detail( @@ -483,17 +484,17 @@ class Robot(Job): chatroom_id, member_wxids # 直接传递列表,不需要转换为集合 ) - + # 使用ContactsDBOperator处理响应 from db.contacts_db import ContactsDBOperator contacts_db = ContactsDBOperator() success = contacts_db.process_chatroom_member_detail_response(chatroom_id, details_response) - + if success: self.LOG.info(f"成功更新群聊{chatroom_id}的成员详细信息") else: self.LOG.error(f"更新群聊{chatroom_id}的成员详细信息失败") - + return success else: self.LOG.warning(f"群聊{chatroom_id}没有成员") diff --git a/utils/json_converter.py b/utils/json_converter.py index fdbe3fd..18ba6d5 100644 --- a/utils/json_converter.py +++ b/utils/json_converter.py @@ -65,56 +65,24 @@ def json_to_object(json_data): if __name__ == "__main__": # 示例JSON数据 example_json = { - "ret": 200, - "msg": "操作成功", - "data": { - "friends": [ - "tmessage", - "medianote", - "qmessage", - "qqmail", - "wxid_910acevfm2nb21", - "qqsafe", - "wxid_9299552988412", - "weixin", - "exmail_tool", - "wxid_mp05xmje0ctn22", - "wxid_09oq4f4j4wg912", - "wxid_6bfguz79h8n122", - "wxid_lyuq4hr4lrjq22", - "wxid_a1zqyljsrsdu12", - "wxid_lv3pb3zhna3522", - "wxid_k2biq6fuinsr22", - "wxid_ujredjhxz9y712", - "wxid_uwb7989u0jea12", - "wxid_in46ey732vxu12", - "wxid_3rvervwohj6921", - "wxid_4wkls7tu62ua12", - "wxid_g0bdknnotx2f12", - "wxid_ce5fgp0icb3y21", - "wxid_1482424825211", - "wxid_vw3p4f6jy7bm12", - "wxid_o2m8xm71c23522", - "wxid_bclqpc2ho6o412", - "wxid_98pjjzpiisi721", - "wxid_noq2wsn5c8h222" - ], - "chatrooms": [ - "2180313478@chatroom", - "14358945067@chatroom", - "17362526147@chatroom", - "11685224357@chatroom", - "17522822550@chatroom" - ], - "ghs": [ - "gh_7aac992b0363", - "gh_d7293b5f14f4", - "gh_f51ce3ef83a4", - "gh_7d20df86e26b", - "gh_69bfb92a3e43" - ] - } - } + "ret": 200, + "msg": "操作成功", + "data": { + "wxid": "zhangchuan2288", + "nickName": "朝夕。", + "mobile": "18761670817", + "uin": 1042679712, + "sex": 1, + "province": "Jiangsu", + "city": "Xuzhou", + "signature": ".......", + "country": "CN", + "bigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/REoLX7KfdibFAgDbtoeXGNjE6sGa8NCib8UaiazlekKjuLneCvicM4xQpuEbZWjjQooSicsKEbKdhqCOCpTHWtnBqdJicJ0I3CgZumwJ6SxR3ibuNs/0", + "smallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/REoLX7KfdibFAgDbtoeXGNjE6sGa8NCib8UaiazlekKjuLneCvicM4xQpuEbZWjjQooSicsKEbKdhqCOCpTHWtnBqdJicJ0I3CgZumwJ6SxR3ibuNs/132", + "regCountry": "CN", + "snsBgImg": "http://shmmsns.qpic.cn/mmsns/FzeKA69P5uIdqPfQxp59LvOohoE2iaiaj86IBH1jl0F76aGvg8AlU7giaMtBhQ3bPibunbhVLb3aEq4/0" + } +} # 转换为对象 obj = json_to_object(example_json) @@ -122,10 +90,7 @@ if __name__ == "__main__": # 通过属性访问 print(f"返回码: {obj.ret}") print(f"消息: {obj.msg}") - print(f"好友数量: {len(obj.data.friends)}") - print(f"第一个好友: {obj.data.friends[0]}") - print(f"第一个群聊: {obj.data.chatrooms[0]}") - + print(f"wxid: {obj.data.wxid}") # 转换回字典 dict_data = obj.to_dict() print(f"转换回字典: {dict_data}") \ No newline at end of file