提供qq协议端判断方法,广播添加to_me规则以及延迟 (#1858)

*  提供qq协议端判断方法

* 🩹 API重试添加额外错误捕获

* 🩹 广播添加延迟,添加to_me规则
This commit is contained in:
HibiKier 2025-02-24 09:33:06 +08:00 committed by GitHub
parent a6ddb726d3
commit f1d32bff89
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 82 additions and 56 deletions

View File

@ -58,7 +58,7 @@
“真寻是<strong>[椛椛](https://github.com/FloatTech/ZeroBot-Plugin)</strong>的好朋友!” “真寻是<strong>[椛椛](https://github.com/FloatTech/ZeroBot-Plugin)</strong>的好朋友!”
🎉喜欢真寻,于是真寻就来了!🎉 🎉 喜欢真寻,于是真寻就来了!🎉
本项目符合 [OneBot](https://github.com/howmanybots/onebot) 标准,可基于以下项目与机器人框架/平台进行交互 本项目符合 [OneBot](https://github.com/howmanybots/onebot) 标准,可基于以下项目与机器人框架/平台进行交互
@ -107,13 +107,13 @@ AccessToken: PUBLIC_ZHENXUN_TEST
“不要害怕,你的背后还有千千万万的 <strong>伙伴</strong> 啊!” “不要害怕,你的背后还有千千万万的 <strong>伙伴</strong> 啊!”
| 项目名称 | 主要用途 | 仓库作者 | 备注 | | 项目名称 | 主要用途 | 仓库作者 | 备注 |
| :--------------------------------------------------------------------: | :------: | :-------------------------------------------------: | :---------------------------: | | :--------------------------------------------------------------------: | :------: | :-------------------------------------------------: | :---------------------------------------------------: |
| [插件库](https://github.com/zhenxun-org/zhenxun_bot_plugins) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 原 plugins 文件夹插件 | | [插件库](https://github.com/zhenxun-org/zhenxun_bot_plugins) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 原 plugins 文件夹插件 |
| [插件索引库](https://github.com/zhenxun-org/zhenxun_bot_plugins_index) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 扩展插件索引库 | | [插件索引库](https://github.com/zhenxun-org/zhenxun_bot_plugins_index) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 扩展插件索引库 |
| [一键安装](https://github.com/soloxiaoye2022/zhenxun_bot-deploy) | 安装 | [soloxiaoye2022](https://github.com/soloxiaoye2022) | 第三方 | | [一键安装](https://github.com/soloxiaoye2022/zhenxun_bot-deploy) | 安装 | [soloxiaoye2022](https://github.com/soloxiaoye2022) | 第三方 |
| [WebUi](https://github.com/HibiKier/zhenxun_bot_webui) | 管理 | [hibikier](https://github.com/HibiKier) | 基于真寻 WebApi 的 webui 实现 [预览](#-webui界面展示) | | [WebUi](https://github.com/HibiKier/zhenxun_bot_webui) | 管理 | [hibikier](https://github.com/HibiKier) | 基于真寻 WebApi 的 webui 实现 [预览](#-webui界面展示) |
| [安卓 app(WebUi)](https://github.com/YuS1aN/zhenxun_bot_android_ui) | 安装 | [YuS1aN](https://github.com/YuS1aN) | 第三方 | | [安卓 app(WebUi)](https://github.com/YuS1aN/zhenxun_bot_android_ui) | 安装 | [YuS1aN](https://github.com/YuS1aN) | 第三方 |
</div> </div>
@ -140,8 +140,7 @@ pip install poetry # 安装 poetry
poetry install # 安装依赖 poetry install # 安装依赖
# 开始运行 # 开始运行
poetry shell # 进入虚拟环境 poetry run python bot.py
python bot.py # 运行机器人
``` ```
## 📝 简单配置 ## 📝 简单配置
@ -158,7 +157,7 @@ python bot.py # 运行机器人
DB_URL 是基于 Tortoise ORM 的数据库连接字符串,用于指定项目所使用的数据库。以下是 DB_URL 的组成部分以及示例: DB_URL 是基于 Tortoise ORM 的数据库连接字符串,用于指定项目所使用的数据库。以下是 DB_URL 的组成部分以及示例:
格式为: ```<数据库类型>://<用户名>:<密码>@<主机>:<端口>/<数据库名>?<参数>``` 格式为: `<数据库类型>://<用户名>:<密码>@<主机>:<端口>/<数据库名>?<参数>`
- 数据库类型:表示数据库类型,例如 postgres、mysql、sqlite 等。 - 数据库类型:表示数据库类型,例如 postgres、mysql、sqlite 等。
- 用户名:数据库的用户名,例如 root。 - 用户名:数据库的用户名,例如 root。
@ -264,7 +263,7 @@ DB_URL 是基于 Tortoise ORM 的数据库连接字符串,用于指定项目
(可以告诉我你的 **github** 地址,我偷偷换掉 0v|) (可以告诉我你的 **github** 地址,我偷偷换掉 0v|)
[shenqi](https://afdian.net/u/fa923a8cfe3d11eba61752540025c377) [A_Kyuu](https://afdian.net/u/b83954fc2c1211eba9eb52540025c377) [疯狂混沌](https://afdian.net/u/789a2f9200cd11edb38352540025c377) [投冥](https://afdian.net/a/144514mm) [茶喵](https://afdian.net/u/fd22382eac4d11ecbfc652540025c377) [AemokpaTNR](https://afdian.net/u/1169bb8c8a9611edb0c152540025c377) [爱发电用户\_wrxn](https://afdian.net/u/4aa03d20db4311ecb1e752540025c377) [qqw](https://afdian.net/u/b71db4e2cc3e11ebb76652540025c377) [溫一壺月光下酒](https://afdian.net/u/ad667a5c650c11ed89bf52540025c377) [伝木](https://afdian.net/u/246b80683f9511edba7552540025c377) [阿奎](https://afdian.net/u/da41f72845d511ed930d52540025c377) [醉梦尘逸](https://afdian.net/u/bc11d2683cd011ed99b552540025c377) [Abc](https://afdian.net/u/870dc10a3cd311ed828852540025c377) [本喵无敌哒](https://afdian.net/u/dffaa9005bc911ebb69b52540025c377) [椎名冬羽](https://afdian.net/u/ca1ebd64395e11ed81b452540025c377) [kaito](https://afdian.net/u/a055e20a498811eab1f052540025c377) [笑柒 XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377) [请问一份爱多少钱](https://afdian.net/u/f57ef6602dbd11ed977f52540025c377) [咸鱼鱼鱼鱼](https://afdian.net/u/8e39b9a400e011ed9f4a52540025c377) [Kafka](https://afdian.net/u/41d66798ef6911ecbc5952540025c377) [墨然](https://afdian.net/u/8aa5874a644d11eb8a6752540025c377) [爱发电用户\_T9e4](https://afdian.net/u/2ad1bb82f3a711eca22852540025c377) [笑柒 XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377) [noahzark](https://afdian.net/a/noahzark) [腊条](https://afdian.net/u/f739c4d69eca11eba94b52540025c377) [zeroller](https://afdian.net/u/0e599e96257211ed805152540025c377) [爱发电用户\_4jrf](https://afdian.net/u/6b2cdcc817c611ed949152540025c377) [爱发电用户\_TBsd](https://afdian.net/u/db638b60217911ed9efd52540025c377) [烟寒若雨](https://afdian.net/u/067bd2161eec11eda62b52540025c377) [ln](https://afdian.net/u/b51914ba1c6611ed8a4e52540025c377) [爱发电用户\_b9S4](https://afdian.net/u/3d8f30581a2911edba6d52540025c377) [爱发电用户\_c58s](https://afdian.net/u/a6ad8dda195e11ed9a4152540025c377) [爱发电用户\_eNr9](https://afdian.net/u/05fdb41c0c9a11ed814952540025c377) [MangataAkihi](https://github.com/Sakuracio) [](https://afdian.net/u/69b76e9ec77b11ec874f52540025c377) [爱发电用户\_Bc6j](https://afdian.net/u/8546be24f44111eca64052540025c377) [大魔王](https://github.com/xipesoy) [CopilotLaLaLa](https://github.com/CopilotLaLaLa) [嘿小欧](https://afdian.net/u/daa4bec4f24911ec82e552540025c377) [回忆的秋千](https://afdian.net/u/e315d9c6f14f11ecbeef52540025c377) [十年くん](https://github.com/shinianj) [](https://afdian.net/u/9b266244f23911eca19052540025c377) [yajiwa](https://github.com/yajiwa) [爆金币](https://afdian.net/u/0d78879ef23711ecb22452540025c377)... [Zer](https://afdian.com/u/6bccdb2a60b411ec9ad452540025c377) [爱发电用户\_HTjk](https://afdian.com/u/6c7d0208064511ec8d7b52540025c377) [shenghuo2](https://afdian.com/u/bca13286102111eda2a052540025c377) [术樱](https://afdian.com/u/414da63a09a311ec8eb752540025c377) [飞火](https://afdian.com/u/404135f48ed711ec962152540025c377) [shenqi](https://afdian.net/u/fa923a8cfe3d11eba61752540025c377) [A_Kyuu](https://afdian.net/u/b83954fc2c1211eba9eb52540025c377) [疯狂混沌](https://afdian.net/u/789a2f9200cd11edb38352540025c377) [投冥](https://afdian.net/a/144514mm) [茶喵](https://afdian.net/u/fd22382eac4d11ecbfc652540025c377) [AemokpaTNR](https://afdian.net/u/1169bb8c8a9611edb0c152540025c377) [爱发电用户\_wrxn](https://afdian.net/u/4aa03d20db4311ecb1e752540025c377) [qqw](https://afdian.net/u/b71db4e2cc3e11ebb76652540025c377) [溫一壺月光下酒](https://afdian.net/u/ad667a5c650c11ed89bf52540025c377) [伝木](https://afdian.net/u/246b80683f9511edba7552540025c377) [阿奎](https://afdian.net/u/da41f72845d511ed930d52540025c377) [醉梦尘逸](https://afdian.net/u/bc11d2683cd011ed99b552540025c377) [Abc](https://afdian.net/u/870dc10a3cd311ed828852540025c377) [本喵无敌哒](https://afdian.net/u/dffaa9005bc911ebb69b52540025c377) [椎名冬羽](https://afdian.net/u/ca1ebd64395e11ed81b452540025c377) [kaito](https://afdian.net/u/a055e20a498811eab1f052540025c377) [笑柒 XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377) [请问一份爱多少钱](https://afdian.net/u/f57ef6602dbd11ed977f52540025c377) [咸鱼鱼鱼鱼](https://afdian.net/u/8e39b9a400e011ed9f4a52540025c377) [Kafka](https://afdian.net/u/41d66798ef6911ecbc5952540025c377) [墨然](https://afdian.net/u/8aa5874a644d11eb8a6752540025c377) [爱发电用户\_T9e4](https://afdian.net/u/2ad1bb82f3a711eca22852540025c377) [笑柒 XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377) [noahzark](https://afdian.net/a/noahzark) [腊条](https://afdian.net/u/f739c4d69eca11eba94b52540025c377) [zeroller](https://afdian.net/u/0e599e96257211ed805152540025c377) [爱发电用户\_4jrf](https://afdian.net/u/6b2cdcc817c611ed949152540025c377) [爱发电用户\_TBsd](https://afdian.net/u/db638b60217911ed9efd52540025c377) [烟寒若雨](https://afdian.net/u/067bd2161eec11eda62b52540025c377) [ln](https://afdian.net/u/b51914ba1c6611ed8a4e52540025c377) [爱发电用户\_b9S4](https://afdian.net/u/3d8f30581a2911edba6d52540025c377) [爱发电用户\_c58s](https://afdian.net/u/a6ad8dda195e11ed9a4152540025c377) [爱发电用户\_eNr9](https://afdian.net/u/05fdb41c0c9a11ed814952540025c377) [MangataAkihi](https://github.com/Sakuracio) [](https://afdian.net/u/69b76e9ec77b11ec874f52540025c377) [爱发电用户\_Bc6j](https://afdian.net/u/8546be24f44111eca64052540025c377) [大魔王](https://github.com/xipesoy) [CopilotLaLaLa](https://github.com/CopilotLaLaLa) [嘿小欧](https://afdian.net/u/daa4bec4f24911ec82e552540025c377) [回忆的秋千](https://afdian.net/u/e315d9c6f14f11ecbeef52540025c377) [十年くん](https://github.com/shinianj) [](https://afdian.net/u/9b266244f23911eca19052540025c377) [yajiwa](https://github.com/yajiwa) [爆金币](https://afdian.net/u/0d78879ef23711ecb22452540025c377)...
## 📜 贡献指南 ## 📜 贡献指南
@ -327,7 +326,7 @@ Project [zhenxun_bot](https://github.com/users/HibiKier/projects/2)
<img src="https://contrib.rocks/image?repo=HibiKier/zhenxun_bot&max=1000" alt="contributors"/> <img src="https://contrib.rocks/image?repo=HibiKier/zhenxun_bot&max=1000" alt="contributors"/>
</a> </a>
## 📸 WebUI界面展示 ## 📸 WebUI 界面展示
<div style="display: flex; flex-wrap: wrap; justify-content: space-between;"> <div style="display: flex; flex-wrap: wrap; justify-content: space-between;">
<div style="width: 48%; margin-bottom: 10px;"> <div style="width: 48%; margin-bottom: 10px;">

View File

@ -29,6 +29,7 @@ _flmt = FreqLimiter(300)
async def _( async def _(
matcher: Matcher, bot: Bot, event: Event, state: T_State, session: EventSession matcher: Matcher, bot: Bot, event: Event, state: T_State, session: EventSession
): ):
extra = {}
if plugin := matcher.plugin: if plugin := matcher.plugin:
if metadata := plugin.metadata: if metadata := plugin.metadata:
extra = metadata.extra extra = metadata.extra
@ -66,7 +67,12 @@ async def _(
time_str = f"{hours} 小时 {minute}分钟" time_str = f"{hours} 小时 {minute}分钟"
else: else:
time_str = f"{minute} 分钟" time_str = f"{minute} 分钟"
if time != -1 and ban_result and _flmt.check(user_id): if (
not extra.get("ignore_prompt")
and time != -1
and ban_result
and _flmt.check(user_id)
):
_flmt.start_cd(user_id) _flmt.start_cd(user_id)
await MessageUtils.build_message( await MessageUtils.build_message(
[ [

View File

@ -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.rule import to_me
from nonebot_plugin_alconna import Text as alcText from nonebot_plugin_alconna import Text as alcText
from nonebot_plugin_alconna import UniMsg from nonebot_plugin_alconna import UniMsg
from nonebot_plugin_session import EventSession from nonebot_plugin_session import EventSession
@ -41,7 +42,9 @@ __plugin_meta__ = PluginMetadata(
).to_dict(), ).to_dict(),
) )
_matcher = on_command("广播", priority=1, permission=SUPERUSER, block=True) _matcher = on_command(
"广播", priority=1, permission=SUPERUSER, block=True, rule=to_me()
)
@_matcher.handle() @_matcher.handle()

View File

@ -1,11 +1,8 @@
import asyncio
import random
from nonebot.adapters import Bot from nonebot.adapters import Bot
import nonebot_plugin_alconna as alc import nonebot_plugin_alconna as alc
# 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_plugin_alconna import Image, UniMsg from nonebot_plugin_alconna import Image, UniMsg
from nonebot_plugin_session import EventSession from nonebot_plugin_session import EventSession
@ -59,6 +56,7 @@ class BroadcastManage:
session=session, session=session,
target=f"{group.group_id}:{group.channel_id}", target=f"{group.group_id}:{group.channel_id}",
) )
await asyncio.sleep(random.randint(1, 3))
else: else:
logger.warning("target为空", "广播", session=session) logger.warning("target为空", "广播", session=session)
except Exception as e: except Exception as e:

View File

@ -1,3 +1,4 @@
import asyncio
from collections.abc import Awaitable, Callable from collections.abc import Awaitable, Callable
import random import random
from typing import Literal from typing import Literal
@ -156,43 +157,44 @@ class PlatformUtils:
返回: 返回:
UserData | None: 用户数据 UserData | None: 用户数据
""" """
if interface := get_interface(bot): if not (interface := get_interface(bot)):
member = None return None
user = None member = None
if channel_id: user = None
member = await interface.get_member( if channel_id:
SceneType.CHANNEL_TEXT, channel_id, user_id member = await interface.get_member(
) SceneType.CHANNEL_TEXT, channel_id, user_id
if member: )
user = member.user
elif group_id:
member = await interface.get_member(SceneType.GROUP, group_id, user_id)
if member:
user = member.user
else:
user = await interface.get_user(user_id)
if not user:
return None
if member: if member:
return UserData( user = member.user
name=user.name or "", elif group_id:
card=member.nick, member = await interface.get_member(SceneType.GROUP, group_id, user_id)
user_id=user.id, if member:
group_id=group_id, user = member.user
channel_id=channel_id, else:
role=member.role.id if member.role else None, user = await interface.get_user(user_id)
join_time=int(member.joined_at.timestamp()) if not user:
if member.joined_at return None
else None, return (
) UserData(
else: name=user.name or "",
return UserData( card=member.nick,
name=user.name or "", user_id=user.id,
user_id=user.id, group_id=group_id,
group_id=group_id, channel_id=channel_id,
channel_id=channel_id, role=member.role.id if member.role else None,
) join_time=(
return None int(member.joined_at.timestamp()) if member.joined_at else None
),
)
if member
else UserData(
name=user.name or "",
user_id=user.id,
group_id=group_id,
channel_id=channel_id,
)
)
@classmethod @classmethod
async def get_user_avatar( async def get_user_avatar(
@ -343,6 +345,23 @@ class PlatformUtils:
return "qq" if platform.startswith("qq") else platform return "qq" if platform.startswith("qq") else platform
return "unknown" return "unknown"
@classmethod
def is_forward_merge_supported(cls, t: Bot | Uninfo) -> bool:
"""是否支持转发消息
参数:
t: bot | Uninfo
返回:
bool: 是否支持转发消息
"""
if not isinstance(t, Bot):
return t.basic["scope"] == SupportScope.qq_client
if interface := get_interface(t):
info = interface.basic_info()
return info["scope"] == SupportScope.qq_client
return False
@classmethod @classmethod
async def get_group_list( async def get_group_list(
cls, bot: Bot, only_group: bool = False cls, bot: Bot, only_group: bool = False
@ -539,6 +558,7 @@ async def broadcast_group(
target, _bot target, _bot
) )
logger.debug("发送成功", log_cmd, target=key) logger.debug("发送成功", log_cmd, target=key)
await asyncio.sleep(random.randint(1, 3))
else: else:
logger.warning("target为空", log_cmd, target=key) logger.warning("target为空", log_cmd, target=key)
except Exception as e: except Exception as e: