mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +08:00
perf👌: 广播与全局插件/被动管理
This commit is contained in:
parent
88bda9ce2c
commit
a2d6c7f951
@ -1,6 +1,6 @@
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot_plugin_alconna import Arparma, Match
|
||||
from nonebot_plugin_alconna import AlconnaQuery, Arparma, Match, Query
|
||||
from nonebot_plugin_saa import Image, Text
|
||||
from nonebot_plugin_session import EventSession
|
||||
|
||||
@ -21,14 +21,16 @@ __plugin_meta__ = PluginMetadata(
|
||||
usage="""
|
||||
普通管理员
|
||||
格式:
|
||||
开启/关闭[功能名称] : 开关功能
|
||||
群被动状态 : 查看被动技能开关状态
|
||||
醒来 : 结束休眠
|
||||
休息吧 : 群组休眠, 不会再响应命令
|
||||
开启/关闭[功能名称] : 开关功能
|
||||
开启/关闭群被动[被动名称] : 群被动开关
|
||||
群被动状态 : 查看被动技能开关状态
|
||||
醒来 : 结束休眠
|
||||
休息吧 : 群组休眠, 不会再响应命令
|
||||
|
||||
示例:
|
||||
开启签到 : 开启签到
|
||||
关闭签到 : 关闭签到
|
||||
开启群被动早晚安 : 关闭被动任务早晚安
|
||||
|
||||
超级管理员额外命令
|
||||
格式:
|
||||
@ -61,26 +63,21 @@ __plugin_meta__ = PluginMetadata(
|
||||
|
||||
|
||||
@_status_matcher.assign("$main")
|
||||
async def _(bot: Bot, session: EventSession, arparma: Arparma):
|
||||
async def _(
|
||||
bot: Bot,
|
||||
session: EventSession,
|
||||
arparma: Arparma,
|
||||
task: Query[bool] = AlconnaQuery("task.value", False),
|
||||
):
|
||||
image = None
|
||||
if session.id1 in bot.config.superusers:
|
||||
if task.result:
|
||||
image = await build_task(session.id3 or session.id2)
|
||||
elif session.id1 in bot.config.superusers:
|
||||
image = await build_plugin()
|
||||
if image:
|
||||
await Image(image.pic2bytes()).send(reply=True)
|
||||
logger.info(
|
||||
f"查看功能列表",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
)
|
||||
|
||||
|
||||
@_status_matcher.assign("task")
|
||||
async def _(bot: Bot, session: EventSession, arparma: Arparma):
|
||||
image = None
|
||||
if image := await build_task(session.id3 or session.id2):
|
||||
await Image(image.pic2bytes()).send(reply=True)
|
||||
logger.info(
|
||||
f"查看被动列表",
|
||||
f"查看{'功能' if arparma.find('task') else '被动'}列表",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
)
|
||||
@ -93,21 +90,35 @@ async def _(
|
||||
arparma: Arparma,
|
||||
name: str,
|
||||
group: Match[str],
|
||||
task: Query[bool] = AlconnaQuery("task.value", False),
|
||||
):
|
||||
if gid := session.id3 or session.id2:
|
||||
result = await PluginManage.block_group_plugin(name, gid)
|
||||
if task.result:
|
||||
result = await PluginManage.unblock_group_task(name, gid)
|
||||
else:
|
||||
result = await PluginManage.block_group_plugin(name, gid)
|
||||
await Text(result).send(reply=True)
|
||||
logger.info(f"开启功能 {name}", arparma.header_result, session=session)
|
||||
elif session.id1 in bot.config.superusers:
|
||||
group_id = group.result if group.available else None
|
||||
result = await PluginManage.superuser_block(name, None, group_id)
|
||||
await Text(result).send(reply=True)
|
||||
logger.info(
|
||||
f"超级用户开启功能 {name}",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
target=group_id,
|
||||
)
|
||||
if task.result:
|
||||
result = await PluginManage.superuser_task_handle(name, group_id, True)
|
||||
await Text(result).send(reply=True)
|
||||
logger.info(
|
||||
f"超级用户开启被动技能 {name}",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
target=group_id,
|
||||
)
|
||||
else:
|
||||
result = await PluginManage.superuser_block(name, None, group_id)
|
||||
await Text(result).send(reply=True)
|
||||
logger.info(
|
||||
f"超级用户开启功能 {name}",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
target=group_id,
|
||||
)
|
||||
|
||||
|
||||
@_status_matcher.assign("close")
|
||||
@ -118,27 +129,41 @@ async def _(
|
||||
name: str,
|
||||
block_type: Match[str],
|
||||
group: Match[str],
|
||||
task: Query[bool] = AlconnaQuery("task.value", False),
|
||||
):
|
||||
if gid := session.id3 or session.id2:
|
||||
result = await PluginManage.unblock_group_plugin(name, gid)
|
||||
if task.result:
|
||||
result = await PluginManage.block_group_task(name, gid)
|
||||
else:
|
||||
result = await PluginManage.unblock_group_plugin(name, gid)
|
||||
await Text(result).send(reply=True)
|
||||
logger.info(f"关闭功能 {name}", arparma.header_result, session=session)
|
||||
elif session.id1 in bot.config.superusers:
|
||||
group_id = group.result if group.available else None
|
||||
_type = BlockType.ALL
|
||||
if block_type.available:
|
||||
if block_type.result in ["p", "private"]:
|
||||
_type = BlockType.PRIVATE
|
||||
elif block_type.result in ["g", "group"]:
|
||||
_type = BlockType.GROUP
|
||||
result = await PluginManage.superuser_block(name, _type, group_id)
|
||||
await Text(result).send(reply=True)
|
||||
logger.info(
|
||||
f"超级用户关闭功能 {name}, 禁用类型: {_type}",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
target=group_id,
|
||||
)
|
||||
if task.result:
|
||||
result = await PluginManage.superuser_task_handle(name, group_id, False)
|
||||
await Text(result).send(reply=True)
|
||||
logger.info(
|
||||
f"超级用户关闭被动技能 {name}",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
target=group_id,
|
||||
)
|
||||
else:
|
||||
_type = BlockType.ALL
|
||||
if block_type.available:
|
||||
if block_type.result in ["p", "private"]:
|
||||
_type = BlockType.PRIVATE
|
||||
elif block_type.result in ["g", "group"]:
|
||||
_type = BlockType.GROUP
|
||||
result = await PluginManage.superuser_block(name, _type, group_id)
|
||||
await Text(result).send(reply=True)
|
||||
logger.info(
|
||||
f"超级用户关闭功能 {name}, 禁用类型: {_type}",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
target=group_id,
|
||||
)
|
||||
|
||||
|
||||
@_group_status_matcher.handle()
|
||||
|
||||
@ -104,7 +104,9 @@ async def build_task(group_id: str | None) -> BuildImage:
|
||||
column_name = ["ID", "模块", "名称", "群组状态", "全局状态", "运行时间"]
|
||||
group = None
|
||||
if group_id:
|
||||
group = await GroupConsole.get_or_none(group_id=group_id)
|
||||
group = await GroupConsole.get_or_none(
|
||||
group_id=group_id, channel_id__isnull=True
|
||||
)
|
||||
if not group:
|
||||
raise GroupInfoNotFound()
|
||||
else:
|
||||
@ -145,17 +147,23 @@ class PluginManage:
|
||||
|
||||
@classmethod
|
||||
async def is_wake(cls, group_id: str) -> bool:
|
||||
if c := await GroupConsole.get_or_none(group_id=group_id):
|
||||
if c := await GroupConsole.get_or_none(
|
||||
group_id=group_id, channel_id__isnull=True
|
||||
):
|
||||
return c.status
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def sleep(cls, group_id: str):
|
||||
await GroupConsole.filter(group_id=group_id).update(status=False)
|
||||
await GroupConsole.filter(group_id=group_id, channel_id__isnull=True).update(
|
||||
status=False
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def wake(cls, group_id: str):
|
||||
await GroupConsole.filter(group_id=group_id).update(status=True)
|
||||
await GroupConsole.filter(group_id=group_id, channel_id__isnull=True).update(
|
||||
status=True
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def block(cls, module: str):
|
||||
@ -178,6 +186,32 @@ class PluginManage:
|
||||
"""
|
||||
return await cls._change_group_plugin(plugin_name, group_id, True)
|
||||
|
||||
@classmethod
|
||||
async def unblock_group_task(cls, task_name: str, group_id: str) -> str:
|
||||
"""启用被动技能
|
||||
|
||||
参数:
|
||||
task_name: 被动技能名称
|
||||
group_id: 群组id
|
||||
|
||||
返回:
|
||||
str: 返回信息
|
||||
"""
|
||||
return await cls._change_group_task(task_name, group_id, False)
|
||||
|
||||
@classmethod
|
||||
async def block_group_task(cls, task_name: str, group_id: str) -> str:
|
||||
"""禁用被动技能
|
||||
|
||||
参数:
|
||||
task_name: 被动技能名称
|
||||
group_id: 群组id
|
||||
|
||||
返回:
|
||||
str: 返回信息
|
||||
"""
|
||||
return await cls._change_group_task(task_name, group_id, True)
|
||||
|
||||
@classmethod
|
||||
async def unblock_group_plugin(cls, plugin_name: str, group_id: str) -> str:
|
||||
"""启用群组插件
|
||||
@ -191,6 +225,33 @@ class PluginManage:
|
||||
"""
|
||||
return await cls._change_group_plugin(plugin_name, group_id, False)
|
||||
|
||||
@classmethod
|
||||
async def _change_group_task(
|
||||
cls, task_name: str, group_id: str, status: bool
|
||||
) -> str:
|
||||
"""改变群组被动技能状态
|
||||
|
||||
参数:
|
||||
task_name: 被动技能名称
|
||||
group_id: 群组Id
|
||||
status: 状态
|
||||
|
||||
返回:
|
||||
str: 返回信息
|
||||
"""
|
||||
if task := await TaskInfo.get_or_none(name=task_name):
|
||||
status_str = "关闭" if status else "开启"
|
||||
group, _ = await GroupConsole.get_or_create(
|
||||
group_id=group_id, channel_id__isnull=True
|
||||
)
|
||||
if status:
|
||||
group.block_task += f"{task.module},"
|
||||
else:
|
||||
group.block_task = group.block_task.replace(f"{task.module},", "")
|
||||
await group.save(update_fields=["block_task"])
|
||||
return f"已成功{status_str} {task_name} 被动技能!"
|
||||
return "没有找到这个被动技能喔..."
|
||||
|
||||
@classmethod
|
||||
async def _change_group_plugin(
|
||||
cls, plugin_name: str, group_id: str, status: bool
|
||||
@ -212,7 +273,9 @@ class PluginManage:
|
||||
plugin = await PluginInfo.get_or_none(name=plugin_name)
|
||||
status_str = "开启" if status else "关闭"
|
||||
if plugin:
|
||||
group, _ = await GroupConsole.get_or_create(group_id=group_id)
|
||||
group, _ = await GroupConsole.get_or_create(
|
||||
group_id=group_id, channel_id__isnull=True
|
||||
)
|
||||
if status:
|
||||
if plugin.module in group.block_plugin:
|
||||
group.block_plugin = group.block_plugin.replace(
|
||||
@ -228,11 +291,44 @@ class PluginManage:
|
||||
return f"该功能已经{status_str}了喔,不要重复{status_str}..."
|
||||
return "没有找到这个功能喔..."
|
||||
|
||||
@classmethod
|
||||
async def superuser_task_handle(
|
||||
cls, task_name: str, group_id: str | None, status: bool
|
||||
) -> str:
|
||||
"""超级用户禁用被动技能
|
||||
|
||||
参数:
|
||||
task_name: 被动技能名称
|
||||
group_id: 群组id
|
||||
status: 状态
|
||||
|
||||
返回:
|
||||
str: 返回信息
|
||||
"""
|
||||
if task := await TaskInfo.get_or_none(name=task_name):
|
||||
status_str = "开启" if status else "关闭"
|
||||
if group_id:
|
||||
group, _ = await GroupConsole.get_or_create(
|
||||
group_id=group_id, channel_id__isnull=True
|
||||
)
|
||||
if status:
|
||||
group.block_task = group.block_task.replace(
|
||||
f"super:{task.module},", ""
|
||||
)
|
||||
else:
|
||||
group.block_task += f"super:{task.module},"
|
||||
await group.save(update_fields=["block_task"])
|
||||
else:
|
||||
task.status = status
|
||||
await task.save(update_fields=["status"])
|
||||
return f"已成功将被动技能 {task_name} 全局{status_str}!"
|
||||
return "没有找到这个功能喔..."
|
||||
|
||||
@classmethod
|
||||
async def superuser_block(
|
||||
cls, plugin_name: str, block_type: BlockType | None, group_id: str | None
|
||||
) -> str:
|
||||
"""超级用户禁用
|
||||
"""超级用户禁用插件
|
||||
|
||||
参数:
|
||||
plugin_name: 插件名称
|
||||
@ -248,7 +344,9 @@ class PluginManage:
|
||||
plugin = await PluginInfo.get_or_none(name=plugin_name)
|
||||
if plugin:
|
||||
if group_id:
|
||||
if group := await GroupConsole.get_or_none(group_id=group_id):
|
||||
if group := await GroupConsole.get_or_none(
|
||||
group_id=group_id, channel_id__isnull=True
|
||||
):
|
||||
if f"super:{plugin.module}," not in group.block_plugin:
|
||||
group.block_plugin += f"super:{plugin.module},"
|
||||
await group.save(update_fields=["block_plugin"])
|
||||
|
||||
@ -63,6 +63,15 @@ _status_matcher.shortcut(
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
_status_matcher.shortcut(
|
||||
r"开启群被动(?P<name>.+)",
|
||||
command="switch",
|
||||
arguments=["open", "{name}", "--task"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
_status_matcher.shortcut(
|
||||
r"开启(?P<name>.+)",
|
||||
command="switch",
|
||||
@ -70,6 +79,13 @@ _status_matcher.shortcut(
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
_status_matcher.shortcut(
|
||||
r"关闭群被动(?P<name>.+)",
|
||||
command="switch",
|
||||
arguments=["close", "{name}", "--task"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
_status_matcher.shortcut(
|
||||
r"关闭(?P<name>.+)",
|
||||
command="switch",
|
||||
@ -77,6 +93,7 @@ _status_matcher.shortcut(
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
_group_status_matcher.shortcut(
|
||||
r"醒来",
|
||||
command="group-status",
|
||||
|
||||
@ -1,28 +1,75 @@
|
||||
import nonebot
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot_plugin_apscheduler import scheduler
|
||||
from nonebot_plugin_saa import Image
|
||||
|
||||
# TODO: 消息发送
|
||||
from zhenxun.configs.config import NICKNAME
|
||||
from zhenxun.configs.path_config import IMAGE_PATH
|
||||
from zhenxun.configs.utils import PluginExtraData, Task
|
||||
from zhenxun.models.group_console import GroupConsole
|
||||
from zhenxun.models.task_info import TaskInfo
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.enum import PluginType
|
||||
from zhenxun.utils.platform import broadcast_group
|
||||
|
||||
# # 早上好
|
||||
# @scheduler.scheduled_job(
|
||||
# "cron",
|
||||
# hour=6,
|
||||
# minute=1,
|
||||
# )
|
||||
# async def _():
|
||||
# img = image(IMAGE_PATH / "zhenxun" / "zao.jpg")
|
||||
# await broadcast_group("[[_task|zwa]]早上好" + img, log_cmd="被动早晚安")
|
||||
# logger.info("每日早安发送...")
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name="早晚安被动技能",
|
||||
description="早晚安被动技能",
|
||||
usage="",
|
||||
extra=PluginExtraData(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.HIDDEN,
|
||||
tasks=[
|
||||
Task(module="group_welcome", name="进群欢迎"),
|
||||
Task(module="refund_group_remind", name="退群提醒"),
|
||||
],
|
||||
).dict(),
|
||||
)
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
|
||||
@driver.on_startup
|
||||
async def _():
|
||||
if not await TaskInfo.exists(module="morning_goodnight"):
|
||||
await TaskInfo.create(
|
||||
module="morning_goodnight",
|
||||
name="早晚安",
|
||||
status=True,
|
||||
)
|
||||
|
||||
|
||||
async def check(group_id: str, channel_id: str | None) -> bool:
|
||||
task = await TaskInfo.get_or_none(module="morning_goodnight")
|
||||
if not task or not task.status:
|
||||
return False
|
||||
return await GroupConsole.is_block_task(group_id, "morning_goodnight")
|
||||
|
||||
|
||||
# 早上好
|
||||
@scheduler.scheduled_job(
|
||||
"cron",
|
||||
hour=6,
|
||||
minute=1,
|
||||
)
|
||||
async def _():
|
||||
img = Image(IMAGE_PATH / "zhenxun" / "zao.jpg")
|
||||
await broadcast_group("早上好" + img, log_cmd="被动早晚安", check_func=check)
|
||||
logger.info("每日早安发送...")
|
||||
|
||||
|
||||
# # 睡觉了
|
||||
# @scheduler.scheduled_job(
|
||||
# "cron",
|
||||
# hour=23,
|
||||
# minute=59,
|
||||
# )
|
||||
# async def _():
|
||||
# img = image(IMAGE_PATH / "zhenxun" / "sleep.jpg")
|
||||
# await broadcast_group(
|
||||
# f"[[_task|zwa]]{NICKNAME}要睡觉了,你们也要早点睡呀" + img, log_cmd="被动早晚安"
|
||||
# )
|
||||
# logger.info("每日晚安发送...")
|
||||
@scheduler.scheduled_job(
|
||||
"cron",
|
||||
hour=23,
|
||||
minute=59,
|
||||
)
|
||||
async def _():
|
||||
img = Image(IMAGE_PATH / "zhenxun" / "sleep.jpg")
|
||||
await broadcast_group(
|
||||
f"{NICKNAME}要睡觉了,你们也要早点睡呀" + img,
|
||||
log_cmd="被动早晚安",
|
||||
check_func=check,
|
||||
)
|
||||
logger.info("每日晚安发送...")
|
||||
|
||||
@ -5,6 +5,7 @@ from nonebot.adapters import Bot
|
||||
from nonebot.params import Command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot_plugin_alconna import Text as alcText
|
||||
from nonebot_plugin_alconna import UniMsg
|
||||
from nonebot_plugin_saa import Text
|
||||
from nonebot_plugin_session import EventSession
|
||||
@ -51,8 +52,11 @@ async def _(
|
||||
message: UniMsg,
|
||||
command: Annotated[tuple[str, ...], Command()],
|
||||
):
|
||||
message[0].text = message[0].text.replace(command[0], "").strip()
|
||||
# await Text("正在发送..请等一下哦!").send()
|
||||
for msg in message:
|
||||
if isinstance(msg, alcText) and msg.text.strip().startswith(command[0]):
|
||||
msg.text = msg.text.replace(command[0], "", 1).strip()
|
||||
break
|
||||
await Text("正在发送..请等一下哦!").send()
|
||||
count, error_count = await BroadcastManage.send(bot, message, session)
|
||||
result = f"成功广播 {count} 个群组"
|
||||
if error_count:
|
||||
|
||||
@ -9,23 +9,13 @@ from nonebot_plugin_alconna import UniMsg
|
||||
from nonebot_plugin_saa import (
|
||||
Image,
|
||||
MessageFactory,
|
||||
TargetDoDoChannel,
|
||||
TargetQQGroup,
|
||||
Text,
|
||||
)
|
||||
from nonebot_plugin_session import EventSession
|
||||
from pydantic import BaseModel
|
||||
|
||||
from zhenxun.models.group_console import GroupConsole
|
||||
from zhenxun.services.log import logger
|
||||
|
||||
|
||||
class GroupChannel(BaseModel):
|
||||
|
||||
group_id: str
|
||||
"""群组id"""
|
||||
channel_id: str | None = None
|
||||
"""频道id"""
|
||||
from zhenxun.utils.platform import PlatformManage
|
||||
|
||||
|
||||
class BroadcastManage:
|
||||
@ -50,24 +40,27 @@ class BroadcastManage:
|
||||
message_list.append(Image(msg.url))
|
||||
elif isinstance(msg, alc.Text):
|
||||
message_list.append(Text(msg.text))
|
||||
if group_list := await cls.__get_group_list(bot):
|
||||
group_list, _ = await PlatformManage.get_group_list(bot)
|
||||
if group_list:
|
||||
error_count = 0
|
||||
for group in group_list:
|
||||
try:
|
||||
if not await GroupConsole.is_block_task(
|
||||
group.group_id, "broadcast", group.channel_id
|
||||
):
|
||||
if isinstance(bot, (v11Bot, v12Bot)):
|
||||
target = TargetQQGroup(group_id=int(group.group_id))
|
||||
elif isinstance(bot, DodoBot):
|
||||
target = TargetDoDoChannel(channel_id=group.channel_id) # type: ignore
|
||||
await MessageFactory(message_list).send_to(target, bot)
|
||||
logger.debug(
|
||||
"发送成功",
|
||||
"广播",
|
||||
session=session,
|
||||
target=f"{group.group_id}:{group.channel_id}",
|
||||
target = PlatformManage.get_target(
|
||||
bot, group.group_id, group.channel_id
|
||||
)
|
||||
if target:
|
||||
await MessageFactory(message_list).send_to(target, bot)
|
||||
logger.debug(
|
||||
"发送成功",
|
||||
"广播",
|
||||
session=session,
|
||||
target=f"{group.group_id}:{group.channel_id}",
|
||||
)
|
||||
else:
|
||||
logger.warning("target为空", "广播", session=session)
|
||||
except Exception as e:
|
||||
error_count += 1
|
||||
logger.error(
|
||||
@ -79,40 +72,3 @@ class BroadcastManage:
|
||||
)
|
||||
return len(group_list) - error_count, error_count
|
||||
return 0, 0
|
||||
|
||||
@classmethod
|
||||
async def __get_group_list(cls, bot: Bot) -> list[GroupChannel]:
|
||||
"""获取群组id列表
|
||||
|
||||
参数:
|
||||
bot: Bot
|
||||
|
||||
返回:
|
||||
list[str]: 群组id列表
|
||||
"""
|
||||
if isinstance(bot, (v11Bot, v12Bot)):
|
||||
group_list = await bot.get_group_list()
|
||||
return [GroupChannel(group_id=str(g["group_id"])) for g in group_list]
|
||||
if isinstance(bot, DodoBot):
|
||||
island_list = await bot.get_island_list()
|
||||
source_id_list = [
|
||||
g.island_source_id for g in island_list if g.island_source_id
|
||||
]
|
||||
channel_id_list = []
|
||||
for id in source_id_list:
|
||||
channel_list = await bot.get_channel_list(island_source_id=id)
|
||||
channel_id_list += [
|
||||
GroupChannel(group_id=id, channel_id=c.channel_id)
|
||||
for c in channel_list
|
||||
]
|
||||
return channel_id_list
|
||||
if isinstance(bot, KaiheilaBot):
|
||||
# TODO: kaiheila获取群组列表
|
||||
pass
|
||||
# group_list = await bot.guild_list()
|
||||
# if group_list.guilds:
|
||||
# return [g.open_id for g in group_list.guilds if g.open_id]
|
||||
if isinstance(bot, DiscordBot):
|
||||
# TODO: discord获取群组列表
|
||||
pass
|
||||
return []
|
||||
|
||||
@ -108,6 +108,12 @@ class GroupConsole(Model):
|
||||
返回:
|
||||
bool: 是否禁用被动
|
||||
"""
|
||||
if not channel_id:
|
||||
return await cls.exists(
|
||||
group_id=group_id,
|
||||
channel_id__isnull=True,
|
||||
block_task__contains=f"{task},",
|
||||
)
|
||||
return await cls.exists(
|
||||
group_id=group_id, channel_id=channel_id, block_task__contains=f"{task},"
|
||||
)
|
||||
|
||||
@ -1,9 +1,20 @@
|
||||
from typing import Awaitable, Callable, Literal, Set
|
||||
|
||||
import nonebot
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.adapters.discord import Bot as DiscordBot
|
||||
from nonebot.adapters.dodo import Bot as DodoBot
|
||||
from nonebot.adapters.kaiheila import Bot as KaiheilaBot
|
||||
from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
||||
from nonebot.adapters.onebot.v12 import Bot as v12Bot
|
||||
from nonebot.utils import is_coroutine_callable
|
||||
from nonebot_plugin_saa import (
|
||||
MessageFactory,
|
||||
TargetDoDoChannel,
|
||||
TargetKaiheilaChannel,
|
||||
TargetQQGroup,
|
||||
Text,
|
||||
)
|
||||
|
||||
from zhenxun.models.friend_user import FriendUser
|
||||
from zhenxun.models.group_console import GroupConsole
|
||||
@ -23,7 +34,7 @@ class PlatformManage:
|
||||
int: 更新个数
|
||||
"""
|
||||
create_list = []
|
||||
group_list, platform = await cls.__get_group_list(bot)
|
||||
group_list, platform = await cls.get_group_list(bot)
|
||||
if group_list:
|
||||
exists_group_list = await GroupConsole.all().values_list(
|
||||
"group_id", "channel_id"
|
||||
@ -42,7 +53,25 @@ class PlatformManage:
|
||||
return len(create_list)
|
||||
|
||||
@classmethod
|
||||
async def __get_group_list(cls, bot: Bot) -> tuple[list[GroupConsole], str]:
|
||||
def get_platform(cls, bot: Bot) -> str | None:
|
||||
"""获取平台
|
||||
|
||||
参数:
|
||||
bot: Bot
|
||||
|
||||
返回:
|
||||
str | None: 平台
|
||||
"""
|
||||
if isinstance(bot, (v11Bot, v12Bot)):
|
||||
return "qq"
|
||||
if isinstance(bot, DodoBot):
|
||||
return "dodo"
|
||||
if isinstance(bot, KaiheilaBot):
|
||||
return "kaiheila"
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def get_group_list(cls, bot: Bot) -> tuple[list[GroupConsole], str]:
|
||||
"""获取群组列表
|
||||
|
||||
参数:
|
||||
@ -121,7 +150,7 @@ class PlatformManage:
|
||||
int: 更新个数
|
||||
"""
|
||||
create_list = []
|
||||
friend_list, platform = await cls.__get_friend_list(bot)
|
||||
friend_list, platform = await cls.get_friend_list(bot)
|
||||
if friend_list:
|
||||
user_id_list = await FriendUser.all().values_list("user_id", flat=True)
|
||||
for friend in friend_list:
|
||||
@ -133,7 +162,7 @@ class PlatformManage:
|
||||
return len(create_list)
|
||||
|
||||
@classmethod
|
||||
async def __get_friend_list(cls, bot: Bot) -> tuple[list[FriendUser], str]:
|
||||
async def get_friend_list(cls, bot: Bot) -> tuple[list[FriendUser], str]:
|
||||
"""获取好友列表
|
||||
|
||||
参数:
|
||||
@ -167,3 +196,116 @@ class PlatformManage:
|
||||
# TODO: discord好友列表
|
||||
pass
|
||||
return [], ""
|
||||
|
||||
@classmethod
|
||||
def get_target(cls, bot: Bot, group_id: str | None, channel_id: str | None):
|
||||
"""获取发生Target
|
||||
|
||||
参数:
|
||||
bot: Bot
|
||||
group_id: 群组id
|
||||
channel_id: 频道id
|
||||
|
||||
返回:
|
||||
target: 对应平台Target
|
||||
"""
|
||||
target = None
|
||||
if isinstance(bot, (v11Bot, v12Bot)):
|
||||
if group_id:
|
||||
target = TargetQQGroup(group_id=int(group_id))
|
||||
if channel_id:
|
||||
if isinstance(bot, DodoBot):
|
||||
target = TargetDoDoChannel(channel_id=channel_id)
|
||||
elif isinstance(bot, KaiheilaBot):
|
||||
target = TargetKaiheilaChannel(channel_id=channel_id)
|
||||
return target
|
||||
|
||||
|
||||
async def broadcast_group(
|
||||
message: str | MessageFactory,
|
||||
bot: Bot | list[Bot] | None = None,
|
||||
bot_id: str | Set[str] | None = None,
|
||||
ignore_group: Set[int] | None = None,
|
||||
check_func: Callable[[str, str | None], Awaitable] | None = None,
|
||||
log_cmd: str | None = None,
|
||||
platform: Literal["qq", "dodo", "kaiheila"] | None = None,
|
||||
):
|
||||
"""获取所有Bot或指定Bot对象广播群聊
|
||||
|
||||
Args:
|
||||
message: 广播消息内容
|
||||
bot: 指定bot对象.
|
||||
bot_id: 指定bot id.
|
||||
ignore_group: 忽略群聊列表.
|
||||
check_func: 发送前对群聊检测方法,判断是否发送.
|
||||
log_cmd: 日志标记.
|
||||
platform: 指定平台
|
||||
"""
|
||||
if platform and platform not in ["qq", "dodo", "kaiheila"]:
|
||||
raise ValueError("指定平台不支持")
|
||||
if not message:
|
||||
raise ValueError("群聊广播消息不能为空")
|
||||
bot_dict = nonebot.get_bots()
|
||||
bot_list: list[Bot] = []
|
||||
if bot:
|
||||
if isinstance(bot, list):
|
||||
bot_list = bot
|
||||
else:
|
||||
bot_list.append(bot)
|
||||
elif bot_id:
|
||||
_bot_id_list = bot_id
|
||||
if isinstance(bot_id, str):
|
||||
_bot_id_list = [bot_id]
|
||||
for id_ in _bot_id_list:
|
||||
if bot_id in bot_dict:
|
||||
bot_list.append(bot_dict[bot_id])
|
||||
else:
|
||||
logger.warning(f"Bot:{id_} 对象未连接或不存在")
|
||||
else:
|
||||
bot_list = list(bot_dict.values())
|
||||
_used_group = []
|
||||
for _bot in bot_list:
|
||||
try:
|
||||
if platform and platform != PlatformManage.get_platform(_bot):
|
||||
continue
|
||||
group_list, _ = await PlatformManage.get_group_list(_bot)
|
||||
if group_list:
|
||||
for group in group_list:
|
||||
key = f"{group.group_id}:{group.channel_id}"
|
||||
try:
|
||||
if (
|
||||
ignore_group
|
||||
and (
|
||||
group.group_id in ignore_group
|
||||
or group.channel_id in ignore_group
|
||||
)
|
||||
) or key in _used_group:
|
||||
continue
|
||||
is_continue = False
|
||||
if check_func:
|
||||
if is_coroutine_callable(check_func):
|
||||
is_continue = not await check_func(
|
||||
group.group_id, group.channel_id
|
||||
)
|
||||
else:
|
||||
is_continue = not check_func(
|
||||
group.group_id, group.channel_id
|
||||
)
|
||||
if is_continue:
|
||||
continue
|
||||
target = PlatformManage.get_target(
|
||||
_bot, group.group_id, group.channel_id
|
||||
)
|
||||
if target:
|
||||
_used_group.append(key)
|
||||
message_list = message
|
||||
if isinstance(message, str):
|
||||
message_list = MessageFactory([Text(message)])
|
||||
await MessageFactory(message_list).send_to(target, _bot)
|
||||
logger.debug("发送成功", log_cmd, target=key)
|
||||
else:
|
||||
logger.warning("target为空", log_cmd, target=key)
|
||||
except Exception as e:
|
||||
logger.error("发送失败", log_cmd, target=key, e=e)
|
||||
except Exception as e:
|
||||
logger.error(f"Bot: {_bot.self_id} 获取群聊列表失败", command=log_cmd, e=e)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user