feat(sendmsg, README): 添加微信状态检查和发送结果验证功能
- 在sendmsg.py中实现微信状态检查,确保客户端就绪、已登录及接收者有效性。 - 增强消息和文件发送逻辑,添加发送结果验证,记录详细的发送状态信息。 - 更新README.md,详细描述新增功能和使用方法,包括微信状态检查和多格式图片支持。
This commit is contained in:
parent
08d302b22c
commit
6acdaea9f8
70
README.md
70
README.md
@ -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
|
||||||
|
- 基础消息发送功能
|
||||||
|
- 定时任务调度
|
||||||
|
- 飞书提醒机制
|
||||||
|
- 基础日志记录
|
||||||
|
|||||||
175
sendmsg.py
175
sendmsg.py
@ -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}")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user