fix: Optimized the message push module and fixed some instances of missed push

This commit is contained in:
LWR
2023-05-20 22:21:00 +08:00
parent 58d6c6a3bf
commit d7ec1325c4
5 changed files with 76 additions and 27 deletions

View File

@@ -207,8 +207,8 @@ class Up(BaseModel):
"{url}": f"https://live.bilibili.com/{self.room_id}",
"{cover}": "".join(["{urlpic=", arg_base["cover"], "}"])
}
await self.__bot.send_live_on_at(self)
await self.__bot.send_live_on(self, args)
await self.__bot.send_live_on_at(self)
@self.__room.on("PREPARING")
async def live_off(event):
@@ -365,6 +365,7 @@ class Up(BaseModel):
动态更新事件
"""
logger.debug(f"{self.uname} (DYNAMIC_UPDATE): {event}")
logger.opt(colors=True).info(f"<magenta>[动态更新] {self.uname}</>")
dynamic_id = event["desc"]["dynamic_id"]
dynamic_type = event["desc"]["type"]

View File

@@ -1,11 +1,11 @@
import asyncio
import time
from asyncio import AbstractEventLoop
from typing import Optional, List, Dict, Any, Union, Callable
from typing import Optional, List, Dict, Any, Union, Callable, Tuple
from graia.ariadne import Ariadne
from graia.ariadne.connection.config import config as AriadneConfig, HttpClientConfig, WebsocketClientConfig
from graia.ariadne.exception import RemoteException
from graia.ariadne.exception import RemoteException, AccountMuted
from graia.ariadne.message.chain import MessageChain
from graia.ariadne.message.element import At, AtAll
from graia.ariadne.model import LogConfig, MemberPerm
@@ -14,6 +14,7 @@ from pydantic import BaseModel, PrivateAttr
from .model import LiveOn, LiveOff, DynamicUpdate, Message, PushType, PushTarget
from .room import Up
from ..exception import NoPermissionException
from ..exception.AtAllLimitedException import AtAllLimitedException
from ..painter.LiveReportGenerator import LiveReportGenerator
from ..utils import config, redis
@@ -71,7 +72,6 @@ class Bot(BaseModel):
Raises:
"""
exception = None
if msg.type == PushType.Friend:
for message in msg.get_message_chains():
try:
@@ -81,56 +81,73 @@ class Bot(BaseModel):
logger.exception("消息推送模块异常", ex)
continue
else:
msgs = await self.group_message_filter(msg)
if any([(AtAll in x) for x in msg.get_message_chains()]) and all([(AtAll not in x) for x in msgs]):
exception = AtAllLimitedException()
msgs, exception = await self.group_message_filter(msg)
for message in msgs:
try:
await self.__bot.send_group_message(msg.id, message)
logger.info(f"{self.qq} -> 群[{msg.id}] : {message.safe_display}")
except AccountMuted:
logger.warning(f"Bot({self.qq}) 在群 {msg.id} 中被禁言")
return
except RemoteException as ex:
if "AT_ALL_LIMITED" in str(ex):
logger.warning(f"Bot({self.qq}) 今日的@全体成员次数已达到上限")
exception = AtAllLimitedException()
self.__at_all_limited = time.localtime(time.time()).tm_yday
continue
else:
logger.exception("消息推送模块异常", ex)
continue
except Exception as ex:
logger.exception("消息推送模块异常", ex)
continue
if exception is not None:
raise exception
if exception is not None:
message = ""
if isinstance(exception, AtAllLimitedException):
message = config.get("AT_ALL_LIMITED_MESSAGE")
elif isinstance(exception, NoPermissionException):
message = config.get("NO_PERMISSION_MESSAGE")
if len(message) > 0:
try:
await self.__bot.send_group_message(msg.id, MessageChain(message))
except Exception:
pass
async def group_message_filter(self, message: Message) -> List[MessageChain]:
async def group_message_filter(self, message: Message) -> Tuple[List[MessageChain], Optional[Exception]]:
"""
过滤群消息中的非法元素
Args:
message: 源消息
message: 源消息
Returns:
处理后的消息链
处理后的消息链和引发的异常
"""
exception = None
if message.type == PushType.Friend:
return message.get_message_chains()
return message.get_message_chains(), exception
new_chains = []
# 过滤 Bot 不在群内的消息
group = await self.__bot.get_group(message.id)
if group is None:
return new_chains
return new_chains, exception
for chain in message.get_message_chains():
if AtAll in chain:
# 过滤已超出当日次数上限的 @全体成员 消息
if time.localtime(time.time()).tm_yday == self.__at_all_limited:
exception = AtAllLimitedException()
chain = chain.exclude(AtAll)
# 过滤 Bot 不是群管理员时的 @全体成员 消息
bot_info = await self.__bot.get_member(message.id, self.qq)
if bot_info.permission < MemberPerm.Administrator:
chain = chain.exclude(AtAll)
# 过滤已超出当日次数上限的 @全体成员 消息
if time.localtime(time.time()).tm_yday == self.__at_all_limited:
exception = NoPermissionException()
chain = chain.exclude(AtAll)
# 过滤多余的 @全体成员 消息
@@ -157,7 +174,7 @@ class Bot(BaseModel):
if len(chain) != 0:
new_chains.append(chain)
return new_chains
return new_chains, exception
async def send_to_all_target(self, up: Up, msg: str, target_filter: Callable[[PushTarget], bool] = lambda t: True):
"""
@@ -189,11 +206,13 @@ class Bot(BaseModel):
if not isinstance(up, Up):
return
logger.debug(f"{up.uname} 已配置推送群: ({', '.join(map(lambda t: str(t.id), up.targets))})")
for target in up.targets:
select = type_selector(target)
if not isinstance(select, (LiveOn, LiveOff, DynamicUpdate)):
return
logger.debug(f"{target.id}: ({select.enabled}) ({select.message})")
if select.enabled:
message = select.message
for arg, val in args.items():
@@ -208,24 +227,26 @@ class Bot(BaseModel):
up: 要发送的 UP 主实例
args: 占位符参数
"""
try:
await self.__send_push_message(up, lambda t: t.live_on, args)
except AtAllLimitedException:
await self.send_live_on_at(up, True)
await self.__send_push_message(up, lambda t: t.live_on, args)
async def send_live_on_at(self, up: Up, limited: bool = False):
async def send_live_on_at(self, up: Up):
"""
发送开播 @ 我列表中的 @ 消息
Args:
up: 要发送的 UP 主实例
limited: 是否为 @全体成员次数达到上限时发送。默认False
"""
if not isinstance(up, Up):
return
limited = self.__at_all_limited == time.localtime(time.time()).tm_yday
for target in filter(lambda t: t.type == PushType.Group, up.targets):
if target.live_on.enabled and (limited or "{atall}" not in target.live_on.message):
group = await self.__bot.get_group(target.id)
if group is None:
continue
bot_info = await self.__bot.get_member(target.id, self.qq)
not_admin = bot_info.permission < MemberPerm.Administrator
if target.live_on.enabled and (limited or "{atall}" not in target.live_on.message or not_admin):
ats = " ".join(["{at" + str(x) + "}" for x in await redis.range_live_on_at(target.id)])
await self.send_message(Message(id=target.id, content=ats, type=target.type))

