all Update to v1.4.8

This commit is contained in:
xtaodada 2024-02-04 15:56:06 +08:00
parent 0d7b581d91
commit cdca0354ae
Signed by: xtaodada
GPG Key ID: 4CBB3F4FA8C85659
31 changed files with 258 additions and 226 deletions

View File

@ -260,4 +260,4 @@ async def AutoSendReactions(message: Message):
return False return False
## ⬆️ 不懂勿动 ⬆️ ## ⬆️ 不懂勿动 ⬆️

View File

@ -43,9 +43,9 @@ async def get_hitokoto(request: AsyncClient):
try: try:
htk = (await request.get("https://v1.hitokoto.cn/?charset=utf-8")).json() htk = (await request.get("https://v1.hitokoto.cn/?charset=utf-8")).json()
text = f"\"{htk['hitokoto']}\" —— " text = f"\"{htk['hitokoto']}\" —— "
if htk['from_who']: if htk["from_who"]:
text += f"{htk['from_who']}" text += f"{htk['from_who']}"
if htk['from']: if htk["from"]:
text += f"{htk['from']}" text += f"{htk['from']}"
except Exception: except Exception:
text = '"用代码表达言语的魅力,用代码书写山河的壮丽。" —— 一言「一言开发者中心」' text = '"用代码表达言语的魅力,用代码书写山河的壮丽。" —— 一言「一言开发者中心」'

View File

@ -24,7 +24,7 @@ async def at_admins(client: Client, message: Message):
await client.send_message( await client.send_message(
message.chat.id, message.chat.id,
"%s\n\n%s" % (say, send_list), "%s\n\n%s" % (say, send_list),
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()

View File

@ -23,7 +23,8 @@ async def audio_to_voice(bot: Client, message: Message):
audio, audio,
reply_to_message_id=message.id reply_to_message_id=message.id
if message.audio if message.audio
else (message.reply_to_message_id or message.reply_to_top_message_id), else message.reply_to_message_id,
message_thread_id=message.message_thread_id,
) )
except Exception as e: except Exception as e:
await message.edit(f"转换为语音消息失败:{e}") await message.edit(f"转换为语音消息失败:{e}")

View File

