Compare commits

...
10 Commits
Author SHA1 Message Date
HibiKier 14d1512b1e update v0.1.4.4 2022-03-18 20:55:05 +08:00
HibiKier 3f533516af Update README.md 2022-03-07 20:46:48 +08:00
HibiKier f1354308fd Update set_admin_permissions.py 2022-03-07 20:46:13 +08:00
HibiKier c06248e46b Update README.md 2022-03-06 18:00:58 +08:00
HibiKier 9c8eaed938 Update pid_search.py 2022-03-06 18:00:35 +08:00
HibiKier 2081302e32 Update README.md 2022-03-06 17:04:34 +08:00
HibiKier 678fc19f2d Update __init__.py 2022-03-06 17:02:59 +08:00
HibiKier adc2757e8e Merge pull request #128 from Sakuracio/main
去除背景图上的(白点?
2022-03-03 21:18:43 +08:00
Sakuracio 82a1261371 去除背景图上的(白点? 2022-03-03 00:38:54 +08:00
HibiKier 067da9dc57 update 0.1.4.3 2022-03-03 00:18:59 +08:00
20 changed files with 270 additions and 65 deletions
-1
View File
@@ -142,7 +142,6 @@ test.py
server_ip.py server_ip.py
member_activity_handle.py member_activity_handle.py
Yu-Gi-Oh/ Yu-Gi-Oh/
search_image/
black_word/ black_word/
csgo/ csgo/
fantasy_card/ fantasy_card/
+18 -1
View File
@@ -236,6 +236,24 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
## 更新 ## 更新
### 2022/3/18 \[v0.1.4.4]
* 修复戳一戳无法功能关闭与ban禁用
* 新增图片搜索 search_image
### 2022/3/7
* 优化增删权限插件
### 2022/3/6
* 修复树脂提醒无法开启
* 修复p搜图片路径错误
### 2022/3/3 \[v0.1.4.3]
* 修复手动同意群聊请求依旧退出
### 2022/3/1 \[v0.1.4.2] ### 2022/3/1 \[v0.1.4.2]
* 0.1.4内容 * 0.1.4内容
@@ -288,7 +306,6 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
* 适配nonebot.beta2 * 适配nonebot.beta2
* 删除图片搜索 nonebot_plugin_picsearcher * 删除图片搜索 nonebot_plugin_picsearcher
* 新增图片搜索 search_image
* 替换cos api * 替换cos api
* 原神签到树脂提醒新增绑定群里,在某群绑定uid就会在某群发送提醒信息(有好友则私聊,需要重新绑定uid * 原神签到树脂提醒新增绑定群里,在某群绑定uid就会在某群发送提醒信息(有好友则私聊,需要重新绑定uid
* 修改update_info.json * 修改update_info.json
+1 -1
View File
@@ -1 +1 @@
__version__: v0.1.4.2 __version__: v0.1.4.4
+4
View File
@@ -2,6 +2,10 @@ from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent
from utils.manager import plugins2block_manager, StaticData from utils.manager import plugins2block_manager, StaticData
import time import time
ignore_rst_module = ["ai", "poke", "dialogue"]
other_limit_plugins = ["poke"]
class StatusMessageManager(StaticData): class StatusMessageManager(StaticData):
+10 -9
View File
@@ -13,7 +13,12 @@ from utils.manager import (
plugins2block_manager, plugins2block_manager,
plugins2count_manager, plugins2count_manager,
) )
from ._utils import set_block_limit_false, status_message_manager from ._utils import (
set_block_limit_false,
status_message_manager,
ignore_rst_module,
other_limit_plugins,
)
from nonebot.typing import T_State from nonebot.typing import T_State
from typing import Optional from typing import Optional
from nonebot.adapters.onebot.v11 import ( from nonebot.adapters.onebot.v11 import (
@@ -37,12 +42,10 @@ _flmt_g = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
_flmt_s = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD")) _flmt_s = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
_flmt_c = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD")) _flmt_c = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
ignore_rst_module = ["ai", "poke", "dialogue"]
# 权限检测 # 权限检测
@run_preprocessor @run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State):
module = matcher.plugin_name module = matcher.plugin_name
plugins2info_dict = plugins2settings_manager.get_data() plugins2info_dict = plugins2settings_manager.get_data()
# 功能的金币检测 ####################################### # 功能的金币检测 #######################################
@@ -64,7 +67,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
await BagUser.spend_gold(event.user_id, event.group_id, cost_gold) await BagUser.spend_gold(event.user_id, event.group_id, cost_gold)
try: try:
if ( if (
(not isinstance(event, MessageEvent) and module != "poke") (not isinstance(event, MessageEvent) and module not in other_limit_plugins)
or await BanUser.is_ban(event.user_id) or await BanUser.is_ban(event.user_id)
and str(event.user_id) not in bot.config.superusers and str(event.user_id) not in bot.config.superusers
) or ( ) or (
@@ -88,7 +91,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
except AttributeError: except AttributeError:
pass pass
# 群黑名单检测 群总开关检测 # 群黑名单检测 群总开关检测
if isinstance(event, GroupMessageEvent) or matcher.plugin_name == "poke": if isinstance(event, GroupMessageEvent) or matcher.plugin_name == other_limit_plugins:
try: try:
if ( if (
group_manager.get_group_level(event.group_id) < 0 group_manager.get_group_level(event.group_id) < 0
@@ -145,9 +148,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
raise IgnoredException("权限不足") raise IgnoredException("权限不足")
if module in plugins2info_dict.keys() and matcher.priority not in [1, 9]: if module in plugins2info_dict.keys() and matcher.priority not in [1, 9]:
# 戳一戳单独判断 # 戳一戳单独判断
if isinstance(event, GroupMessageEvent) or ( if isinstance(event, GroupMessageEvent) or isinstance(event, PokeNotifyEvent) or matcher.plugin_name in other_limit_plugins:
isinstance(event, PokeNotifyEvent) and event.group_id
):
if status_message_manager.get(event.group_id) is None: if status_message_manager.get(event.group_id) is None:
status_message_manager.delete(event.group_id) status_message_manager.delete(event.group_id)
if plugins2info_dict[module]["level"] > group_manager.get_group_level( if plugins2info_dict[module]["level"] > group_manager.get_group_level(
+22 -14
View File
@@ -4,13 +4,16 @@ from nonebot.adapters.onebot.v11.exception import ActionFailed
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.onebot.v11 import ( from nonebot.adapters.onebot.v11 import (
Bot, Bot,
Event,
MessageEvent, MessageEvent,
PokeNotifyEvent,
GroupMessageEvent, GroupMessageEvent,
) )
from configs.config import Config from configs.config import Config
from models.ban_user import BanUser from models.ban_user import BanUser
from utils.utils import is_number, static_flmt, FreqLimiter from utils.utils import is_number, static_flmt, FreqLimiter
from utils.message_builder import at from utils.message_builder import at
from ._utils import ignore_rst_module, other_limit_plugins
Config.add_plugin_config( Config.add_plugin_config(
@@ -25,18 +28,19 @@ _flmt = FreqLimiter(300)
# 检查是否被ban # 检查是否被ban
@run_preprocessor @run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State):
try: if (
if ( (isinstance(event, MessageEvent) or isinstance(event, PokeNotifyEvent))
await BanUser.is_super_ban(event.user_id) and matcher.priority not in [1, 9]
and str(event.user_id) not in bot.config.superusers ) or matcher.plugin_name in other_limit_plugins:
): try:
raise IgnoredException("用户处于超级黑名单中") if (
except AttributeError: await BanUser.is_super_ban(event.user_id)
pass and str(event.user_id) not in bot.config.superusers
if not isinstance(event, MessageEvent): ):
return raise IgnoredException("用户处于超级黑名单中")
if matcher.type == "message" and matcher.priority not in [1, 9]: except AttributeError:
pass
if ( if (
await BanUser.is_ban(event.user_id) await BanUser.is_ban(event.user_id)
and str(event.user_id) not in bot.config.superusers and str(event.user_id) not in bot.config.superusers
@@ -57,7 +61,11 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
if matcher.priority != 9: if matcher.priority != 9:
try: try:
ban_result = Config.get_config("hook", "BAN_RESULT") ban_result = Config.get_config("hook", "BAN_RESULT")
if ban_result and _flmt.check(event.user_id): if (
ban_result
and _flmt.check(event.user_id)
and matcher.plugin_name not in ignore_rst_module
):
_flmt.start_cd(event.user_id) _flmt.start_cd(event.user_id)
await bot.send_group_msg( await bot.send_group_msg(
group_id=event.group_id, group_id=event.group_id,
@@ -74,7 +82,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
if matcher.priority != 9: if matcher.priority != 9:
try: try:
ban_result = Config.get_config("hook", "BAN_RESULT") ban_result = Config.get_config("hook", "BAN_RESULT")
if ban_result: if ban_result and matcher.plugin_name not in ignore_rst_module:
await bot.send_private_msg( await bot.send_private_msg(
user_id=event.user_id, user_id=event.user_id,
message=at(event.user_id) message=at(event.user_id)
+12 -2
View File
@@ -14,10 +14,20 @@ async def handle_api_call(bot: Bot, api: str, data: Dict[str, Any]):
or api == "send_group_msg" or api == "send_group_msg"
) )
and ( and (
(r := re.search("^\[\[_task\|(.*)]]", str(data["message"]["text"]).strip())) (
r := re.search(
"^\[\[_task\|(.*)]]",
data["message"].strip()
if isinstance(data["message"], str)
else str(data["message"]["text"]).strip(),
)
)
or ( or (
r := re.search( r := re.search(
"^&#91;&#91;_task\|(.*)&#93;&#93;", str(data["message"]["text"]).strip() "^&#91;&#91;_task\|(.*)&#93;&#93;",
data["message"].strip()
if isinstance(data["message"], str)
else str(data["message"]["text"]).strip(),
) )
) )
) )
+2 -1
View File
@@ -102,7 +102,7 @@ async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandAr
if is_number(id_): if is_number(id_):
id_ = int(id_) id_ = int(id_)
if cmd[:2] == "同意": if cmd[:2] == "同意":
rid = await requests_manager.approve(bot, id_, "group") rid = requests_manager.get_group_id(id_)
if rid: if rid:
await friend_handle.send("同意群聊请求成功..") await friend_handle.send("同意群聊请求成功..")
if await GroupInfo.get_group_info(rid): if await GroupInfo.get_group_info(rid):
@@ -116,6 +116,7 @@ async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandAr
group_info["member_count"], group_info["member_count"],
1 1
) )
await requests_manager.approve(bot, id_, "group")
else: else:
await friend_handle.send("同意群聊请求失败,可能是未找到此id的请求..") await friend_handle.send("同意群聊请求失败,可能是未找到此id的请求..")
else: else:
@@ -1,7 +1,7 @@
from nonebot import on_command from nonebot import on_command
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from models.level_user import LevelUser from models.level_user import LevelUser
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message, GroupMessageEvent
from utils.utils import get_message_at, is_number from utils.utils import get_message_at, is_number
from services.log import logger from services.log import logger
from utils.message_builder import at from utils.message_builder import at
@@ -37,41 +37,49 @@ super_cmd = on_command(
@super_cmd.handle() @super_cmd.handle()
async def _(bot: Bot, event: GroupMessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()): async def _(
cmd = cmd[0] bot: Bot,
group_id = -1 event: MessageEvent,
level = 0 cmd: Tuple[str, ...] = Command(),
arg: Message = CommandArg(),
):
group_id = event.group_id if isinstance(event, GroupMessageEvent) else -1
level = None
args = arg.extract_plain_text().strip().split()
qq = get_message_at(event.json())
flag = 2
try: try:
args = arg.extract_plain_text().strip().split() if qq:
qq = get_message_at(event.json()) qq = qq[0]
flag = -1 if cmd[0][:2] == "添加" and args and is_number(args[0]):
if not qq: level = int(args[0])
if len(args) > 2: else:
if is_number(args[0]) and is_number(args[1]) and is_number(args[2]): if cmd[0][:2] == "添加":
if (
len(args) > 2
and is_number(args[0])
and is_number(args[1])
and is_number(args[2])
):
qq = int(args[0]) qq = int(args[0])
group_id = int(args[1]) group_id = int(args[1])
level = int(args[2]) level = int(args[2])
flag = 1
else:
await super_cmd.finish("所有参数必须是数字!", at_sender=True)
else: else:
await super_cmd.finish( if len(args) > 1 and is_number(args[0]) and is_number(args[1]):
"权限参数不完全\n\t格式:添加/删除权限 [at] [level]" qq = int(args[0])
"\n\t格式:添加/删除权限 [qq] [group_id] [level]", group_id = int(args[1])
at_sender=True, flag = 1
) level = -1 if cmd[0][:2] == "删除" else level
else: if group_id == -1 or not level or not qq:
if not is_number(args[0]): raise IndexError()
await super_cmd.finish("所有参数必须是数字!", at_sender=True) except IndexError:
level = int(args[0]) await super_cmd.finish(__plugin_usage__)
qq = qq[0] try:
group_id = event.group_id if cmd[0][:2] == "添加":
flag = 2
if cmd[:2] == "添加":
if await LevelUser.set_level(qq, group_id, level, 1): if await LevelUser.set_level(qq, group_id, level, 1):
result = "添加管理成功, 权限: " + str(level) result = f"添加管理成功, 权限: {level}"
else: else:
result = "管理已存在, 更新权限: " + str(level) result = f"管理已存在, 更新权限: {level}"
else: else:
if await LevelUser.delete_level(qq, event.group_id): if await LevelUser.delete_level(qq, event.group_id):
result = "删除管理成功!" result = "删除管理成功!"
@@ -82,7 +90,10 @@ async def _(bot: Bot, event: GroupMessageEvent, cmd: Tuple[str, ...] = Command()
elif flag == 1: elif flag == 1:
await bot.send_group_msg( await bot.send_group_msg(
group_id=group_id, group_id=group_id,
message=Message(f"{at(qq)}管理员修改了你的权限" f"\n--------\n你当前的权限等级:{level}"), message=Message(
f"{at(qq)}管理员修改了你的权限"
f"\n--------\n你当前的权限等级:{level if level != -1 else 0}"
),
) )
await super_cmd.send("修改成功") await super_cmd.send("修改成功")
except Exception as e: except Exception as e:
+1 -1
View File
@@ -132,4 +132,4 @@ async def get_fudu_img_hash(url, group_id):
logger.warning(f"复读下载图片失败...") logger.warning(f"复读下载图片失败...")
except Exception as e: except Exception as e:
logger.warning(f"复读读取图片Hash出错 {type(e)}:{e}") logger.warning(f"复读读取图片Hash出错 {type(e)}:{e}")
return "" return ""
@@ -254,6 +254,7 @@ class Genshin(db.Model):
query = cls.query.where(cls.today_query_uid.contains(str(uid))) query = cls.query.where(cls.today_query_uid.contains(str(uid)))
x = await query.gino.first() x = await query.gino.first()
if x: if x:
await cls._add_query_uid(uid, uid)
return x.cookie return x.cookie
for u in [ for u in [
x for x in await cls.query.order_by(db.func.random()).gino.all() if x.cookie x for x in await cls.query.order_by(db.func.random()).gino.all() if x.cookie
@@ -356,7 +357,7 @@ class Genshin(db.Model):
""" """
query = cls.query.where(cls.uid == cookie_uid).with_for_update() query = cls.query.where(cls.uid == cookie_uid).with_for_update()
user = await query.gino.first() user = await query.gino.first()
await user.update(today_query_uid=cls.today_query_uid + f"{uid} ").apply() await user.update(today_query_uid=user.today_query_uid + f"{uid} ").apply()
@classmethod @classmethod
async def _get_user_data( async def _get_user_data(
@@ -55,7 +55,7 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
scheduler.remove_job(f"genshin_resin_remind_{uid}_{event.user_id}") scheduler.remove_job(f"genshin_resin_remind_{uid}_{event.user_id}")
except JobLookupError: except JobLookupError:
pass pass
if cmd == "开": if cmd[0] == "开":
await Genshin.set_resin_remind(uid, True) await Genshin.set_resin_remind(uid, True)
add_job(event.user_id, uid) add_job(event.user_id, uid)
logger.info( logger.info(
@@ -5,6 +5,7 @@ from apscheduler.jobstores.base import ConflictingIdError
from nonebot import Driver from nonebot import Driver
from .._models import Genshin from .._models import Genshin
from datetime import datetime, timedelta from datetime import datetime, timedelta
from apscheduler.jobstores.base import JobLookupError
from services.log import logger from services.log import logger
from nonebot.plugin import require from nonebot.plugin import require
from configs.config import Config from configs.config import Config
@@ -108,6 +109,11 @@ async def _():
def add_job(user_id: int, uid: int): def add_job(user_id: int, uid: int):
# 移除
try:
scheduler.remove_job(f"genshin_resin_remind_{uid}_{user_id}")
except JobLookupError:
pass
date = datetime.now(pytz.timezone("Asia/Shanghai")) + timedelta(seconds=30) date = datetime.now(pytz.timezone("Asia/Shanghai")) + timedelta(seconds=30)
try: try:
scheduler.add_job( scheduler.add_job(
+1 -1
View File
@@ -84,7 +84,7 @@ async def _(event: MessageEvent, state: T_State, pid: str = Arg("pid")):
f"pid:{pid}\n" f"pid:{pid}\n"
f"author:{author}\n" f"author:{author}\n"
f"author_id:{author_id}\n" f"author_id:{author_id}\n"
f'{image(f"pid_search_{event.user_id}.png", "temp")}' f'{image(TEMP_PATH / f"pid_search_{event.user_id}.png")}'
f"{tmp}" f"{tmp}"
) )
) )
+91
View File
@@ -0,0 +1,91 @@
from nonebot.plugin import on_command
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, Message
from nonebot.typing import T_State
from services.log import logger
from utils.utils import get_message_img
from utils.message_builder import custom_forward_msg
from nonebot.params import CommandArg, Arg, ArgStr, Depends
from .saucenao import get_saucenao_image
__zx_plugin_name__ = "识图"
__plugin_usage__ = """
usage:
识别图片 [二次元图片]
指令:
识图 [图片]
""".strip()
__plugin_des__ = "以图搜图,看破本源"
__plugin_cmd__ = ["识图"]
__plugin_type__ = ("一些工具",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["识图"],
}
__plugin_configs__ = {
"MAX_FIND_IMAGE_COUNT": {"value": 3, "help": "识图返回的最大结果数", "default_value": 3},
"API_KEY": {
"value": None,
"help": "Saucenao的API_KEY,通过 https://saucenao.com/user.php?page=search-api 注册获取",
},
}
search_image = on_command("识图", block=True, priority=5)
async def get_image_info(mod: str, url: str):
if mod == "saucenao":
return await get_saucenao_image(url)
def parse_image(key: str):
async def _key_parser(
state: T_State, img: Message = Arg(key)
):
if not get_message_img(img):
await search_image.reject_arg(key, "请发送要识别的图片!")
state[key] = img
return _key_parser
@search_image.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State, arg: Message = CommandArg()):
msg = arg.extract_plain_text().strip()
if msg:
state["mod"] = msg
else:
state["mod"] = "saucenao"
if get_message_img(event.json()):
state["img"] = event.message
@search_image.got("img", prompt="图来!", parameterless=[Depends(parse_image("img"))])
async def _(
bot: Bot,
event: MessageEvent,
state: T_State,
mod: str = ArgStr("mod"),
img: Message = Arg("img"),
):
img = get_message_img(img)[0]
await search_image.send("开始处理图片...")
msg = await get_image_info(mod, img)
if isinstance(msg, str):
await search_image.finish(msg, at_sender=True)
if isinstance(event, GroupMessageEvent):
await bot.send_group_forward_msg(
group_id=event.group_id, messages=custom_forward_msg(msg, bot.self_id)
)
else:
for m in msg[1:]:
await search_image.send(m)
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 识图:" + img
)
+50
View File
@@ -0,0 +1,50 @@
from utils.http_utils import AsyncHttpx
from configs.config import Config
from configs.path_config import TEMP_PATH
from utils.message_builder import image
from typing import Union, List
import random
API_URL_SAUCENAO = "https://saucenao.com/search.php"
API_URL_ASCII2D = "https://ascii2d.net/search/url/"
API_URL_IQDB = "https://iqdb.org/"
async def get_saucenao_image(url: str) -> Union[str, List[str]]:
api_key = Config.get_config("search_image", "API_KEY")
if not api_key:
return "Saucenao 缺失API_KEY!"
params = {
"output_type": 2,
"api_key": api_key,
"testmode": 1,
"numres": 6,
"db": 999,
"url": url,
}
data = (await AsyncHttpx.post(API_URL_SAUCENAO, params=params)).json()
if data["header"]["status"] != 0:
return "Saucenao识图失败.."
data = data["results"]
data = (
data
if len(data) < Config.get_config("search_image", "MAX_FIND_IMAGE_COUNT")
else data[: Config.get_config("search_image", "MAX_FIND_IMAGE_COUNT")]
)
msg_list = []
index = random.randint(0, 10000)
if await AsyncHttpx.download_file(
url, TEMP_PATH / f"saucenao_search_{index}.jpg"
):
msg_list.append(image(TEMP_PATH / f"saucenao_search_{index}.jpg"))
for info in data:
similarity = info["header"]["similarity"]
tmp = f"相似度:{similarity}%\n"
for x in info["data"].keys():
if x != "ext_urls":
tmp += f"{x}:{info['data'][x]}\n"
if "source" not in info["data"].keys():
tmp += f'source:{info["data"]["ext_urls"][0]}\n'
msg_list.append(tmp[:-1])
return msg_list
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 88 KiB

+1 -2
View File
@@ -8,8 +8,7 @@
"configs/path_config.py", "configs/path_config.py",
"configs/utils", "configs/utils",
"poetry.lock", "poetry.lock",
"pyproject.toml", "pyproject.toml"
"resources/font"
], ],
"add_file": [], "add_file": [],
"delete_file": [] "delete_file": []
+7
View File
@@ -75,6 +75,13 @@ class RequestManager(StaticData):
break break
self.save() self.save()
def get_group_id(self, id_: int) -> Optional[int]:
"""
通过id获取群号
:param id_: id
"""
return self._data["group"].get(id_)
async def approve(self, bot: Bot, id_: int, type_: str) -> Optional[int]: async def approve(self, bot: Bot, id_: int, type_: str) -> Optional[int]:
""" """
同意请求 同意请求