微信聊天记录监听与转发工具

以下是基于您需求撰写的《微信聊天记录监听与转发工具需求分析开发文档》:

微信聊天记录监听与转发工具

需求分析开发文档

一、项目概述

1.1 目标

开发基于wxauto的自动化工具,实现:

  1. 实时监听指定微信聊天窗口(群组/个人)
  2. 捕获并处理新消息
  3. 按指定策略转发至目标用户"元宝"
  4. 确保操作间隔符合10秒限制

1.2 技术栈

  • 核心框架:Python 3.8+
  • 微信自动化:wxauto_custom (基于wxauto的定制版本)
  • 并发处理:threading
  • 配置管理:configparser
  • 数据结构:collections.deque
  • 异常处理:logging模块
  • 辅助库:random, datetime, os, time

二、核心功能设计

2.1 系统架构

+-----------------------+
|     监听子系统        |
|  - 窗口事件监听       |
|  - 消息队列管理       |
+----------+------------+
           ↓
+-----------------------+
|     处理子系统        |
|  - 消息过滤           |
|  - 内容格式化         |
+----------+------------+
           ↓
+-----------------------+
|     发送子系统        |
|  - 定时调度           |
|  - 消息发送           |
+-----------------------+

2.2 功能模块

模块1:窗口监听器 (WindowMonitor)
class WindowMonitor:
    def __init__(self, queue, wx_instance):
        self.wx = wx_instance # 使用传入的WeChat实例
        self.message_queue = queue
        self.chats_to_monitor = set(CHATS_TO_MONITOR) # 从配置加载
        self.running = False
        self._stop_event = threading.Event()

    def start_listening(self):
        # 启动独立线程进行消息轮询
        self.thread = threading.Thread(target=self._poll_messages, daemon=True)
        self.thread.start()

    def _poll_messages(self):
        # 循环调用 GetNextNewMessage 获取新消息
        while not self._stop_event.is_set():
            aggregated_new_messages = {}
            while True:
                next_new_msg_dict = self.wx.GetNextNewMessage(savepic=True, savefile=True)
                if not next_new_msg_dict:
                    break
                # 处理并聚合消息...
            
            if aggregated_new_messages:
                for chat_name, messages_list in aggregated_new_messages.items():
                    if not self.chats_to_monitor or chat_name in self.chats_to_monitor:
                        for new_msg in messages_list:
                            # 将消息放入队列
                            self.message_queue.append({'chat_name': chat_name, 'message': new_msg})
            
            time.sleep(random.uniform(1.0, 3.0)) # 随机间隔轮询
模块2:消息处理器 (MessageProcessor)
class MessageProcessor:
    def __init__(self):
        pass # 初始化简单

    @ErrorHandler.handle_errors
    def process_message(self, raw_msg_data):
        # raw_msg_data = {'chat_name': chat_name, 'message': new_msg_object}
        raw_msg = raw_msg_data['message']
        chat_name = raw_msg_data['chat_name']

        # 使用getattr安全访问属性
        msg_type = getattr(raw_msg, 'type', 'unknown')
        sender = getattr(raw_msg, 'sender', 'Unknown')
        content = getattr(raw_msg, 'content', '')
        
        processed = {
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'sender': sender,
            'content': content,
            'type': self._detect_content_type(raw_msg), # 检测用于发送的类型
            'original_type': msg_type,
            'source_chat': chat_name
        }

        # 提取文件/图片/视频路径
        if processed['type'] in ['file', 'image', 'video']:
            processed['file_path'] = getattr(raw_msg, 'file', None)

        return processed

    def _detect_content_type(self, raw_msg):
        # 根据原始消息类型和内容判断转发类型 (text, link, image, file, video, emotion)
        # ... 实现细节 ...
        pass