View File

@@ -0,0 +1,15 @@
"""
没有管理员权限异常
"""
from .ApiException import ApiException
class NoPermissionException(ApiException):
"""
没有管理员权限异常
"""
def __init__(self):
super().__init__()
self.msg = "没有管理员权限"

View File

@@ -1,10 +1,12 @@
from .ApiException import *
from .AtAllLimitedException import *
from .CredentialNoBiliJctException import *
from .CredentialNoBuvid3Exception import *
from .CredentialNoSessdataException import *
from .DataSourceException import *
from .LiveException import *
from .NetworkException import *
from .NoPermissionException import *
from .RedisException import *
from .ResponseCodeException import *
from .ResponseException import *

View File

@@ -57,6 +57,11 @@ SIMPLE_CONFIG = {
# 视为主播网络波动断线重连时,需发送的额外提示消息
"UP_DISCONNECT_CONNECT_MESSAGE": "检测到下播后短时间内重新开播,可能是由于主播网络波动引起,本次开播不再重复通知",
# 当日 @全体成员 达到上限后,需发送的额外提示消息
"AT_ALL_LIMITED_MESSAGE": "今日@全体成员次数已达上限,将尝试@指定成员,请需要接收单独@消息的群员使用\"开播@我\"命令进行订阅",
# 设置了 @全体成员 但没有管理员权限时,需发送的额外提示消息
"NO_PERMISSION_MESSAGE": "已设置@全体成员但没有管理员权限,将尝试@指定成员,请需要接收单独@消息的群员使用\"开播@我\"命令进行订阅",
# 动态推送抓取频率和视为新动态的时间间隔,单位:秒
"DYNAMIC_INTERVAL": 10,
@@ -168,6 +173,11 @@ FULL_CONFIG = {
# 视为主播网络波动断线重连时,需发送的额外提示消息
"UP_DISCONNECT_CONNECT_MESSAGE": "检测到下播后短时间内重新开播,可能是由于主播网络波动引起,本次开播不再重复通知",
# 当日 @全体成员 达到上限后,需发送的额外提示消息
"AT_ALL_LIMITED_MESSAGE": "今日@全体成员次数已达上限,将尝试@指定成员,请需要接收单独@消息的群员使用\"开播@我\"命令进行订阅",
# 设置了 @全体成员 但没有管理员权限时,需发送的额外提示消息
"NO_PERMISSION_MESSAGE": "已设置@全体成员但没有管理员权限,将尝试@指定成员,请需要接收单独@消息的群员使用\"开播@我\"命令进行订阅",
# 动态推送抓取频率和视为新动态的时间间隔,单位:秒
"DYNAMIC_INTERVAL": 10,