import asyncio import time import tomllib import toml import wechat_ipad # 明确导入需要的类 from loguru import logger from wechat_ipad.models.message import WxMessage async def bot_core(): # 读取 config.toml 文件 with open("config.toml", "rb") as f: config = tomllib.load(f) logger.info("启动bot") # 获取 server_url 内容 server_url = config.get("server_url", "") if server_url == "": raise ValueError("server_url 不能为空") server_ip = config.get("server_ip", "") server_port = config.get("server_port", 8058) # 调用登录接口 bot = wechat_ipad.WechatAPIClient(server_ip, server_port) wxid = config.get("wxid", "") device_name = config.get("device_name", "") device_id = config.get("device_id", "") if device_name == "": device_name = bot.create_device_name() if device_id == "": device_id = bot.create_device_id() if not await bot.is_logged_in(wxid): while not await bot.is_logged_in(wxid): # 需要登录 try: if await bot.get_cached_info(wxid): # 尝试唤醒登录 uuid = await bot.awaken_login(wxid) logger.info("获取到登录uuid: {}", uuid) else: # 二维码登录 if not device_name: device_name = bot.create_device_name() if not device_id: device_id = bot.create_device_id() uuid, url = await bot.get_qr_code(device_id=device_id, device_name=device_name, print_qr=True) logger.info("获取到登录uuid: {}", uuid) logger.info("获取到登录二维码: {}", url) except: # 二维码登录 if not device_name: device_name = bot.create_device_name() if not device_id: device_id = bot.create_device_id() uuid, url = await bot.get_qr_code(device_id=device_id, device_name=device_name, print_qr=True) logger.info("获取到登录uuid: {}", uuid) logger.info("获取到登录二维码: {}", url) while True: logger.info(f"uuid: {uuid}, url: {url}") stat, data = await bot.check_login_uuid(uuid, device_id=device_id) if stat: break logger.info("等待登录中,过期倒计时:{}", data) await asyncio.sleep(5) # 保存登录信息 config["wxid"] = bot.wxid config["device_name"] = device_name config["device_id"] = device_id with open("config.toml", "w", encoding="utf-8") as f: toml.dump(config, f) # 获取登录账号信息 bot.wxid = data.get("acctSectResp").get("userName") bot.nickname = data.get("acctSectResp").get("nickName") bot.alias = data.get("acctSectResp").get("alias") bot.phone = data.get("acctSectResp").get("bindMobile") logger.info("登录账号信息: wxid: {} 昵称: {} 微信号: {} 手机号: {}", bot.wxid, bot.nickname, bot.alias, bot.phone) break else: # 已登录 bot.wxid = wxid profile = await bot.get_profile() bot.nickname = profile.get("NickName").get("string") bot.alias = profile.get("Alias") bot.phone = profile.get("BindMobile").get("string") logger.info("登录账号信息: wxid: {} 昵称: {} 微信号: {} 手机号: {}", bot.wxid, bot.nickname, bot.alias, bot.phone) logger.info("登录设备信息: device_name: {} device_id: {}", device_name, device_id) logger.info("登录成功") # 开启自动心跳(作为后台任务) async def heartbeat_task(): logger.success("开启心跳!") while True: try: success = await bot.heartbeat() if not success: logger.warning("心跳失败") except Exception as e: logger.error("heartbeat:{}", e) await asyncio.sleep(5) # 创建心跳任务但不等待它完成 asyncio.create_task(heartbeat_task()) # noqa # 先接受堆积消息 logger.info("处理堆积消息中") count = 0 while True: data = await bot.sync_message() data = data.get("AddMsgs") if not data: if count > 2: break else: count += 1 continue logger.debug("接受到 {} 条消息", len(data)) await asyncio.sleep(1) logger.success("处理堆积消息完毕") logger.success("开始处理消息") while True: now = time.time() try: data = await bot.sync_message() except Exception as e: logger.warning("获取新消息失败 {}", e) await asyncio.sleep(5) continue data = data.get("AddMsgs") if data: for message in data: # 获取原始JSON数据 # 创建消息对象 msg = WxMessage.from_json(message) logger.info("source message: {}".format(message)) logger.info("parse msg: {}".format(msg)) # 使用异步睡眠替代忙等待循环 await asyncio.sleep(0.5) if __name__ == '__main__': asyncio.run(bot_core())