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.adapters import Bot
|
||||||
from nonebot.plugin import PluginMetadata
|
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_saa import Image, Text
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_session import EventSession
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
普通管理员
|
普通管理员
|
||||||
格式:
|
格式:
|
||||||
开启/关闭[功能名称] : 开关功能
|
开启/关闭[功能名称] : 开关功能
|
||||||
|
开启/关闭群被动[被动名称] : 群被动开关
|
||||||
群被动状态 : 查看被动技能开关状态
|
群被动状态 : 查看被动技能开关状态
|
||||||
醒来 : 结束休眠
|
醒来 : 结束休眠
|
||||||
休息吧 : 群组休眠, 不会再响应命令
|
休息吧 : 群组休眠, 不会再响应命令
|
||||||
@ -29,6 +30,7 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
示例:
|
示例:
|
||||||
开启签到 : 开启签到
|
开启签到 : 开启签到
|
||||||
关闭签到 : 关闭签到
|
关闭签到 : 关闭签到
|
||||||
|
开启群被动早晚安 : 关闭被动任务早晚安
|
||||||
|
|
||||||
超级管理员额外命令
|
超级管理员额外命令
|
||||||
格式:
|
格式:
|
||||||
@ -61,26 +63,21 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
|
|
||||||
|
|
||||||
@_status_matcher.assign("$main")
|
@_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
|
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()
|
image = await build_plugin()
|
||||||
if image:
|
if image:
|
||||||
await Image(image.pic2bytes()).send(reply=True)
|
await Image(image.pic2bytes()).send(reply=True)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"查看功能列表",
|
f"查看{'功能' if arparma.find('task') else '被动'}列表",
|
||||||
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"查看被动列表",
|
|
||||||
arparma.header_result,
|
arparma.header_result,
|
||||||
session=session,
|
session=session,
|
||||||
)
|
)
|
||||||
@ -93,13 +90,27 @@ async def _(
|
|||||||
arparma: Arparma,
|
arparma: Arparma,
|
||||||
name: str,
|
name: str,
|
||||||
group: Match[str],
|
group: Match[str],
|
||||||
|
task: Query[bool] = AlconnaQuery("task.value", False),
|
||||||
):
|
):
|
||||||
if gid := session.id3 or session.id2:
|
if gid := session.id3 or session.id2:
|
||||||
|
if task.result:
|
||||||
|
result = await PluginManage.unblock_group_task(name, gid)
|
||||||
|
else:
|
||||||
result = await PluginManage.block_group_plugin(name, gid)
|
result = await PluginManage.block_group_plugin(name, gid)
|
||||||
await Text(result).send(reply=True)
|
await Text(result).send(reply=True)
|
||||||
logger.info(f"开启功能 {name}", arparma.header_result, session=session)
|
logger.info(f"开启功能 {name}", arparma.header_result, session=session)
|
||||||
elif session.id1 in bot.config.superusers:
|
elif session.id1 in bot.config.superusers:
|
||||||
group_id = group.result if group.available else None
|
group_id = group.result if group.available else None
|
||||||
|
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)
|
result = await PluginManage.superuser_block(name, None, group_id)
|
||||||
await Text(result).send(reply=True)
|
await Text(result).send(reply=True)
|
||||||
logger.info(
|
logger.info(
|
||||||
@ -118,13 +129,27 @@ async def _(
|
|||||||
name: str,
|
name: str,
|
||||||
block_type: Match[str],
|
block_type: Match[str],
|
||||||
group: Match[str],
|
group: Match[str],
|
||||||
|
task: Query[bool] = AlconnaQuery("task.value", False),
|
||||||
):
|
):
|
||||||
if gid := session.id3 or session.id2:
|
if gid := session.id3 or session.id2:
|
||||||
|
if task.result:
|
||||||
|
result = await PluginManage.block_group_task(name, gid)
|
||||||
|
else:
|
||||||
result = await PluginManage.unblock_group_plugin(name, gid)
|
result = await PluginManage.unblock_group_plugin(name, gid)
|
||||||
await Text(result).send(reply=True)
|
await Text(result).send(reply=True)
|
||||||
logger.info(f"关闭功能 {name}", arparma.header_result, session=session)
|
logger.info(f"关闭功能 {name}", arparma.header_result, session=session)
|
||||||
elif session.id1 in bot.config.superusers:
|
elif session.id1 in bot.config.superusers:
|
||||||
group_id = group.result if group.available else None
|
group_id = group.result if group.available else None
|
||||||
|
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
|
_type = BlockType.ALL
|
||||||
if block_type.available:
|
if block_type.available:
|
||||||
if block_type.result in ["p", "private"]:
|
if block_type.result in ["p", "private"]:
|
||||||
|
|||||||
@ -104,7 +104,9 @@ async def build_task(group_id: str | None) -> BuildImage:
|
|||||||
column_name = ["ID", "模块", "名称", "群组状态", "全局状态", "运行时间"]
|
column_name = ["ID", "模块", "名称", "群组状态", "全局状态", "运行时间"]
|
||||||
group = None
|
group = None
|
||||||
if group_id:
|
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:
|
if not group:
|
||||||
raise GroupInfoNotFound()
|
raise GroupInfoNotFound()
|
||||||
else:
|
else:
|
||||||
@ -145,17 +147,23 @@ class PluginManage:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def is_wake(cls, group_id: str) -> bool:
|
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 c.status
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def sleep(cls, group_id: str):
|
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
|
@classmethod
|
||||||
async def wake(cls, group_id: str):
|
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
|
@classmethod
|
||||||
async def block(cls, module: str):
|
async def block(cls, module: str):
|
||||||
@ -178,6 +186,32 @@ class PluginManage:
|
|||||||
"""
|
"""
|
||||||
return await cls._change_group_plugin(plugin_name, group_id, True)
|
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
|
@classmethod
|
||||||
async def unblock_group_plugin(cls, plugin_name: str, group_id: str) -> str:
|
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)
|
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
|
@classmethod
|
||||||
async def _change_group_plugin(
|
async def _change_group_plugin(
|
||||||
cls, plugin_name: str, group_id: str, status: bool
|
cls, plugin_name: str, group_id: str, status: bool
|
||||||
@ -212,7 +273,9 @@ class PluginManage:
|
|||||||
plugin = await PluginInfo.get_or_none(name=plugin_name)
|
plugin = await PluginInfo.get_or_none(name=plugin_name)
|
||||||
status_str = "开启" if status else "关闭"
|
status_str = "开启" if status else "关闭"
|
||||||
if plugin:
|
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 status:
|
||||||
if plugin.module in group.block_plugin:
|
if plugin.module in group.block_plugin:
|
||||||
group.block_plugin = group.block_plugin.replace(
|
group.block_plugin = group.block_plugin.replace(
|
||||||
@ -228,11 +291,44 @@ class PluginManage:
|
|||||||
return f"该功能已经{status_str}了喔,不要重复{status_str}..."
|
return f"该功能已经{status_str}了喔,不要重复{status_str}..."
|
||||||
return "没有找到这个功能喔..."
|
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
|
@classmethod
|
||||||
async def superuser_block(
|
async def superuser_block(
|
||||||
cls, plugin_name: str, block_type: BlockType | None, group_id: str | None
|
cls, plugin_name: str, block_type: BlockType | None, group_id: str | None
|
||||||
) -> str:
|
) -> str:
|
||||||
"""超级用户禁用
|
"""超级用户禁用插件
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
plugin_name: 插件名称
|
plugin_name: 插件名称
|
||||||
@ -248,7 +344,9 @@ class PluginManage:
|
|||||||
plugin = await PluginInfo.get_or_none(name=plugin_name)
|
plugin = await PluginInfo.get_or_none(name=plugin_name)
|
||||||
if plugin:
|
if plugin:
|
||||||
if group_id:
|
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:
|
if f"super:{plugin.module}," not in group.block_plugin:
|
||||||
group.block_plugin += f"super:{plugin.module},"
|
group.block_plugin += f"super:{plugin.module},"
|
||||||
await group.save(update_fields=["block_plugin"])
|
await group.save(update_fields=["block_plugin"])
|
||||||
|
|||||||
@ -63,6 +63,15 @@ _status_matcher.shortcut(
|
|||||||
prefix=True,
|
prefix=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_status_matcher.shortcut(
|
||||||
|
r"开启群被动(?P<name>.+)",
|
||||||
|
command="switch",
|
||||||
|
arguments=["open", "{name}", "--task"],
|
||||||
|
prefix=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
_status_matcher.shortcut(
|
_status_matcher.shortcut(
|
||||||
r"开启(?P<name>.+)",
|
r"开启(?P<name>.+)",
|
||||||
command="switch",
|
command="switch",
|
||||||
@ -70,6 +79,13 @@ _status_matcher.shortcut(
|
|||||||
prefix=True,
|
prefix=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_status_matcher.shortcut(
|
||||||
|
r"关闭群被动(?P<name>.+)",
|
||||||
|
command="switch",
|
||||||
|
arguments=["close", "{name}", "--task"],
|
||||||
|
prefix=True,
|
||||||
|
)
|
||||||
|
|
||||||
_status_matcher.shortcut(
|
_status_matcher.shortcut(
|
||||||
r"关闭(?P<name>.+)",
|
r"关闭(?P<name>.+)",
|
||||||
command="switch",
|
command="switch",
|
||||||
@ -77,6 +93,7 @@ _status_matcher.shortcut(
|
|||||||
prefix=True,
|
prefix=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
_group_status_matcher.shortcut(
|
_group_status_matcher.shortcut(
|
||||||
r"醒来",
|
r"醒来",
|
||||||
command="group-status",
|
command="group-status",
|
||||||
|
|||||||
@ -1,28 +1,75 @@
|
|||||||
|
import nonebot
|
||||||
|
from nonebot.plugin import PluginMetadata
|
||||||
from nonebot_plugin_apscheduler import scheduler
|
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
|
||||||
|
|
||||||
# # 早上好
|
__plugin_meta__ = PluginMetadata(
|
||||||
# @scheduler.scheduled_job(
|
name="早晚安被动技能",
|
||||||
# "cron",
|
description="早晚安被动技能",
|
||||||
# hour=6,
|
usage="",
|
||||||
# minute=1,
|
extra=PluginExtraData(
|
||||||
# )
|
author="HibiKier",
|
||||||
# async def _():
|
version="0.1",
|
||||||
# img = image(IMAGE_PATH / "zhenxun" / "zao.jpg")
|
plugin_type=PluginType.HIDDEN,
|
||||||
# await broadcast_group("[[_task|zwa]]早上好" + img, log_cmd="被动早晚安")
|
tasks=[
|
||||||
# logger.info("每日早安发送...")
|
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(
|
@scheduler.scheduled_job(
|
||||||
# "cron",
|
"cron",
|
||||||
# hour=23,
|
hour=23,
|
||||||
# minute=59,
|
minute=59,
|
||||||
# )
|
)
|
||||||
# async def _():
|
async def _():
|
||||||
# img = image(IMAGE_PATH / "zhenxun" / "sleep.jpg")
|
img = Image(IMAGE_PATH / "zhenxun" / "sleep.jpg")
|
||||||
# await broadcast_group(
|
await broadcast_group(
|
||||||
# f"[[_task|zwa]]{NICKNAME}要睡觉了,你们也要早点睡呀" + img, log_cmd="被动早晚安"
|
f"{NICKNAME}要睡觉了,你们也要早点睡呀" + img,
|
||||||
# )
|
log_cmd="被动早晚安",
|
||||||
# logger.info("每日晚安发送...")
|
check_func=check,
|
||||||
|
)
|
||||||
|
logger.info("每日晚安发送...")
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from nonebot.adapters import Bot
|
|||||||
from nonebot.params import Command
|
from nonebot.params import Command
|
||||||
from nonebot.permission import SUPERUSER
|
from nonebot.permission import SUPERUSER
|
||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
|
from nonebot_plugin_alconna import Text as alcText
|
||||||
from nonebot_plugin_alconna import UniMsg
|
from nonebot_plugin_alconna import UniMsg
|
||||||
from nonebot_plugin_saa import Text
|
from nonebot_plugin_saa import Text
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_session import EventSession
|
||||||
@ -51,8 +52,11 @@ async def _(
|
|||||||
message: UniMsg,
|
message: UniMsg,
|
||||||
command: Annotated[tuple[str, ...], Command()],
|
command: Annotated[tuple[str, ...], Command()],
|
||||||
):
|
):
|
||||||
message[0].text = message[0].text.replace(command[0], "").strip()
|
for msg in message:
|
||||||
# await Text("正在发送..请等一下哦!").send()
|
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)
|
count, error_count = await BroadcastManage.send(bot, message, session)
|
||||||
result = f"成功广播 {count} 个群组"
|
result = f"成功广播 {count} 个群组"
|
||||||
if error_count:
|
if error_count:
|
||||||
|
|||||||
@ -9,23 +9,13 @@ from nonebot_plugin_alconna import UniMsg
|
|||||||
from nonebot_plugin_saa import (
|
from nonebot_plugin_saa import (
|
||||||
Image,
|
Image,
|
||||||
MessageFactory,
|
MessageFactory,
|
||||||
TargetDoDoChannel,
|
|
||||||
TargetQQGroup,
|
|
||||||
Text,
|
Text,
|
||||||
)
|
)
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_session import EventSession
|
||||||
from pydantic import BaseModel
|
|
||||||
|
|
||||||
from zhenxun.models.group_console import GroupConsole
|
from zhenxun.models.group_console import GroupConsole
|
||||||
from zhenxun.services.log import logger
|
from zhenxun.services.log import logger
|
||||||
|
from zhenxun.utils.platform import PlatformManage
|
||||||
|
|
||||||
class GroupChannel(BaseModel):
|
|
||||||
|
|
||||||
group_id: str
|
|
||||||
"""群组id"""
|
|
||||||
channel_id: str | None = None
|
|
||||||
"""频道id"""
|
|
||||||
|
|
||||||
|
|
||||||
class BroadcastManage:
|
class BroadcastManage:
|
||||||
@ -50,17 +40,18 @@ class BroadcastManage:
|
|||||||
message_list.append(Image(msg.url))
|
message_list.append(Image(msg.url))
|
||||||
elif isinstance(msg, alc.Text):
|
elif isinstance(msg, alc.Text):
|
||||||
message_list.append(Text(msg.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
|
error_count = 0
|
||||||
for group in group_list:
|
for group in group_list:
|
||||||
try:
|
try:
|
||||||
if not await GroupConsole.is_block_task(
|
if not await GroupConsole.is_block_task(
|
||||||
group.group_id, "broadcast", group.channel_id
|
group.group_id, "broadcast", group.channel_id
|
||||||
):
|
):
|
||||||
if isinstance(bot, (v11Bot, v12Bot)):
|
target = PlatformManage.get_target(
|
||||||
target = TargetQQGroup(group_id=int(group.group_id))
|
bot, group.group_id, group.channel_id
|
||||||
elif isinstance(bot, DodoBot):
|
)
|
||||||
target = TargetDoDoChannel(channel_id=group.channel_id) # type: ignore
|
if target:
|
||||||
await MessageFactory(message_list).send_to(target, bot)
|
await MessageFactory(message_list).send_to(target, bot)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"发送成功",
|
"发送成功",
|
||||||
@ -68,6 +59,8 @@ class BroadcastManage:
|
|||||||
session=session,
|
session=session,
|
||||||
target=f"{group.group_id}:{group.channel_id}",
|
target=f"{group.group_id}:{group.channel_id}",
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
logger.warning("target为空", "广播", session=session)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_count += 1
|
error_count += 1
|
||||||
logger.error(
|
logger.error(
|
||||||
@ -79,40 +72,3 @@ class BroadcastManage:
|
|||||||
)
|
)
|
||||||
return len(group_list) - error_count, error_count
|
return len(group_list) - error_count, error_count
|
||||||
return 0, 0
|
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: 是否禁用被动
|
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(
|
return await cls.exists(
|
||||||
group_id=group_id, channel_id=channel_id, block_task__contains=f"{task},"
|
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 import Bot
|
||||||
from nonebot.adapters.discord import Bot as DiscordBot
|
from nonebot.adapters.discord import Bot as DiscordBot
|
||||||
from nonebot.adapters.dodo import Bot as DodoBot
|
from nonebot.adapters.dodo import Bot as DodoBot
|
||||||
from nonebot.adapters.kaiheila import Bot as KaiheilaBot
|
from nonebot.adapters.kaiheila import Bot as KaiheilaBot
|
||||||
from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
||||||
from nonebot.adapters.onebot.v12 import Bot as v12Bot
|
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.friend_user import FriendUser
|
||||||
from zhenxun.models.group_console import GroupConsole
|
from zhenxun.models.group_console import GroupConsole
|
||||||
@ -23,7 +34,7 @@ class PlatformManage:
|
|||||||
int: 更新个数
|
int: 更新个数
|
||||||
"""
|
"""
|
||||||
create_list = []
|
create_list = []
|
||||||
group_list, platform = await cls.__get_group_list(bot)
|
group_list, platform = await cls.get_group_list(bot)
|
||||||
if group_list:
|
if group_list:
|
||||||
exists_group_list = await GroupConsole.all().values_list(
|
exists_group_list = await GroupConsole.all().values_list(
|
||||||
"group_id", "channel_id"
|
"group_id", "channel_id"
|
||||||
@ -42,7 +53,25 @@ class PlatformManage:
|
|||||||
return len(create_list)
|
return len(create_list)
|
||||||
|
|
||||||
@classmethod
|
@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: 更新个数
|
int: 更新个数
|
||||||
"""
|
"""
|
||||||
create_list = []
|
create_list = []
|
||||||
friend_list, platform = await cls.__get_friend_list(bot)
|
friend_list, platform = await cls.get_friend_list(bot)
|
||||||
if friend_list:
|
if friend_list:
|
||||||
user_id_list = await FriendUser.all().values_list("user_id", flat=True)
|
user_id_list = await FriendUser.all().values_list("user_id", flat=True)
|
||||||
for friend in friend_list:
|
for friend in friend_list:
|
||||||
@ -133,7 +162,7 @@ class PlatformManage:
|
|||||||
return len(create_list)
|
return len(create_list)
|
||||||
|
|
||||||
@classmethod
|
@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好友列表
|
# TODO: discord好友列表
|
||||||
pass
|
pass
|
||||||
return [], ""
|
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