uy/sun bec252c48c
多机器人支持 (#179)
* 维护一个群号和QQ号与机器人实例的表

* 随机获取一个对应的机器人

* 获取所有机器人所在群的并集

* 监听到相关事件的时候刷新整个缓存

* 在发送错误后自动刷新缓存

* 合并相同类型的函数

* 添加测试
2023-01-31 21:04:00 +08:00

115 lines
3.7 KiB
Python

import time
from typing import Literal, Union
from nonebot.adapters.onebot.v11.bot import Bot
from nonebot.adapters.onebot.v11.exception import ActionFailed
from nonebot.adapters.onebot.v11.message import Message
from nonebot.log import logger
from .plugin_config import plugin_config
from .utils.get_bot import refresh_bots
QUEUE: list[
tuple[
Bot,
int,
Literal["private", "group", "group-forward"],
Union[str, Message],
int,
]
] = []
LAST_SEND_TIME = time.time()
async def _do_send(
bot: "Bot",
user: int,
user_type: Literal["group", "private", "group-forward"],
msg: Union[str, Message],
):
try:
if user_type == "group":
await bot.send_group_msg(group_id=user, message=msg)
elif user_type == "private":
await bot.send_private_msg(user_id=user, message=msg)
elif user_type == "group-forward":
await bot.send_group_forward_msg(group_id=user, messages=msg)
except ActionFailed:
await refresh_bots()
logger.warning(f"send msg failed, refresh bots")
async def do_send_msgs():
global LAST_SEND_TIME
if time.time() - LAST_SEND_TIME < 1.5:
return
if QUEUE:
bot, user, user_type, msg, retry_time = QUEUE.pop(0)
try:
await _do_send(bot, user, user_type, msg)
except Exception as e:
if retry_time > 0:
QUEUE.insert(0, (bot, user, user_type, msg, retry_time - 1))
else:
msg_str = str(msg)
if len(msg_str) > 50:
msg_str = msg_str[:50] + "..."
logger.warning(f"send msg err {e} {msg_str}")
LAST_SEND_TIME = time.time()
async def _send_msgs_dispatch(
bot: Bot,
user,
user_type: Literal["private", "group", "group-forward"],
msg: Union[str, Message],
):
if plugin_config.bison_use_queue:
QUEUE.append((bot, user, user_type, msg, plugin_config.bison_resend_times))
else:
await _do_send(bot, user, user_type, msg)
async def send_msgs(
bot: Bot, user, user_type: Literal["private", "group"], msgs: list[Message]
):
if not plugin_config.bison_use_pic_merge or user_type == "private":
for msg in msgs:
await _send_msgs_dispatch(bot, user, user_type, msg)
return
msgs = msgs.copy()
if plugin_config.bison_use_pic_merge == 1:
await _send_msgs_dispatch(bot, user, "group", msgs.pop(0))
if msgs:
if len(msgs) == 1: # 只有一条消息序列就不合并转发
await _send_msgs_dispatch(bot, user, "group", msgs.pop(0))
else:
group_bot_info = await bot.get_group_member_info(
group_id=user, user_id=int(bot.self_id), no_cache=True
) # 调用api获取群内bot的相关参数
# forward_msg = Message(
# [
# MessageSegment.node_custom(
# group_bot_info["user_id"],
# nickname=group_bot_info["card"] or group_bot_info["nickname"],
# content=msg,
# )
# for msg in msgs
# ]
# )
# FIXME: Because of https://github.com/nonebot/adapter-onebot/issues/9
forward_msg = [
{
"type": "node",
"data": {
"name": group_bot_info["card"] or group_bot_info["nickname"],
"uin": group_bot_info["user_id"],
"content": msg,
},
}
for msg in msgs
]
await _send_msgs_dispatch(bot, user, "group-forward", forward_msg)