Files
abot/wechat_ipad/bot-core.py
2025-06-06 09:24:23 +08:00

156 lines
5.5 KiB
Python

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", 8059)
# 调用登录接口
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())