@ -40,14 +40,14 @@ async def bingwall(message: Message):
filename, filename,
caption=f"#bing wallpaper\n" f"{str(copy_right)}", caption=f"#bing wallpaper\n" f"{str(copy_right)}",
quote=False, quote=False,
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
else: else:
await message.reply_photo( await message.reply_photo(
filename, filename,
caption=f"#bing wallpaper\n" f"{str(copy_right)}", caption=f"#bing wallpaper\n" f"{str(copy_right)}",
quote=False, quote=False,
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
status = True status = True
break # 成功了就赶紧结束啦! break # 成功了就赶紧结束啦!

View File

@ -79,7 +79,7 @@ async def chat_transfer(message: Message):
"chats.csv", "chats.csv",
caption=f"对话导出文件,成功导出了 {num} 个群组/频道", caption=f"对话导出文件,成功导出了 {num} 个群组/频道",
thumb=f"pagermaid{sep}assets{sep}logo.jpg", thumb=f"pagermaid{sep}assets{sep}logo.jpg",
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
safe_remove("chats.csv") safe_remove("chats.csv")
await message.safe_delete() await message.safe_delete()

View File

@ -487,7 +487,7 @@ async def eat(client_: Client, context: Message):
await client_.send_document( await client_.send_document(
context.chat.id, context.chat.id,
f"plugins{sep}eat{sep}eat.webp", f"plugins{sep}eat{sep}eat.webp",
reply_to_message_id=context.reply_to_top_message_id, message_thread_id=context.message_thread_id,
) )
await final_msg.safe_delete() await final_msg.safe_delete()
except TypeError: except TypeError:

View File

@ -115,7 +115,7 @@ async def emoji_transfer(message: Message):
"emojis.csv", "emojis.csv",
caption=f"Emoji 包导出文件,成功导出了 {num} 个 Emoji 包", caption=f"Emoji 包导出文件,成功导出了 {num} 个 Emoji 包",
thumb=f"pagermaid{sep}assets{sep}logo.jpg", thumb=f"pagermaid{sep}assets{sep}logo.jpg",
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
safe_remove("emojis.csv") safe_remove("emojis.csv")
await message.safe_delete() await message.safe_delete()

View File

@ -120,13 +120,13 @@ async def epic(message: Message):
"epic.jpg", "epic.jpg",
caption=msg, caption=msg,
quote=False, quote=False,
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
except Exception: except Exception:
await message.reply( await message.reply(
msg, msg,
quote=False, quote=False,
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
safe_remove("epic.jpg") safe_remove("epic.jpg")
else: else:

View File

@ -85,8 +85,8 @@ async def upload_sticker(bot: Client, message: Message, sticker_set: StickerSet)
message.chat.id, message.chat.id,
f"{directory_name}.zip", f"{directory_name}.zip",
caption=sticker_set.set.short_name, caption=sticker_set.set.short_name,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
safe_remove(f"{directory_name}.zip") safe_remove(f"{directory_name}.zip")
shutil.rmtree(directory_name) shutil.rmtree(directory_name)

View File

@ -20,10 +20,9 @@ async def httpcat(client: Client, message: Message, request: AsyncClient):
await client.send_photo( await client.send_photo(
message.chat.id, message.chat.id,
io, io,
reply_to_message_id=( reply_to_message_id=message.reply_to_message_id
message.reply_to_message_id or message.reply_to_top_message_id
)
if message.outgoing if message.outgoing
else message.id, else message.id,
message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()

View File

@ -133,7 +133,7 @@ async def jikipedia(message: Message):
image, image,
quote=False, quote=False,
caption=text, caption=text,
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()
except Exception: except Exception:

View File

@ -17,8 +17,8 @@ async def ju_pai(message: Message):
await message.reply_photo( await message.reply_photo(
image_url, image_url,
quote=False, quote=False,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()
except Exception as e: except Exception as e:

View File

@ -161,10 +161,13 @@ class KeywordTask:
async def process_keyword(self, message: Message): async def process_keyword(self, message: Message):
msg = None msg = None
text = self.replace_reply(message) text = self.replace_reply(message)
reply_id = message.id if self.reply else message.reply_to_top_message_id reply_id = message.id if self.reply else None
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
msg = await message.reply( msg = await message.reply(
text, parse_mode=ParseMode.HTML, reply_to_message_id=reply_id text,
parse_mode=ParseMode.HTML,
reply_to_message_id=reply_id,
message_thread_id=message.message_thread_id,
) )
if self.delete: if self.delete:
if self.source_delay_delete > 0: if self.source_delay_delete > 0:
@ -236,10 +239,17 @@ class KeywordTask:
if len(data) > 4: if len(data) > 4:
self.delay_delete = int(data[4]) self.delay_delete = int(data[4])
if len(data) > 5: # assuming the source_delay_delete is the 6th part of the task format if (
len(data) > 5
): # assuming the source_delay_delete is the 6th part of the task format
self.source_delay_delete = int(data[5]) self.source_delay_delete = int(data[5])
if self.ban < 0 or self.restrict < 0 or self.delay_delete < 0 or self.source_delay_delete < 0: if (
self.ban < 0
or self.restrict < 0
or self.delay_delete < 0
or self.source_delay_delete < 0
):
raise ValueError("Invalid task format") raise ValueError("Invalid task format")

View File

@ -43,8 +43,8 @@ async def netease_search(keyword: str, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()
@ -57,8 +57,8 @@ async def netease_url(url: str, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()
@ -71,8 +71,8 @@ async def netease_id(music_id: str, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()

View File

@ -51,8 +51,6 @@ async def set_read_mentions(client: Client, message: Message):
await client.invoke( await client.invoke(
ReadMentions( ReadMentions(
peer=await client.resolve_peer(message.chat.id), peer=await client.resolve_peer(message.chat.id),
top_msg_id=message.reply_to_top_message_id top_msg_id=message.message_thread_id if message.topic else None,
if message.chat.is_forum
else None,
) )
) )

View File

@ -285,14 +285,14 @@ async def send_illust(message: Message, illust: Illust) -> None:
illust.image_urls["large"], illust.image_urls["large"],
caption=caption, caption=caption,
quote=False, quote=False,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
else: else:
await message.reply_text( await message.reply_text(
caption, caption,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )

View File

@ -72,7 +72,7 @@ def get_version():
from json import load from json import load
with open( with open(
f"{working_dir}{sep}plugins{sep}version.json", "r", encoding="utf-8" f"{working_dir}{sep}plugins{sep}version.json", "r", encoding="utf-8"
) as f: ) as f:
version_json = load(f) version_json = load(f)
return version_json.get(cmd_name, "unknown") return version_json.get(cmd_name, "unknown")
@ -290,7 +290,7 @@ class Command:
cmd_args = self.msg.parameter[1:args_len] cmd_args = self.msg.parameter[1:args_len]
func_args = [] func_args = []
for index, arg_type in enumerate( for index, arg_type in enumerate(
tuple(full_arg_spec.annotations.values()) tuple(full_arg_spec.annotations.values())
): # Check arg type ): # Check arg type
if args_len is None: if args_len is None:
func_args = cmd_args func_args = cmd_args
@ -299,14 +299,14 @@ class Command:
if getattr(arg_type, "__origin__", None) == Union: if getattr(arg_type, "__origin__", None) == Union:
NoneType = type(None) NoneType = type(None)
if ( if (
len(arg_type.__args__) != 2 len(arg_type.__args__) != 2
or arg_type.__args__[1] is not NoneType or arg_type.__args__[1] is not NoneType
): ):
continue continue
if ( if (
len(cmd_args) - 1 > index len(cmd_args) - 1 > index
and not cmd_args[index] and not cmd_args[index]
or len(cmd_args) - 1 < index or len(cmd_args) - 1 < index
): ):
func_args.append(None) func_args.append(None)
continue continue
@ -403,17 +403,17 @@ class Command:
if name.startswith("_"): if name.startswith("_"):
continue continue
if ( if (
result := re.search(self.alias_rgx, func.__doc__ or "") result := re.search(self.alias_rgx, func.__doc__ or "")
) and alias_name in result[1].replace(" ", "").split(","): ) and alias_name in result[1].replace(" ", "").split(","):
return func if ret_type == "func" else name return func if ret_type == "func" else name
async def _display_value( async def _display_value(
self, self,
*, *,
key: Optional[str] = None, key: Optional[str] = None,
display_text: str, display_text: str,
sub_cmd: str, sub_cmd: str,
value_type: str, value_type: str,
): ):
text = [ text = [
display_text, display_text,
@ -427,7 +427,7 @@ class Command:
# Set On / Off Boolean # Set On / Off Boolean
async def _set_toggle(self, key: str, toggle: str, *, reverse: bool = False): async def _set_toggle(self, key: str, toggle: str, *, reverse: bool = False):
if (toggle := toggle.lower()[0]) not in ("y", "n", "t", "f", "1", "0") and ( if (toggle := toggle.lower()[0]) not in ("y", "n", "t", "f", "1", "0") and (
toggle := toggle.lower() toggle := toggle.lower()
) not in ("on", "off"): ) not in ("on", "off"):
return await self.help(key) return await self.help(key)
toggle = toggle in ("y", "t", "1", "on") toggle = toggle in ("y", "t", "1", "on")
@ -437,9 +437,9 @@ class Command:
async def _get_user_id(self, user_id: Union[str, int]) -> Optional[int]: async def _get_user_id(self, user_id: Union[str, int]) -> Optional[int]:
if ( if (
not user_id not user_id
and not self.msg.reply_to_message_id and not self.msg.reply_to_message_id
and self.msg.chat.type != ChatType.PRIVATE and self.msg.chat.type != ChatType.PRIVATE
): ):
return return
try: try:
@ -449,15 +449,15 @@ class Command:
pass pass
user = None user = None
user_id = user_id or ( user_id = user_id or (
self.msg.reply_to_message self.msg.reply_to_message
and self.msg.reply_to_message.from_user.id and self.msg.reply_to_message.from_user.id
or self.msg.chat.id or self.msg.chat.id
) )
try: try:
if ( if (
not user_id not user_id
or not (user := await bot.get_users(user_id)) or not (user := await bot.get_users(user_id))
or (user.is_bot or user.is_verified or user.is_deleted) or (user.is_bot or user.is_verified or user.is_deleted)
): ):
return return
except (ValueError, PeerIdInvalid): except (ValueError, PeerIdInvalid):
@ -591,8 +591,8 @@ class Command:
continue continue
help_msg.append( help_msg.append(
( (
code(f",{user_cmd_name} {self._get_cmd_with_param(name)}".strip()) code(f",{user_cmd_name} {self._get_cmd_with_param(name)}".strip())
+ f"\n· {re.search(r'(.+)', func.__doc__ or '')[1].strip()}\n" + f"\n· {re.search(r'(.+)', func.__doc__ or '')[1].strip()}\n"
) )
) )
await self._edit("\n".join(help_msg + footer)) await self._edit("\n".join(help_msg + footer))
@ -619,7 +619,7 @@ class Command:
if not (user_id := await self._get_user_id(_id)): if not (user_id := await self._get_user_id(_id)):
return await self._edit(lang("invalid_user_id")) return await self._edit(lang("invalid_user_id"))
if captcha := curr_captcha.get( if captcha := curr_captcha.get(
user_id user_id
): # This user is currently in challenge state ): # This user is currently in challenge state
await captcha.action(True) await captcha.action(True)
if curr_captcha.get(user_id): if curr_captcha.get(user_id):
@ -657,12 +657,12 @@ class Command:
return await self._edit(lang("invalid_user_id")) return await self._edit(lang("invalid_user_id"))
captcha = None captcha = None
if (state := setting.get_challenge_state(user_id)) or ( if (state := setting.get_challenge_state(user_id)) or (
captcha := curr_captcha.get(user_id) captcha := curr_captcha.get(user_id)
): ):
await CaptchaTask.archive(user_id, un_archive=True) await CaptchaTask.archive(user_id, un_archive=True)
try: try:
( (
captcha and captcha.type or state.get("type", "math") captcha and captcha.type or state.get("type", "math")
) == "img" and await bot.unblock_user(user_id) ) == "img" and await bot.unblock_user(user_id)
except Exception as e: except Exception as e:
console.error( console.error(
@ -744,7 +744,7 @@ class Command:
if seconds is None: if seconds is None:
return await self._display_value( return await self._display_value(
display_text=lang("timeout_curr_rule") display_text=lang("timeout_curr_rule")
% int(setting.get(key_name, default_timeout_time)), % int(setting.get(key_name, default_timeout_time)),
sub_cmd="wait", sub_cmd="wait",
value_type="vocab_int", value_type="vocab_int",
) )
@ -767,7 +767,7 @@ class Command:
if not toggle: if not toggle:
return await self._display_value( return await self._display_value(
display_text=lang("disable_pm_curr_rule") display_text=lang("disable_pm_curr_rule")
% lang("enabled" if setting.get("disable") else "disabled"), % lang("enabled" if setting.get("disable") else "disabled"),
sub_cmd="disable_pm", sub_cmd="disable_pm",
value_type="vocab_bool", value_type="vocab_bool",
) )
@ -832,7 +832,7 @@ class Command:
if not toggle: if not toggle:
return await self._display_value( return await self._display_value(
display_text=lang("report_curr_rule") display_text=lang("report_curr_rule")
% lang("enabled" if setting.get("report", True) else "disabled"), % lang("enabled" if setting.get("report", True) else "disabled"),
sub_cmd="report", sub_cmd="report",
value_type="vocab_bool", value_type="vocab_bool",
) )
@ -920,7 +920,7 @@ class Command:
if not toggle: if not toggle:
return await self._display_value( return await self._display_value(
display_text=lang("initiative_curr_rule") display_text=lang("initiative_curr_rule")
% lang("enabled" if setting.get("initiative", True) else "disabled"), % lang("enabled" if setting.get("initiative", True) else "disabled"),
sub_cmd="initiative", sub_cmd="initiative",
value_type="vocab_bool", value_type="vocab_bool",
) )
@ -937,7 +937,7 @@ class Command:
if not toggle: if not toggle:
return await self._display_value( return await self._display_value(
display_text=lang("silent_curr_rule") display_text=lang("silent_curr_rule")
% lang("enabled" if setting.get("silent") else "disabled"), % lang("enabled" if setting.get("silent") else "disabled"),
sub_cmd="quiet", sub_cmd="quiet",
value_type="vocab_bool", value_type="vocab_bool",
) )
@ -992,7 +992,7 @@ class Command:
if not toggle: if not toggle:
return await self._display_value( return await self._display_value(
display_text=lang("flood_username_curr_rule") display_text=lang("flood_username_curr_rule")
% lang("enabled" if setting.get("flood_username") else "disabled"), % lang("enabled" if setting.get("flood_username") else "disabled"),
sub_cmd="flood_username", sub_cmd="flood_username",
value_type="vocab_bool", value_type="vocab_bool",
) )
@ -1016,7 +1016,7 @@ class Command:
if not action: if not action:
return await self._display_value( return await self._display_value(
display_text=lang("flood_act_curr_rule") display_text=lang("flood_act_curr_rule")
% lang(f"flood_act_set_{setting.get('flood_act', 'delete')}"), % lang(f"flood_act_set_{setting.get('flood_act', 'delete')}"),
sub_cmd="flood_act", sub_cmd="flood_act",
value_type="vocab_action", value_type="vocab_action",
) )
@ -1099,7 +1099,7 @@ class Command:
if not _type: if not _type:
return await self._display_value( return await self._display_value(
display_text=lang("type_curr_rule") display_text=lang("type_curr_rule")
% lang(f'type_captcha_{setting.get("type", "math")}'), % lang(f'type_captcha_{setting.get("type", "math")}'),
sub_cmd="typ", sub_cmd="typ",
value_type="type_param_name", value_type="type_param_name",
) )
@ -1116,26 +1116,26 @@ class Command:
settings_text = [] settings_text = []
text_none = bold(lang("none")) text_none = bold(lang("none"))
for key, default in ( for key, default in (
("whitelist", text_none), ("whitelist", text_none),
("blacklist", text_none), ("blacklist", text_none),
("timeout", 300 if setting.get("type") == "img" else 30), ("timeout", 300 if setting.get("type") == "img" else 30),
("disable_pm", bold(lang("disabled"))), ("disable_pm", bold(lang("disabled"))),
("action", bold(lang("action_ban"))), ("action", bold(lang("action_ban"))),
("report", bold(lang("enabled"))), ("report", bold(lang("enabled"))),
("premium", bold(lang("premium_set_none"))), ("premium", bold(lang("premium_set_none"))),
("groups_in_common", text_none), ("groups_in_common", text_none),
("chat_history", -1), ("chat_history", -1),
("initiative", bold(lang("enabled"))), ("initiative", bold(lang("enabled"))),
("silent", bold(lang("disabled"))), ("silent", bold(lang("disabled"))),
("flood", 5), ("flood", 5),
("flood_username", bold(lang("disabled"))), ("flood_username", bold(lang("disabled"))),
("flood_act", bold(lang("flood_act_set_delete"))), ("flood_act", bold(lang("flood_act_set_delete"))),
("collect_logs", bold(lang("enabled"))), ("collect_logs", bold(lang("enabled"))),
("type", bold(lang("type_captcha_math"))), ("type", bold(lang("type_captcha_math"))),
("img_captcha", bold(lang("img_captcha_type_func"))), ("img_captcha", bold(lang("img_captcha_type_func"))),
("img_captcha_retry", 3), ("img_captcha_retry", 3),
("custom_rule", text_none), ("custom_rule", text_none),
("welcome", text_none), ("welcome", text_none),
): ):
lang_text = lang(f"{key}_curr_rule") lang_text = lang(f"{key}_curr_rule")
# Timeout (rule: timeout, value: [multiple]) # Timeout (rule: timeout, value: [multiple])
@ -1236,7 +1236,7 @@ class Command:
if not _type: if not _type:
return await self._display_value( return await self._display_value(
display_text=lang("type_curr_rule") display_text=lang("type_curr_rule")
% lang(f'img_captcha_type_{setting.get("img_type", "func")}'), % lang(f'img_captcha_type_{setting.get("img_type", "func")}'),
sub_cmd="img_typ", sub_cmd="img_typ",
value_type="type_param_name", value_type="type_param_name",
) )
@ -1254,7 +1254,7 @@ class Command:
if number is None: if number is None:
return await self._display_value( return await self._display_value(
display_text=lang("img_captcha_retry_curr_rule") display_text=lang("img_captcha_retry_curr_rule")
% setting.get("img_max_retry", 3), % setting.get("img_max_retry", 3),
sub_cmd="img_re", sub_cmd="img_re",
value_type="vocab_int", value_type="vocab_int",
) )
@ -1325,14 +1325,14 @@ class TheOrder:
if not await exec_api(bot.block_user(user_id=target)): if not await exec_api(bot.block_user(user_id=target)):
console.debug(f"Failed to block user {target}") console.debug(f"Failed to block user {target}")
if action == "delete" and not await exec_api( if action == "delete" and not await exec_api(
bot.invoke( bot.invoke(
messages.DeleteHistory( messages.DeleteHistory(
just_clear=False, just_clear=False,
revoke=False, revoke=False,
peer=await bot.resolve_peer(target), peer=await bot.resolve_peer(target),
max_id=0, max_id=0,
)
) )
)
): ):
console.debug(f"Failed to delete user chat {target}") console.debug(f"Failed to delete user chat {target}")
setting.pending_ban_list.del_id(target) setting.pending_ban_list.del_id(target)
@ -1343,20 +1343,20 @@ class TheOrder:
chat_link = gen_link(str(target), f"tg://user?id={target}") chat_link = gen_link(str(target), f"tg://user?id={target}")
text = f"[PMCaptcha - The Order] {lang('verify_log_punished')} (Punishment)" text = f"[PMCaptcha - The Order] {lang('verify_log_punished')} (Punishment)"
( (
not skip_log not skip_log
and action not in ("none", "archive") and action not in ("none", "archive")
and await log(text % (chat_link, lang(f"action_{action}")), True) and await log(text % (chat_link, lang(f"action_{action}")), True)
) )
( (
skip_log skip_log
and console.debug( and console.debug(
text text
% ( % (
chat_link, chat_link,
lang(f'action_{action == "none" and "set_none" or action}'), lang(f'action_{action == "none" and "set_none" or action}'),
)
) )
) )
)
except asyncio.CancelledError: except asyncio.CancelledError:
break break
except Exception as e: except Exception as e:
@ -1567,7 +1567,7 @@ class TheWorldEye:
# A user is challenged less than a min # A user is challenged less than a min
self.level += 1 self.level += 1
elif ( elif (
not self.last_challenge_time or now - self.last_challenge_time > 60 not self.last_challenge_time or now - self.last_challenge_time > 60
): ):
self.level = 1 self.level = 1
self.last_challenge_time = now self.last_challenge_time = now
@ -1756,7 +1756,7 @@ class CaptchaTask:
can_report = True can_report = True
auto_archived = False auto_archived = False
if peer_settings := await exec_api( if peer_settings := await exec_api(
bot.invoke(messages.GetPeerSettings(peer=await bot.resolve_peer(user_id))) bot.invoke(messages.GetPeerSettings(peer=await bot.resolve_peer(user_id)))
): ):
can_report = peer_settings.settings.report_spam can_report = peer_settings.settings.report_spam
auto_archived = peer_settings.settings.autoarchived auto_archived = peer_settings.settings.autoarchived
@ -1774,7 +1774,7 @@ class CaptchaTask:
if can_report is None or auto_archived is None: if can_report is None or auto_archived is None:
can_report, auto_archived = await self.get_user_settings(user_id) can_report, auto_archived = await self.get_user_settings(user_id)
if ( if (
last_captcha := setting.get_challenge_state(user_id) last_captcha := setting.get_challenge_state(user_id)
) and not curr_captcha.get(user_id): ) and not curr_captcha.get(user_id):
# Resume last captcha challenge # Resume last captcha challenge
if last_captcha["type"] not in captcha_challenges: if last_captcha["type"] not in captcha_challenges:
@ -1806,19 +1806,19 @@ class CaptchaTask:
user_id and self.queue.task_done() user_id and self.queue.task_done()
async def add( async def add(
self, self,
user_id: int, user_id: int,
msg: Optional[Message], msg: Optional[Message],
can_report: Optional[bool], can_report: Optional[bool],
auto_archived: Optional[bool], auto_archived: Optional[bool],
): ):
await the_world_eye.add_synchronize(user_id) await the_world_eye.add_synchronize(user_id)
if not self.task or self.task.done(): if not self.task or self.task.done():
self.task = asyncio.create_task(self.worker()) self.task = asyncio.create_task(self.worker())
if not ( if not (
setting.pending_challenge_list.check_id(user_id) setting.pending_challenge_list.check_id(user_id)
or curr_captcha.get(user_id) or curr_captcha.get(user_id)
or setting.get_challenge_state(user_id) or setting.get_challenge_state(user_id)
): ):
setting.pending_challenge_list.add_id(user_id) setting.pending_challenge_list.add_id(user_id)
self.queue.put_nowait((user_id, msg, can_report, auto_archived)) self.queue.put_nowait((user_id, msg, can_report, auto_archived))
@ -1885,21 +1885,21 @@ class CaptchaChallenge:
self.captcha_start and caption.append(f"Start: {code(str(self.captcha_start))}") self.captcha_start and caption.append(f"Start: {code(str(self.captcha_start))}")
self.captcha_end and caption.append(f"End: {code(str(self.captcha_end))}") self.captcha_end and caption.append(f"End: {code(str(self.captcha_end))}")
( (
self.captcha_start self.captcha_start
and self.captcha_end and self.captcha_end
and caption.append( and caption.append(
f"Duration: {code(str(self.captcha_end - self.captcha_start))}s" f"Duration: {code(str(self.captcha_end - self.captcha_start))}s"
) )
) )
await exec_api(bot.archive_chats(log_collect_bot)) await exec_api(bot.archive_chats(log_collect_bot))
await exec_api(bot.unblock_user(log_collect_bot)) await exec_api(bot.unblock_user(log_collect_bot))
if not await exec_api( if not await exec_api(
bot.send_document( bot.send_document(
log_collect_bot, log_collect_bot,
log_file, log_file,
caption="\n".join(caption), caption="\n".join(caption),
parse_mode=ParseMode.HTML, parse_mode=ParseMode.HTML,
) )
): ):
return await log("Failed to send log") return await log("Failed to send log")
await log(f"Log collected from user {user.id}") await log(f"Log collected from user {user.id}")
@ -1977,11 +1977,11 @@ class CaptchaChallenge:
for challenge_msg_id in self.challenge_msg_ids: for challenge_msg_id in self.challenge_msg_ids:
await bot.delete_messages(self.user.id, challenge_msg_id) await bot.delete_messages(self.user.id, challenge_msg_id)
( (
self.can_report self.can_report
and setting.get("report", True) and setting.get("report", True)
and await bot.invoke( and await bot.invoke(
messages.ReportSpam(peer=await bot.resolve_peer(self.user.id)) messages.ReportSpam(peer=await bot.resolve_peer(self.user.id))
) )
) )
except Exception as e: except Exception as e:
console.debug( console.debug(
@ -2023,12 +2023,12 @@ class CaptchaChallenge:
def reset_timer(self, timeout: Optional[int] = None): def reset_timer(self, timeout: Optional[int] = None):
self.timer_task and self.timer_task.cancel() self.timer_task and self.timer_task.cancel()
timeout = ( timeout = (
timeout is not None timeout is not None
and timeout and timeout
or setting.get( or setting.get(
f"{self.type == 'img' and 'img_' or ''}timeout", f"{self.type == 'img' and 'img_' or ''}timeout",
self.type == "img" and 300 or 30, self.type == "img" and 300 or 30,
) )
) )
if timeout > 0: if timeout > 0:
self.timer_task = asyncio.create_task(self._challenge_timer(timeout)) self.timer_task = asyncio.create_task(self._challenge_timer(timeout))
@ -2104,7 +2104,11 @@ class MathChallenge(CaptchaChallenge):
} }
if previous_msg_id: if previous_msg_id:
params["message_id"] = previous_msg_id params["message_id"] = previous_msg_id
challenge_msg = await exec_api((bot.edit_message_text if previous_msg_id else bot.send_message)(**params)) challenge_msg = await exec_api(
(bot.edit_message_text if previous_msg_id else bot.send_message)(
**params
)
)
if not challenge_msg: if not challenge_msg:
return await log( return await log(
f"Failed to send math captcha challenge to {self.user.id}" f"Failed to send math captcha challenge to {self.user.id}"
@ -2166,12 +2170,12 @@ class ImageChallenge(CaptchaChallenge):
while True: while True:
try: try:
if ( if (
not ( not (
result := await bot.get_inline_bot_results( result := await bot.get_inline_bot_results(
img_captcha_bot, setting.get("img_type", "func") img_captcha_bot, setting.get("img_type", "func")
)
) )
or not result.results )
or not result.results
): ):
console.debug( console.debug(
f"Failed to get captcha results from {img_captcha_bot}, fallback" f"Failed to get captcha results from {img_captcha_bot}, fallback"
@ -2333,12 +2337,12 @@ class Rule:
def _precondition(self) -> bool: def _precondition(self) -> bool:
return ( return (
# Skip for PGM/PMC Developers # Skip for PGM/PMC Developers
self.user.id in (347437156, 583325201, 1148248480, 751686745, 676660002) self.user.id in (347437156, 583325201, 1148248480, 751686745, 676660002)
or self.msg.from_user.is_contact or self.msg.from_user.is_contact
or self.msg.from_user.is_verified or self.msg.from_user.is_verified
or self.msg.chat.type == ChatType.BOT or self.msg.chat.type == ChatType.BOT
or self.msg.service is not None # skip service message or self.msg.service is not None # skip service message
or setting.is_verified(self.user.id) or setting.is_verified(self.user.id)
) )
def _get_text(self) -> str: def _get_text(self) -> str:
@ -2359,12 +2363,12 @@ class Rule:
docs = func.__doc__ or "" docs = func.__doc__ or ""
try: try:
if not name.startswith("_") and ( if not name.startswith("_") and (
"outgoing" in docs "outgoing" in docs
and outgoing and outgoing
and await func() and await func()
or "outgoing" not in docs or "outgoing" not in docs
and not self.user.is_self and not self.user.is_self
and await func() and await func()
): ):
console.debug( console.debug(
f"Rule triggered: `{name}` (user: {self.user.id} chat: {self.msg.chat.id})" f"Rule triggered: `{name}` (user: {self.user.id} chat: {self.msg.chat.id})"
@ -2403,7 +2407,9 @@ class Rule:
try: try:
exec(f"async def _(msg, text, user, me, bot):\n return {custom_rule}") exec(f"async def _(msg, text, user, me, bot):\n return {custom_rule}")
return bool( return bool(
await locals()["_"](self.msg, self._get_text(), self.user, bot.me, bot) await locals()["_"](
self.msg, self._get_text(), self.user, bot.me, bot
)
) )
except Exception as e: except Exception as e:
await log( await log(
@ -2423,7 +2429,7 @@ class Rule:
if (history_count := setting.get("history_count", -1)) > 0: if (history_count := setting.get("history_count", -1)) > 0:
count = 0 count = 0
async for msg in bot.get_chat_history( async for msg in bot.get_chat_history(
self.user.id, limit=history_count + 1 self.user.id, limit=history_count + 1
): ):
if msg.id != self.msg.id: if msg.id != self.msg.id:
count += 1 count += 1
@ -2437,7 +2443,7 @@ class Rule:
if (common_groups := setting.get("groups_in_common")) is not None: if (common_groups := setting.get("groups_in_common")) is not None:
if user_full := await exec_api( if user_full := await exec_api(
bot.invoke(GetFullUser(id=await bot.resolve_peer(self.user.id))) bot.invoke(GetFullUser(id=await bot.resolve_peer(self.user.id)))
): ):
if user_full.full_user.common_chats_count >= common_groups: if user_full.full_user.common_chats_count >= common_groups:
setting.whitelist.add_id(self.user.id) setting.whitelist.add_id(self.user.id)
@ -2498,9 +2504,9 @@ class Rule:
"""name: captcha""" """name: captcha"""
user_id = self.user.id user_id = self.user.id
if ( if (
setting.get_challenge_state(user_id) setting.get_challenge_state(user_id)
and not curr_captcha.get(user_id) and not curr_captcha.get(user_id)
or not curr_captcha.get(user_id) or not curr_captcha.get(user_id)
): ):
# Put in challenge queue # Put in challenge queue
await captcha_task.add( await captcha_task.add(
@ -2513,9 +2519,9 @@ class Rule:
"""no_priority""" """no_priority"""
user_id = self.user.id user_id = self.user.id
if ( if (
(captcha := curr_captcha.get(user_id)) (captcha := curr_captcha.get(user_id))
and captcha.input and captcha.input
and captcha.type == "math" and captcha.type == "math"
): ):
text = self._get_text() text = self._get_text()
captcha.log_msg(text) captcha.log_msg(text)
@ -2527,9 +2533,9 @@ class Rule:
async def verify_sticker_response(self) -> bool: async def verify_sticker_response(self) -> bool:
"""no_priority""" """no_priority"""
if ( if (
(captcha := curr_captcha.get(user_id := self.user.id)) (captcha := curr_captcha.get(user_id := self.user.id))
and captcha.input and captcha.input
and captcha.type == "sticker" and captcha.type == "sticker"
): ):
captcha.log_msg(self._get_text()) captcha.log_msg(self._get_text())
await captcha.verify(self.msg.sticker) and await self.msg.safe_delete() await captcha.verify(self.msg.sticker) and await self.msg.safe_delete()
@ -2543,14 +2549,14 @@ class Rule:
async def image_captcha_listener(_, msg: Message): async def image_captcha_listener(_, msg: Message):
# Ignores non-private chat, not via bot, username not equal to image bot # Ignores non-private chat, not via bot, username not equal to image bot
if ( if (
msg.chat.type != ChatType.PRIVATE msg.chat.type != ChatType.PRIVATE
or not msg.via_bot or not msg.via_bot
or msg.via_bot.username != img_captcha_bot or msg.via_bot.username != img_captcha_bot
): ):
return return
user_id = msg.chat.id user_id = msg.chat.id
if ( if (
last_captcha := sqlite.get(f"pmcaptcha.challenge.{user_id}") last_captcha := sqlite.get(f"pmcaptcha.challenge.{user_id}")
) and not curr_captcha.get(user_id): ) and not curr_captcha.get(user_id):
# Resume last captcha challenge # Resume last captcha challenge
if last_captcha["type"] != "img": if last_captcha["type"] != "img":
@ -2638,7 +2644,7 @@ async def resume_states():
if key.startswith("pmcaptcha.challenge"): if key.startswith("pmcaptcha.challenge"):
user_id = int(key.split(".")[2]) user_id = int(key.split(".")[2])
if user_id not in curr_captcha and ( if user_id not in curr_captcha and (
challenge := captcha_challenges.get(value.get("type")) challenge := captcha_challenges.get(value.get("type"))
): ):
# Resume challenge state # Resume challenge state
try: try:

View File

@ -35,8 +35,8 @@ async def qq_music(message: Message, client: AsyncClient):
uri, uri,
thumb=cover or None, thumb=cover or None,
caption=f"{text}", caption=f"{text}",
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await msg.safe_delete() await msg.safe_delete()
except Exception as e: except Exception as e:

View File

@ -34,8 +34,8 @@ async def gen_qr(client: Client, message: Message):
await client.send_document( await client.send_document(
message.chat.id, message.chat.id,
document="qr.webp", document="qr.webp",
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
except UnicodeEncodeError: except UnicodeEncodeError:
await message.edit(f"{lang('error_prefix')}{lang('genqr_e_encode')}") await message.edit(f"{lang('error_prefix')}{lang('genqr_e_encode')}")

View File

@ -4,7 +4,11 @@ from typing import Dict, List
from pyrogram import filters from pyrogram import filters
from pyrogram.errors import ChatAdminRequired, UserAdminInvalid, FloodWait from pyrogram.errors import ChatAdminRequired, UserAdminInvalid, FloodWait
from pyrogram.raw.functions.channels import GetAdminLog, GetMessages from pyrogram.raw.functions.channels import GetAdminLog, GetMessages
from pyrogram.raw.types import ChannelAdminLogEventsFilter, ChannelAdminLogEventActionUpdatePinned, InputMessageID from pyrogram.raw.types import (
ChannelAdminLogEventsFilter,
ChannelAdminLogEventActionUpdatePinned,
InputMessageID,
)
from pyrogram.raw.types.channels import AdminLogResults from pyrogram.raw.types.channels import AdminLogResults
from pyrogram.raw.types.messages import Messages from pyrogram.raw.types.messages import Messages
@ -47,9 +51,9 @@ async def try_ask_admin(message: Message, num_map: Dict[int, List[int]]) -> int:
await message.edit(text) await message.edit(text)
try: try:
async with bot.conversation( async with bot.conversation(
message.chat.id, filters=filters.user(message.from_user.id) message.chat.id, filters=filters.user(message.from_user.id)
) as conv: ) as conv:
await sleep(.1) await sleep(0.1)
res: Message = await conv.get_response() res: Message = await conv.get_response()
await res.safe_delete() await res.safe_delete()
uid = int(res.text) uid = int(res.text)
@ -76,7 +80,9 @@ async def pin_one(message: Message, mid: int):
async def get_unpin_messages(cid: int, ids: List[int]) -> List[int]: async def get_unpin_messages(cid: int, ids: List[int]) -> List[int]:
ids = [InputMessageID(id=i) for i in ids] ids = [InputMessageID(id=i) for i in ids]
r: Messages = await bot.invoke(GetMessages(channel=await bot.resolve_peer(cid), id=ids)) r: Messages = await bot.invoke(
GetMessages(channel=await bot.resolve_peer(cid), id=ids)
)
new_ids = [] new_ids = []
for i in r.messages: for i in r.messages:
if not i.pinned: if not i.pinned:

View File

@ -27,18 +27,21 @@ def try_cast_or_fallback(val: Any, t: type) -> Any:
def check_chat_available(chat: Chat): def check_chat_available(chat: Chat):
assert (chat.type in [ChatType.CHANNEL, ChatType.GROUP] and not chat.has_protected_content) assert (
chat.type in [ChatType.CHANNEL, ChatType.GROUP]
and not chat.has_protected_content
)
@listener( @listener(
command="shift", command="shift",
description="开启转发频道新消息功能", description="开启转发频道新消息功能",
parameters="set [from channel] [to channel] (silent) 自动转发频道新消息(可以使用频道用户名或者 id\n" parameters="set [from channel] [to channel] (silent) 自动转发频道新消息(可以使用频道用户名或者 id\n"
"del [from channel] 删除转发\n" "del [from channel] 删除转发\n"
"backup [from channel] [to channel] (silent) 备份频道(可以使用频道用户名或者 id\n" "backup [from channel] [to channel] (silent) 备份频道(可以使用频道用户名或者 id\n"
"list 顯示目前轉發的頻道\n\n" "list 顯示目前轉發的頻道\n\n"
"选项说明:\n" "选项说明:\n"
"silent: 禁用通知, none: 文字, all: 全部訊息都傳, photo: 圖片, document: 檔案, video: 影片", "silent: 禁用通知, none: 文字, all: 全部訊息都傳, photo: 圖片, document: 檔案, video: 影片",
) )
async def shift_set(client: Client, message: Message): async def shift_set(client: Client, message: Message):
if not message.parameter: if not message.parameter:
@ -137,13 +140,21 @@ async def shift_set(client: Client, message: Message):
await message.edit(f"备份频道 {source.id}{target.id} 已完成。") await message.edit(f"备份频道 {source.id}{target.id} 已完成。")
# 列出要轉存的頻道 # 列出要轉存的頻道
elif message.parameter[0] == "list": elif message.parameter[0] == "list":
from_ids = list(filter(lambda x: (x.startswith("shift.") and (not x.endswith("options"))), list(sqlite.keys()))) from_ids = list(
filter(
lambda x: (x.startswith("shift.") and (not x.endswith("options"))),
list(sqlite.keys()),
)
)
if not from_ids: if not from_ids:
return await message.edit("沒有要轉存的頻道") return await message.edit("沒有要轉存的頻道")
output = "總共有 %d 個頻道要轉存\n\n" % len(from_ids) output = "總共有 %d 個頻道要轉存\n\n" % len(from_ids)
for from_id in from_ids: for from_id in from_ids:
to_id = sqlite[from_id] to_id = sqlite[from_id]
output += "%s -> %s\n" % (format_channel_id(from_id[6:]), format_channel_id(to_id)) output += "%s -> %s\n" % (
format_channel_id(from_id[6:]),
format_channel_id(to_id),
)
await message.edit(output) await message.edit(output)
else: else:
await message.edit(f"{lang('error_prefix')}{lang('arg_error')}") await message.edit(f"{lang('error_prefix')}{lang('arg_error')}")
@ -188,10 +199,10 @@ async def shift_channel_message(message: Message):
async def loosely_forward( async def loosely_forward(
notifier: Message, notifier: Message,
message: Message, message: Message,
chat_id: int, chat_id: int,
disable_notification: bool = False, disable_notification: bool = False,
): ):
try: try:
await message.forward(chat_id, disable_notification=disable_notification) await message.forward(chat_id, disable_notification=disable_notification)

View File

@ -118,8 +118,7 @@ async def speedtest(client: Client, message: Message, request: AsyncClient):
message.chat.id, message.chat.id,
photo, photo,
caption=des, caption=des,
reply_to_message_id=message.reply_to_top_message_id message_thread_id=message.message_thread_id or message.reply_to_message_id,
or message.reply_to_message_id,
) )
except Exception: except Exception:
return await msg.edit(des) return await msg.edit(des)

View File

@ -118,7 +118,7 @@ async def sticker_transfer(message: Message):
"stickers.csv", "stickers.csv",
caption=f"贴纸包导出文件,成功导出了 {num} 个贴纸包", caption=f"贴纸包导出文件,成功导出了 {num} 个贴纸包",
thumb=f"pagermaid{sep}assets{sep}logo.jpg", thumb=f"pagermaid{sep}assets{sep}logo.jpg",
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
safe_remove("stickers.csv") safe_remove("stickers.csv")
await message.safe_delete() await message.safe_delete()

View File

@ -29,7 +29,7 @@ async def tg_bg(client: Client, message: Message):
message.chat.id, message.chat.id,
bg_doc.file_id, bg_doc.file_id,
file_name="bg.jpg", file_name="bg.jpg",
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
return await message.safe_delete() return await message.safe_delete()
await message.edit("获取失败,请检查 URL") await message.edit("获取失败,请检查 URL")

View File

@ -49,8 +49,8 @@ async def weather_pic(client: Client, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()
@ -67,8 +67,8 @@ async def weather_he(client: Client, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()
@ -82,8 +82,8 @@ async def az_tts(client: Client, message: Message, mode: str):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()
@ -143,7 +143,7 @@ async def draw_photo(client: Client, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()

View File

@ -17,8 +17,8 @@ async def weather_lite(request: AsyncClient, message: Message):
f.write(data.content) f.write(data.content)
await message.reply_photo( await message.reply_photo(
"weather.png", "weather.png",
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
quote=False, quote=False,
) )
await message.safe_delete() await message.safe_delete()

View File

@ -18,8 +18,8 @@ async def xjj(message: Message, client: AsyncClient):
await message.reply_video( await message.reply_video(
url, url,
quote=False, quote=False,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
await message.safe_delete() await message.safe_delete()
except Exception as e: except Exception as e:

View File

@ -77,7 +77,7 @@ async def start_download(message: Message, url: str):
cid, cid,
video=file, video=file,
supports_streaming=True, supports_streaming=True,
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
except Exception: except Exception:
try: try:
@ -85,7 +85,7 @@ async def start_download(message: Message, url: str):
cid, cid,
document=file, document=file,
force_document=True, force_document=True,
reply_to_message_id=message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
except Exception as e: except Exception as e:
result["status"] = False result["status"] = False

View File

@ -30,16 +30,16 @@ async def yv_lu(bot: Client, message: Message):
try: try:
await chat_response.copy( await chat_response.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
except Flood as e: except Flood as e:
await sleep(e.value + 1) await sleep(e.value + 1)
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await chat_response.copy( await chat_response.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id reply_to_message_id=message.reply_to_message_id,
or message.reply_to_top_message_id, message_thread_id=message.message_thread_id,
) )
except Exception: except Exception:
pass pass

View File

@ -55,7 +55,6 @@ async def get_result(message, request, r18=2):
@listener(command="zpr", description="随机获取一组涩涩纸片人。", parameters="{r18}") @listener(command="zpr", description="随机获取一组涩涩纸片人。", parameters="{r18}")
async def zpr(client: Client, message: Message, request: AsyncClient): async def zpr(client: Client, message: Message, request: AsyncClient):
arguments = message.arguments.upper().strip() arguments = message.arguments.upper().strip()
message_thread_id = message.reply_to_top_message_id or message.reply_to_message_id
message = await message.edit("正在前往二次元。。。") message = await message.edit("正在前往二次元。。。")
try: try:
photoList, des = await get_result( photoList, des = await get_result(
@ -68,7 +67,10 @@ async def zpr(client: Client, message: Message, request: AsyncClient):
await message.edit("传送中。。。") await message.edit("传送中。。。")
try: try:
await client.send_media_group( await client.send_media_group(
message.chat.id, photoList, reply_to_message_id=message_thread_id message.chat.id,
photoList,
reply_to_message_id=message.reply_to_message_id,
message_thread_id=message.message_thread_id,
) )
except RPCError as e: except RPCError as e:
return await message.edit( return await message.edit(