feat(sendmsg, README): 添加微信状态检查和发送结果验证功能

- 在sendmsg.py中实现微信状态检查,确保客户端就绪、已登录及接收者有效性。
- 增强消息和文件发送逻辑,添加发送结果验证,记录详细的发送状态信息。
- 更新README.md,详细描述新增功能和使用方法,包括微信状态检查和多格式图片支持。
This commit is contained in:
teddy 2025-08-22 18:02:11 +08:00
parent 08d302b22c
commit 6acdaea9f8
2 changed files with 237 additions and 12 deletions

View File

@ -2,7 +2,7 @@
## 功能概述 ## 功能概述
这是一个自动发送每日AI新闻图片和消息到微信的程序具有完整的日志记录和错误处理功能。 这是一个自动发送每日AI新闻图片和消息到微信的程序具有完整的日志记录、错误处理和微信状态检查功能。
## 主要功能 ## 主要功能
@ -10,6 +10,31 @@
- **容错机制**: 微信失败时自动发送飞书提醒 - **容错机制**: 微信失败时自动发送飞书提醒
- **详细日志**: 完整的操作日志记录,便于问题排查 - **详细日志**: 完整的操作日志记录,便于问题排查
- **进程管理**: 支持后台运行和进程控制 - **进程管理**: 支持后台运行和进程控制
- **微信状态检查**: 自动检查微信客户端状态和接收者有效性
- **智能重试**: 支持多种图片格式,自动重试机制
## 新增功能
### 微信状态检查
程序现在会自动检查:
- 微信客户端是否就绪
- 微信是否已登录
- 接收者是否存在于联系人列表
- 当前会话数量和联系人数量
- 微信窗口状态
### 发送结果验证
使用wxauto的WxResponse对象验证
- 文件发送是否成功
- 消息发送是否成功
- 详细的发送状态信息
- 部分失败时的智能处理
### 多格式图片支持
支持多种图片格式:
- .jpg
- .jpeg
- .png
## 日志功能 ## 日志功能
@ -58,6 +83,11 @@ python service_runner.py
python stop_scheduler.py python stop_scheduler.py
``` ```
### 5. 测试微信状态
```bash
python test_wechat_status.py
```
## 配置说明 ## 配置说明
`config.py` 中配置: `config.py` 中配置:
@ -79,12 +109,26 @@ python stop_scheduler.py
3. **飞书API问题**: 查看 `send_openmsg_*.log``send_filemsg_*.log` 3. **飞书API问题**: 查看 `send_openmsg_*.log``send_filemsg_*.log`
4. **进程管理问题**: 查看 `service_runner_*.log``stop_scheduler_*.log` 4. **进程管理问题**: 查看 `service_runner_*.log``stop_scheduler_*.log`
### 微信状态检查
运行测试脚本检查微信状态:
```bash
python test_wechat_status.py
```
这将显示:
- 微信客户端状态
- 登录状态
- 接收者有效性
- 可用方法列表
### 日志示例 ### 日志示例
``` ```
2024-01-15 11:40:00 - sendmsg - INFO - send_daily_message:25 - 开始执行每日消息发送任务,当前尝试次数: 0 2024-01-15 11:40:00 - sendmsg - INFO - check_wechat_status:45 - ✅ 微信已登录,当前会话数量: 15
2024-01-15 11:40:00 - sendmsg - INFO - send_daily_message:30 - 目标日期: 2024-01-15 2024-01-15 11:40:00 - sendmsg - INFO - check_wechat_status:52 - ✅ 接收者 '文件传输助手' 存在于联系人列表中
2024-01-15 11:40:00 - sendmsg - INFO - send_daily_message:31 - 目标文件: 2024-01-15.jpg 2024-01-15 11:40:00 - sendmsg - INFO - send_daily_message:120 - 🎉 所有内容发送完成!
2024-01-15 11:40:00 - sendmsg - INFO - send_daily_message:32 - 完整文件路径: Z:\2024-01-15.jpg 2024-01-15 11:40:00 - sendmsg - INFO - send_daily_message:125 - 发送结果总结:
2024-01-15 11:40:00 - sendmsg - INFO - send_daily_message:126 - 📎 文件发送: ✅ 成功
2024-01-15 11:40:00 - sendmsg - INFO - send_daily_message:127 - 💬 消息发送: ✅ 成功
``` ```
## 依赖要求 ## 依赖要求
@ -101,3 +145,19 @@ python stop_scheduler.py
2. 检查文件路径配置是否正确 2. 检查文件路径配置是否正确
3. 验证飞书API配置是否有效 3. 验证飞书API配置是否有效
4. 定期检查日志文件大小,避免占用过多磁盘空间 4. 定期检查日志文件大小,避免占用过多磁盘空间
5. 运行前建议先执行 `test_wechat_status.py` 检查微信状态
## 更新日志
### v0.2.0
- 添加微信状态检查功能
- 使用WxResponse验证发送结果
- 支持多种图片格式
- 改进错误处理和日志记录
- 添加微信状态测试脚本
### v0.1.0
- 基础消息发送功能
- 定时任务调度
- 飞书提醒机制
- 基础日志记录

