shift 支持无通知转发

This commit is contained in:
Ricky8955555 2023-06-12 14:00:44 +08:00 committed by GitHub
parent 0b64b3a475
commit f4e864e341
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 142 additions and 102 deletions

View File

@ -2,18 +2,24 @@
指令:,shift 指令:,shift
# 设置转发 ## 使用方法
### 设置转发
当收到 from_channel_id 的新消息时,自动转发到 to_channel_id。 当收到 from_channel_id 的新消息时,自动转发到 to_channel_id。
需要加入 from_channel_id 和 to_channel_id。 需要加入 from_channel_id 和 to_channel_id。
`, shift set [from channel_id] [to channel_id]` `, shift set [from channel_id] [to channel_id] (silent)`
# 取消转发 ### 取消转发
`, shift del [from channel_id]` `, shift del [from channel_id]`
# 备份频道 ### 备份频道
`, shift backup [from channel_id] [to channel_id]` `, shift backup [from channel_id] [to channel_id] (silent)`
## 选项解释
- `silent`: 禁用通知

View File

@ -1,144 +1,178 @@
""" PagerMaid module for channel help. """ """ PagerMaid module for channel help. """
from asyncio import sleep
from random import uniform
from pyrogram.enums.chat_type import ChatType
from pyrogram.errors.exceptions.flood_420 import FloodWait
from pagermaid import log
from pagermaid.single_utils import sqlite
from pagermaid.enums import Client, Message
from pagermaid.utils import lang
from pagermaid.listener import listener
import contextlib import contextlib
from asyncio import sleep
from random import uniform
from typing import Any
from pagermaid import log
from pagermaid.enums import Client, Message
from pagermaid.listener import listener
from pagermaid.single_utils import sqlite
from pagermaid.utils import lang
from pyrogram.enums.chat_type import ChatType
from pyrogram.errors.exceptions.flood_420 import FloodWait
from pyrogram.types import Chat
WHITELIST = [-1001441461877]
AVAILABLE_OPTIONS = {"silent"}
@listener(command="shift", def try_cast_or_fallback(val: Any, t: type) -> Any:
description='开启转发频道新消息功能', try:
parameters="set [from channel] [to channel] 自动转发频道新消息(可以使用频道用户名或者 id\n" return t(val)
"del [from channel] 删除转发\n" except:
"backup [from channel] [to channel] 备份频道(可以使用频道用户名或者 id") return val
def check_chat_available(chat: Chat):
assert chat.type == ChatType.CHANNEL and not chat.has_protected_content
@listener(
command="shift",
description="开启转发频道新消息功能",
parameters="set [from channel] [to channel] (silent) 自动转发频道新消息(可以使用频道用户名或者 id\n"
"del [from channel] 删除转发\n"
"backup [from channel] [to channel] (silent) 备份频道(可以使用频道用户名或者 id\n\n"
"选项说明:\n"
"silent: 禁用通知",
)
async def shift_set(client: Client, message: Message): async def shift_set(client: Client, message: Message):
if not 1 < len(message.parameter) < 4: if not message.parameter:
await message.edit(f"{lang('error_prefix')}{lang('arg_error')}") await message.edit(f"{lang('error_prefix')}{lang('arg_error')}")
return return
if message.parameter[0] == "set": if message.parameter[0] == "set":
if len(message.parameter) != 3: if len(message.parameter) < 3:
return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}") return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}")
options = set(message.parameter[3:] if len(message.parameter) > 3 else ())
if set(options).difference(AVAILABLE_OPTIONS):
return await message.edit("出错了呜呜呜 ~ 无法识别的选项。")
# 检查来源频道 # 检查来源频道
try: try:
channel = await client.get_chat(int(message.parameter[1])) source = await client.get_chat(
if channel.type != ChatType.CHANNEL: try_cast_or_fallback(message.parameter[1], int)
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。") )
if channel.has_protected_content: assert isinstance(source, Chat)
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。") check_chat_available(source)
except Exception: except Exception:
try: return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。")
channel = await client.get_chat(message.parameter[1]) if source.id in WHITELIST:
if channel.type != ChatType.CHANNEL: return await message.edit("出错了呜呜呜 ~ 此对话位于白名单中。")
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。")
if channel.has_protected_content:
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。")
except Exception:
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。")
if channel.id in [-1001441461877]:
return await message.edit('出错了呜呜呜 ~ 此对话位于白名单中。')
# 检查目标频道 # 检查目标频道
try: try:
to = await client.get_chat(int(message.parameter[2])) target = await client.get_chat(
try_cast_or_fallback(message.parameter[2], int)
)
assert isinstance(target, Chat)
except Exception: except Exception:
try: return await message.edit("出错了呜呜呜 ~ 无法识别的目标对话。")
to = await client.get_chat(message.parameter[2]) if target.id in WHITELIST:
except Exception: await message.edit("出错了呜呜呜 ~ 此对话位于白名单中。")
return await message.edit("出错了呜呜呜 ~ 无法识别的目标对话。")
if to.id in [-1001441461877]:
await message.edit('出错了呜呜呜 ~ 此对话位于白名单中。')
return return
sqlite[f"shift.{channel.id}"] = to.id sqlite[f"shift.{source.id}"] = target.id
await message.edit(f"已成功配置将对话 {channel.id} 的新消息转发到 {to.id}") sqlite[f"shift.{source.id}.options"] = (
await log(f"已成功配置将对话 {channel.id} 的新消息转发到 {to.id}") message.parameter[3:] if len(message.parameter) > 3 else []
)
await message.edit(f"已成功配置将对话 {source.id} 的新消息转发到 {target.id}")
await log(f"已成功配置将对话 {source.id} 的新消息转发到 {target.id}")
elif message.parameter[0] == "del": elif message.parameter[0] == "del":
if len(message.parameter) != 2: if len(message.parameter) != 2:
return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}") return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}")
# 检查来源频道 # 检查来源频道
try: try:
channel = await client.get_chat(int(message.parameter[1])) source = await client.get_chat(
try_cast_or_fallback(message.parameter[1], int)
)
assert isinstance(source, Chat)
except Exception: except Exception:
try: return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。")
channel = await client.get_chat(message.parameter[1])
except Exception:
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。")
try: try:
del sqlite[f"shift.{channel.id}"] del sqlite[f"shift.{source.id}"]
except Exception as e: with contextlib.suppress(Exception):
return await message.edit('emm...当前对话不存在于自动转发列表中。') del sqlite[f"shift.{source.id}.options"]
await message.edit(f"已成功关闭对话 {str(channel.id)} 的自动转发功能。") except Exception:
await log(f"已成功关闭对话 {str(channel.id)} 的自动转发功能。") return await message.edit("emm...当前对话不存在于自动转发列表中。")
await message.edit(f"已成功关闭对话 {str(source.id)} 的自动转发功能。")
await log(f"已成功关闭对话 {str(source.id)} 的自动转发功能。")
elif message.parameter[0] == "backup": elif message.parameter[0] == "backup":
if len(message.parameter) != 3: if len(message.parameter) < 3:
return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}") return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}")
options = set(message.parameter[3:] if len(message.parameter) > 3 else ())
if set(options).difference(AVAILABLE_OPTIONS):
return await message.edit("出错了呜呜呜 ~ 无法识别的选项。")
# 检查来源频道 # 检查来源频道
try: try:
channel = await client.get_chat(int(message.parameter[1])) source = await client.get_chat(
if channel.type != ChatType.CHANNEL: try_cast_or_fallback(message.parameter[1], int)
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。") )
if channel.has_protected_content: assert isinstance(source, Chat)
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。") check_chat_available(source)
except Exception: except Exception:
try: return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。")
channel = await client.get_chat(message.parameter[1]) if source.id in WHITELIST:
if channel.type != ChatType.CHANNEL: return await message.edit("出错了呜呜呜 ~ 此对话位于白名单中。")
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。")
if channel.has_protected_content:
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。")
except Exception:
return await message.edit("出错了呜呜呜 ~ 无法识别的来源对话。")
if channel.id in [-1001441461877]:
return await message.edit('出错了呜呜呜 ~ 此对话位于白名单中。')
# 检查目标频道 # 检查目标频道
try: try:
to = await client.get_chat(int(message.parameter[2])) target = await client.get_chat(
try_cast_or_fallback(message.parameter[2], int)
)
assert isinstance(target, Chat)
except Exception: except Exception:
try: return await message.edit("出错了呜呜呜 ~ 无法识别的目标对话。")
to = await client.get_chat(message.parameter[2]) if target.id in WHITELIST:
except Exception: return await message.edit("出错了呜呜呜 ~ 此对话位于白名单中。")
return await message.edit("出错了呜呜呜 ~ 无法识别的目标对话。")
if to.id in [-1001441461877]:
return await message.edit('出错了呜呜呜 ~ 此对话位于白名单中。')
# 开始遍历消息 # 开始遍历消息
await message.edit(f'开始备份频道 {channel.id}{to.id}') await message.edit(f"开始备份频道 {source.id}{target.id}")
async for msg in client.search_messages(channel.id): async for msg in client.search_messages(source.id): # type: ignore
await sleep(uniform(0.5, 1.0)) await sleep(uniform(0.5, 1.0))
await forward_msg(message, msg, to.id) await loosely_forward(
await message.edit(f'备份频道 {channel.id}{to.id} 已完成。') message,
msg,
target.id,
disable_notification="silent" in options,
)
await message.edit(f"备份频道 {source.id}{target.id} 已完成。")
else: else:
await message.edit(f"{lang('error_prefix')}{lang('arg_error')}") await message.edit(f"{lang('error_prefix')}{lang('arg_error')}")
return return
@listener(is_plugin=True, incoming=True, ignore_edited=True) @listener(is_plugin=True, incoming=True, ignore_edited=True)
async def shift_channel_message(message): async def shift_channel_message(message: Message):
""" Event handler to auto forward channel messages. """ """Event handler to auto forward channel messages."""
cid = sqlite.get(f"shift.{message.chat.id}", None) d = dict(sqlite)
if not cid: source = message.chat.id
return target = d.get(f"shift.{source}")
if message.chat.id in [-1001441461877]: if not target:
return return
if message.chat.has_protected_content: if message.chat.has_protected_content:
del sqlite[f"shift.{message.chat.id}"] del sqlite[f"shift.{source}"]
return return
options = d.get(f"shift.{source}.options") or []
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await message.forward(cid) await message.forward(
target,
disable_notification="silent" in options,
)
async def forward_msg(message, msg, cid): async def loosely_forward(
notifier: Message,
message: Message,
chat_id: int,
disable_notification: bool = False,
):
try: try:
await msg.forward(msg, cid) await message.forward(chat_id, disable_notification=disable_notification)
except FloodWait as e: except FloodWait as ex:
await message.edit(f'触发 Flood ,暂停 {e.value + uniform(0.5, 1.0)} 秒。') min: int = ex.value # type: ignore
try: delay = min + uniform(0.5, 1.0)
await sleep(e.value + uniform(0.5, 1.0)) await notifier.edit(f"触发 Flood ,暂停 {delay} 秒。")
except Exception as e: await sleep(delay)
print(f"Wait flood error: {e}") await loosely_forward(
return notifier, message, chat_id, disable_notification
await forward_msg(message, msg, cid) )
except Exception:
pass # drop other errors