156 lines
5.5 KiB
Python
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
|
|
|
|
|
|
# demo 类,不需要关注
|
|
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())
|