模块3:消息发送器 (MessageSender)
class MessageSender:
    def __init__(self, receiver=RECEIVER, min_interval=MIN_INTERVAL):
        self.receiver = receiver
        self.min_interval = min_interval # 从配置加载
        global last_sent_time

    @ErrorHandler.handle_errors
    def safe_send(self, message):
        global last_sent_time
        # 检查发送间隔
        now = datetime.datetime.now()
        time_since_last_send = (now - last_sent_time).total_seconds()
        if time_since_last_send < self.min_interval:
            wait_time = self.min_interval - time_since_last_send
            time.sleep(wait_time)

        try:
            # 根据消息类型调用不同发送方法
            if message['type'] in ['text', 'link']:
                self._send_text(message)
            elif message['type'] == 'image':
                 self._send_image(message) # 使用 _send_image
            elif message['type'] == 'file':
                self._send_file(message) # 使用 _send_file
            elif message['type'] == 'video': # 新增视频处理
                 self._send_file(message) # 视频也用 SendFiles
            elif message['type'] == 'emotion':
                self._send_text(message, is_emotion=True)
            # ... 其他类型处理 ...

            last_sent_time = datetime.datetime.now()
            time.sleep(random.uniform(0.5, 1.5)) # 发送后随机暂停
        except Exception as e:
            logging.error(f"Failed to send message: {str(e)}")

    def _send_text(self, msg, is_emotion=False, is_fallback=False):
        # 格式化文本消息并发送
        formatted = f"[From: {msg.get('source_chat', 'Unknown')}] {msg.get('sender', 'Unknown')}:\n{msg.get('content', '')}"
        if is_emotion:
             formatted = f"[From: {msg.get('source_chat', 'Unknown')}] {msg.get('sender', 'Unknown')}:\n[表情: {msg.get('content', '')}]"
        elif is_fallback:
             formatted = f"[From: {msg.get('source_chat', 'Unknown')}] {msg.get('sender', 'Unknown')}:\n{msg.get('content', '[Content could not be forwarded]')}"
        wx.SendMsg(formatted, self.receiver) # 使用 SendMsg

    def _send_image(self, msg):
        # 发送图片文件
        file_path = msg.get('file_path')
        if file_path and os.path.exists(file_path):
            wx.SendFiles([file_path], self.receiver) # 使用 SendFiles
        else:
            self._send_text({'content': '[Image could not be forwarded]', **msg}, is_fallback=True)

    def _send_file(self, msg):
        # 发送普通文件或视频文件
        file_path = msg.get('file_path')
        if file_path and os.path.exists(file_path):
            wx.SendFiles([file_path], self.receiver) # 使用 SendFiles
        else:
            self._send_text({'content': '[File could not be forwarded]', **msg}, is_fallback=True)

2.3 调度器 (Scheduler)

class Scheduler:
    def __init__(self, queue, processor, sender):
        self.message_queue = queue
        self.processor = processor
        self.sender = sender
        self.running = False
        self._stop_event = threading.Event()

    def start(self):
        # 启动独立线程处理和发送消息
        self.thread = threading.Thread(target=self._run, daemon=True)
        self.thread.start()

    def _run(self):
        while not self._stop_event.is_set():
            if not self.message_queue:
                self._stop_event.wait(1.0) # 队列为空时等待
                continue

            raw_msg = self.message_queue.popleft()
            processed_msg = self.processor.process_message(raw_msg)
            if processed_msg:
                self.sender.safe_send(processed_msg)
            # 短暂休眠避免CPU空转 (实际代码在WindowMonitor轮询处休眠)

三、关键技术实现

3.1 消息类型处理与转发

消息类型 (原始)处理方式 (转发)发送方法 (wxauto_custom)
text拼接来源和发送者信息wx.SendMsg
link拼接来源和发送者信息 (同text)wx.SendMsg
image获取本地路径后发送文件wx.SendFiles
file获取本地路径后发送文件wx.SendFiles
video获取本地路径后发送文件wx.SendFiles
emotion发送 [表情: 内容] 文本wx.SendMsg
其他默认按文本处理或忽略wx.SendMsg (可能)

3.2 异常处理机制

class ErrorHandler:
    @staticmethod
    def handle_errors(func):
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            # 移除了对 wxauto 特定异常的处理 (WindowNotFoundException, MessageSendTimeout)
            # 因为它们在 wxauto_custom.errors 中可能不存在或已更改
            except Exception as e:
                # 使用 logging 记录未处理的通用异常
                logging.critical(f"Unhandled exception in {func.__name__}: {str(e)}", exc_info=True)
        return wrapper

四、部署与使用

4.1 环境要求

# 核心依赖 (请根据实际使用的 wxauto_custom 版本调整)
# pip install wxauto_custom # 假设库名为 wxauto_custom
# 或者如果直接修改了 wxauto 库,则安装原版
# pip install wxauto==<version_used_by_custom>

# 其他标准库 (通常随 Python 安装)
# configparser, logging, threading, collections, random, datetime, os, time

注意: wxauto 或其定制版通常对微信客户端版本有要求,请参考库文档确认兼容性。

4.2 配置文件示例 (config.ini)

[target]
receiver = 元宝
interval = 10
chats_to_monitor = 测试群1, HR

五、注意事项

  1. 微信版本限制:需使用官方客户端v3.7.6以下版本
  2. 窗口焦点要求:需保持微信窗口处于前台运行状态
  3. 防检测机制:轮询和发送后加入随机延时,模拟人类行为
  4. 性能优化:建议关闭无关聊天窗口降低资源占用

六、测试方案

测试用例矩阵

测试场景输入类型预期结果
群文本消息文字正确转发带来源信息
私聊图片JPEG成功发送图片文件
连续消息发送多条文本间隔不小于配置的 interval 值
微信窗口最小化-可能无法正常捕获 (依赖UI自动化)
网络中断-错误重试机制正常触发
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值