from wxauto import WeChat from datetime import date, datetime, time as dt_time import sys import os import subprocess from config import CONFIG import time from logger_config import setup_logger # 设置日志记录器 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(): """等待到配置的发送时间""" now = datetime.now() # 从配置文件中读取发送时间 send_time_str = CONFIG['sending_time'] # "17:10" hour, minute = map(int, send_time_str.split(':')) target_time = now.replace(hour=hour, minute=minute, second=0, microsecond=0) # 如果当前时间已经过了今天的发送时间,则设置为明天的发送时间 if now >= target_time: target_time = target_time.replace(day=target_time.day + 1) wait_seconds = (target_time - now).total_seconds() logger.info(f"当前时间: {now.strftime('%Y-%m-%d %H:%M:%S')}") logger.info(f"目标发送时间: {target_time.strftime('%Y-%m-%d %H:%M:%S')}") logger.info(f"等待时间: {wait_seconds/3600:.2f} 小时 ({wait_seconds:.0f} 秒)") time.sleep(wait_seconds) logger.info("等待完成,开始执行发送操作") def send_daily_message(count): """发送每日消息的主函数""" logger.info(f"开始执行每日消息发送任务,当前尝试次数: {count}") today = date.today() formatted_date = today.strftime('%Y-%m-%d') # 支持多种图片格式:jpg, jpeg, png file_formats = [".jpg", ".jpeg", ".png"] # 初始化文件路径变量 file_path = None file_name = formatted_date + ".jpg" file_path = CONFIG['file_path'] + file_name logger.info(f"目标日期: {formatted_date}") logger.info(f"目标文件: {file_name}") logger.info(f"完整文件路径: {file_path}") num = count if num >= 4: logger.error("已尝试4次,程序将退出") sys.exit(0) # 直接终止程序 try: logger.info("尝试初始化微信客户端...") wx = WeChat() logger.info("微信客户端初始化完成") except Exception as 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("尝试发送飞书提醒消息...") subprocess.run([sys.executable, 'send_openmsg.py']) if num<4: logger.info(f"等待60秒后重试,当前尝试次数: {num+1}") time.sleep(60) num += 1 send_daily_message(num) else: logger.error("已尝试4次,程序将退出") sys.exit(0) # 直接终止程序 msg = CONFIG['message'] who = CONFIG['messages_reciever'] logger.info(f"消息内容: {msg}") 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: temp_file_name = formatted_date + format temp_file_path = CONFIG['file_path'] + temp_file_name if os.path.isfile(temp_file_path): file_path = temp_file_path print(f"找到了{format}格式的图片文件!") break if file_path and os.path.isfile(file_path): logger.info("找到了指定文件!") logger.info(f"文件大小: {os.path.getsize(file_path)} 字节") # 等待到配置的时间再执行发送操作 wait_until_time() logger.info("开始发送文件和消息...") try: # 发送文件 logger.info(f"正在发送文件: {file_path}") file_response = wx.SendFiles(filepath=file_path, who=who) # 检查文件发送结果 if hasattr(file_response, 'success') and file_response.success(): 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}") msg_response = wx.SendMsg(msg=msg, who=who) # 检查消息发送结果 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 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: logger.error(f"发送过程中出现错误: {str(e)}") 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']) if num<4: logger.info(f"等待60秒后重试,当前尝试次数: {num+1}") time.sleep(60) num += 1 send_daily_message(num) else: logger.error("已尝试4次,程序将退出") sys.exit(0) else: print("没找到任何支持格式的图片文件(.jpg, .jpeg, .png)") logger.warning(f"没找到指定文件: {file_path}") logger.info("尝试发送飞书提醒消息...") subprocess.run([sys.executable, 'send_filemsg.py']) if num<4: time.sleep(1800) logger.info(f"等待60秒后重试,当前尝试次数: {num+1}") time.sleep(60) num += 1 send_daily_message(num) else: logger.error("已尝试4次,程序将退出") sys.exit(0) # 直接终止程序 # 如果直接运行此脚本,执行发送消息功能 if __name__ == "__main__": logger.info("=" * 50) logger.info("开始执行微信消息发送程序") logger.info("=" * 50) count = 0 try: send_daily_message(count) logger.info("程序执行完成") except Exception as e: logger.error(f"程序执行过程中出现未捕获的异常: {str(e)}") logger.error(f"异常类型: {type(e).__name__}") import traceback logger.error(f"异常堆栈: {traceback.format_exc()}") sys.exit(1)