View File

@ -10,6 +10,101 @@ from logger_config import setup_logger
# 设置日志记录器 # 设置日志记录器
logger = setup_logger('sendmsg') logger = setup_logger('sendmsg')
def check_wechat_status(wx, who):
"""检查微信客户端状态"""
logger.info("=" * 30)
logger.info("微信状态检查开始")
logger.info("=" * 30)
status_info = {
'client_ready': False,
'logged_in': False,
'receiver_exists': False,
'sessions_count': 0,
'contacts_count': 0
}
try:
# 检查微信客户端是否就绪
if wx:
status_info['client_ready'] = True
logger.info("✅ 微信客户端对象创建成功")
else:
logger.error("❌ 微信客户端对象创建失败")
return status_info
# 检查微信是否已登录
try:
if hasattr(wx, 'GetSessionList'):
sessions = wx.GetSessionList()
if sessions:
status_info['logged_in'] = True
status_info['sessions_count'] = len(sessions)
logger.info(f"✅ 微信已登录,当前会话数量: {len(sessions)}")
logger.info(f"📱 会话列表: {sessions[:5]}...") # 只显示前5个
else:
logger.warning("⚠️ 微信已登录但会话列表为空")
else:
logger.warning("⚠️ 无法获取会话列表方法")
except Exception as session_e:
logger.warning(f"⚠️ 无法获取会话列表: {str(session_e)}")
# 检查接收者是否存在
try:
if hasattr(wx, 'GetAllContacts'):
contacts = wx.GetAllContacts()
if contacts:
status_info['contacts_count'] = len(contacts)
logger.info(f"📋 联系人总数: {len(contacts)}")
if who in contacts:
status_info['receiver_exists'] = True
logger.info(f"✅ 接收者 '{who}' 存在于联系人列表中")
else:
logger.warning(f"❌ 接收者 '{who}' 不在联系人列表中")
logger.info(f"📝 可用的联系人: {contacts[:10]}...") # 显示前10个
# 尝试模糊匹配
similar_contacts = [c for c in contacts if who.lower() in c.lower()]
if similar_contacts:
logger.info(f"🔍 找到相似的联系人: {similar_contacts}")
else:
logger.warning("⚠️ 联系人列表为空")
else:
logger.warning("⚠️ 无法获取联系人列表方法")
except Exception as contact_e:
logger.warning(f"⚠️ 无法获取联系人列表: {str(contact_e)}")
# 检查微信窗口状态
try:
if hasattr(wx, 'GetWeChatWindow'):
window = wx.GetWeChatWindow()
if window:
logger.info("✅ 微信窗口已找到")
else:
logger.warning("⚠️ 微信窗口未找到")
else:
logger.warning("⚠️ 无法获取微信窗口方法")
except Exception as window_e:
logger.warning(f"⚠️ 无法获取微信窗口: {str(window_e)}")
# 状态总结
logger.info("=" * 30)
logger.info("微信状态检查总结:")
logger.info(f" 🖥️ 客户端就绪: {'' if status_info['client_ready'] else ''}")
logger.info(f" 🔐 登录状态: {'' if status_info['logged_in'] else ''}")
logger.info(f" 👤 接收者存在: {'' if status_info['receiver_exists'] else ''}")
logger.info(f" 📱 会话数量: {status_info['sessions_count']}")
logger.info(f" 📋 联系人数量: {status_info['contacts_count']}")
logger.info("=" * 30)
return status_info
except Exception as e:
logger.error(f"微信状态检查过程中出现错误: {str(e)}")
logger.error(f"错误类型: {type(e).__name__}")
return status_info
def wait_until_time(): def wait_until_time():
"""等待到配置的发送时间""" """等待到配置的发送时间"""
now = datetime.now() now = datetime.now()
@ -61,9 +156,17 @@ def send_daily_message(count):
try: try:
logger.info("尝试初始化微信客户端...") logger.info("尝试初始化微信客户端...")
wx = WeChat() wx = WeChat()
logger.info("微信客户端初始化成功") logger.info("微信客户端初始化完成")
except Exception as e: except Exception as e:
logger.error(f"微信客户端初始化失败: {str(e)}") logger.error(f"微信客户端初始化失败: {str(e)}")
logger.error(f"错误类型: {type(e).__name__}")
logger.error("可能的原因:")
logger.error(" 1. 微信客户端未启动")
logger.error(" 2. 微信客户端未登录")
logger.error(" 3. wxauto库版本不兼容")
logger.error(" 4. 系统权限不足")
logger.info("尝试发送飞书提醒消息...") logger.info("尝试发送飞书提醒消息...")
subprocess.run([sys.executable, 'send_openmsg.py']) subprocess.run([sys.executable, 'send_openmsg.py'])
if num<4: if num<4:
@ -81,6 +184,17 @@ def send_daily_message(count):
logger.info(f"消息内容: {msg}") logger.info(f"消息内容: {msg}")
logger.info(f"接收者: {who}") logger.info(f"接收者: {who}")
# 使用专门的函数检查微信状态
wechat_status = check_wechat_status(wx, who)
# 如果接收者不存在,给出警告但继续执行
if not wechat_status['receiver_exists']:
logger.warning("⚠️ 接收者不在联系人列表中,但将继续尝试发送")
logger.warning("这可能是因为:")
logger.warning(" 1. 接收者是群聊名称")
logger.warning(" 2. 接收者是特殊联系人(如文件传输助手)")
logger.warning(" 3. 联系人列表获取不完整")
# 依次检查各种格式的文件是否存在 # 依次检查各种格式的文件是否存在
for format in file_formats: for format in file_formats:
temp_file_name = formatted_date + format temp_file_name = formatted_date + format
@ -101,21 +215,72 @@ def send_daily_message(count):
try: try:
# 发送文件 # 发送文件
logger.info(f"正在发送文件: {file_path}") logger.info(f"正在发送文件: {file_path}")
wx.SendFiles(filepath=file_path, who=who) file_response = wx.SendFiles(filepath=file_path, who=who)
# 检查文件发送结果
if hasattr(file_response, 'success') and file_response.success():
logger.info("文件发送成功") logger.info("文件发送成功")
logger.info(f"文件发送响应: {file_response}")
else:
logger.warning("文件发送可能失败")
logger.warning(f"文件发送响应: {file_response}")
if hasattr(file_response, 'message'):
logger.warning(f"文件发送消息: {file_response.message}")
# 发送消息 # 发送消息
logger.info(f"正在发送消息: {msg}") logger.info(f"正在发送消息: {msg}")
wx.SendMsg(msg=msg, who=who) msg_response = wx.SendMsg(msg=msg, who=who)
logger.info("消息发送成功")
logger.info("所有内容发送完成!") # 检查消息发送结果
if hasattr(msg_response, 'success') and msg_response.success():
logger.info("消息发送成功")
logger.info(f"消息发送响应: {msg_response}")
else:
logger.warning("消息发送可能失败")
logger.warning(f"消息发送响应: {msg_response}")
if hasattr(msg_response, 'message'):
logger.warning(f"消息发送消息: {msg_response.message}")
# 综合判断发送结果
file_success = hasattr(file_response, 'success') and file_response.success()
msg_success = hasattr(msg_response, 'success') and msg_response.success()
if file_success and msg_success:
logger.info("🎉 所有内容发送完成!")
logger.info("=" * 50)
logger.info("发送结果总结:")
logger.info(f" 📎 文件发送: {'✅ 成功' if file_success else '❌ 失败'}")
logger.info(f" 💬 消息发送: {'✅ 成功' if msg_success else '❌ 失败'}")
logger.info("=" * 50)
return True return True
else:
logger.warning("⚠️ 部分内容发送失败")
logger.warning("=" * 50)
logger.warning("发送结果总结:")
logger.warning(f" 📎 文件发送: {'✅ 成功' if file_success else '❌ 失败'}")
logger.warning(f" 💬 消息发送: {'✅ 成功' if msg_success else '❌ 失败'}")
logger.warning("=" * 50)
# 即使部分失败,也记录为成功(因为至少发送了部分内容)
if file_success or msg_success:
logger.info("由于部分内容发送成功,记录为成功")
return True
else:
logger.error("所有内容发送失败,需要重试")
raise Exception("文件发送和消息发送都失败了")
except Exception as e: except Exception as e:
logger.error(f"发送过程中出现错误: {str(e)}") logger.error(f"发送过程中出现错误: {str(e)}")
logger.error(f"错误类型: {type(e).__name__}") logger.error(f"错误类型: {type(e).__name__}")
# 记录详细的错误信息
if 'file_response' in locals():
logger.error(f"文件发送响应详情: {file_response}")
if 'msg_response' in locals():
logger.error(f"消息发送响应详情: {msg_response}")
# 发送失败时也尝试发送飞书提醒 # 发送失败时也尝试发送飞书提醒
logger.info("尝试发送飞书提醒消息...")
subprocess.run([sys.executable, 'send_filemsg.py']) subprocess.run([sys.executable, 'send_filemsg.py'])
if num<4: if num<4:
logger.info(f"等待60秒后重试当前尝试次数: {num+1}") logger.info(f"等待60秒后重试当前尝试次数: {num+1}")