fix: Optimized the message push module and fixed some instances of missed push
This commit is contained in:
@@ -207,8 +207,8 @@ class Up(BaseModel):
|
|||||||
"{url}": f"https://live.bilibili.com/{self.room_id}",
|
"{url}": f"https://live.bilibili.com/{self.room_id}",
|
||||||
"{cover}": "".join(["{urlpic=", arg_base["cover"], "}"])
|
"{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(self, args)
|
||||||
|
await self.__bot.send_live_on_at(self)
|
||||||
|
|
||||||
@self.__room.on("PREPARING")
|
@self.__room.on("PREPARING")
|
||||||
async def live_off(event):
|
async def live_off(event):
|
||||||
@@ -365,6 +365,7 @@ class Up(BaseModel):
|
|||||||
动态更新事件
|
动态更新事件
|
||||||
"""
|
"""
|
||||||
logger.debug(f"{self.uname} (DYNAMIC_UPDATE): {event}")
|
logger.debug(f"{self.uname} (DYNAMIC_UPDATE): {event}")
|
||||||
|
logger.opt(colors=True).info(f"<magenta>[动态更新] {self.uname}</>")
|
||||||
|
|
||||||
dynamic_id = event["desc"]["dynamic_id"]
|
dynamic_id = event["desc"]["dynamic_id"]
|
||||||
dynamic_type = event["desc"]["type"]
|
dynamic_type = event["desc"]["type"]
|
||||||
|
|||||||
+47
-26
@@ -1,11 +1,11 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import time
|
import time
|
||||||
from asyncio import AbstractEventLoop
|
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 import Ariadne
|
||||||
from graia.ariadne.connection.config import config as AriadneConfig, HttpClientConfig, WebsocketClientConfig
|
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.chain import MessageChain
|
||||||
from graia.ariadne.message.element import At, AtAll
|
from graia.ariadne.message.element import At, AtAll
|
||||||
from graia.ariadne.model import LogConfig, MemberPerm
|
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 .model import LiveOn, LiveOff, DynamicUpdate, Message, PushType, PushTarget
|
||||||
from .room import Up
|
from .room import Up
|
||||||
|
from ..exception import NoPermissionException
|
||||||
from ..exception.AtAllLimitedException import AtAllLimitedException
|
from ..exception.AtAllLimitedException import AtAllLimitedException
|
||||||
from ..painter.LiveReportGenerator import LiveReportGenerator
|
from ..painter.LiveReportGenerator import LiveReportGenerator
|
||||||
from ..utils import config, redis
|
from ..utils import config, redis
|
||||||
@@ -71,7 +72,6 @@ class Bot(BaseModel):
|
|||||||
Raises:
|
Raises:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
exception = None
|
|
||||||
if msg.type == PushType.Friend:
|
if msg.type == PushType.Friend:
|
||||||
for message in msg.get_message_chains():
|
for message in msg.get_message_chains():
|
||||||
try:
|
try:
|
||||||
@@ -81,56 +81,73 @@ class Bot(BaseModel):
|
|||||||
logger.exception("消息推送模块异常", ex)
|
logger.exception("消息推送模块异常", ex)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
msgs = await self.group_message_filter(msg)
|
msgs, exception = 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()
|
|
||||||
|
|
||||||
for message in msgs:
|
for message in msgs:
|
||||||
try:
|
try:
|
||||||
await self.__bot.send_group_message(msg.id, message)
|
await self.__bot.send_group_message(msg.id, message)
|
||||||
logger.info(f"{self.qq} -> 群[{msg.id}] : {message.safe_display}")
|
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:
|
except RemoteException as ex:
|
||||||
if "AT_ALL_LIMITED" in str(ex):
|
if "AT_ALL_LIMITED" in str(ex):
|
||||||
|
logger.warning(f"Bot({self.qq}) 今日的@全体成员次数已达到上限")
|
||||||
exception = AtAllLimitedException()
|
exception = AtAllLimitedException()
|
||||||
self.__at_all_limited = time.localtime(time.time()).tm_yday
|
self.__at_all_limited = time.localtime(time.time()).tm_yday
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
logger.exception("消息推送模块异常", ex)
|
logger.exception("消息推送模块异常", ex)
|
||||||
continue
|
continue
|
||||||
|
except Exception as ex:
|
||||||
|
logger.exception("消息推送模块异常", ex)
|
||||||
|
continue
|
||||||
|
|
||||||
if exception is not None:
|
if exception is not None:
|
||||||
raise exception
|
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:
|
Args:
|
||||||
message: 源消息链
|
message: 源消息
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
处理后的消息链
|
处理后的消息链和引发的异常
|
||||||
"""
|
"""
|
||||||
|
exception = None
|
||||||
|
|
||||||
if message.type == PushType.Friend:
|
if message.type == PushType.Friend:
|
||||||
return message.get_message_chains()
|
return message.get_message_chains(), exception
|
||||||
|
|
||||||
new_chains = []
|
new_chains = []
|
||||||
|
|
||||||
# 过滤 Bot 不在群内的消息
|
# 过滤 Bot 不在群内的消息
|
||||||
group = await self.__bot.get_group(message.id)
|
group = await self.__bot.get_group(message.id)
|
||||||
if group is None:
|
if group is None:
|
||||||
return new_chains
|
return new_chains, exception
|
||||||
|
|
||||||
for chain in message.get_message_chains():
|
for chain in message.get_message_chains():
|
||||||
if AtAll in chain:
|
if AtAll in chain:
|
||||||
|
# 过滤已超出当日次数上限的 @全体成员 消息
|
||||||
|
if time.localtime(time.time()).tm_yday == self.__at_all_limited:
|
||||||
|
exception = AtAllLimitedException()
|
||||||
|
chain = chain.exclude(AtAll)
|
||||||
|
|
||||||
# 过滤 Bot 不是群管理员时的 @全体成员 消息
|
# 过滤 Bot 不是群管理员时的 @全体成员 消息
|
||||||
bot_info = await self.__bot.get_member(message.id, self.qq)
|
bot_info = await self.__bot.get_member(message.id, self.qq)
|
||||||
if bot_info.permission < MemberPerm.Administrator:
|
if bot_info.permission < MemberPerm.Administrator:
|
||||||
chain = chain.exclude(AtAll)
|
exception = NoPermissionException()
|
||||||
|
|
||||||
# 过滤已超出当日次数上限的 @全体成员 消息
|
|
||||||
if time.localtime(time.time()).tm_yday == self.__at_all_limited:
|
|
||||||
chain = chain.exclude(AtAll)
|
chain = chain.exclude(AtAll)
|
||||||
|
|
||||||
# 过滤多余的 @全体成员 消息
|
# 过滤多余的 @全体成员 消息
|
||||||
@@ -157,7 +174,7 @@ class Bot(BaseModel):
|
|||||||
if len(chain) != 0:
|
if len(chain) != 0:
|
||||||
new_chains.append(chain)
|
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):
|
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):
|
if not isinstance(up, Up):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
logger.debug(f"{up.uname} 已配置推送群: ({', '.join(map(lambda t: str(t.id), up.targets))})")
|
||||||
for target in up.targets:
|
for target in up.targets:
|
||||||
select = type_selector(target)
|
select = type_selector(target)
|
||||||
if not isinstance(select, (LiveOn, LiveOff, DynamicUpdate)):
|
if not isinstance(select, (LiveOn, LiveOff, DynamicUpdate)):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
logger.debug(f"群 {target.id}: ({select.enabled}) ({select.message})")
|
||||||
if select.enabled:
|
if select.enabled:
|
||||||
message = select.message
|
message = select.message
|
||||||
for arg, val in args.items():
|
for arg, val in args.items():
|
||||||
@@ -208,24 +227,26 @@ class Bot(BaseModel):
|
|||||||
up: 要发送的 UP 主实例
|
up: 要发送的 UP 主实例
|
||||||
args: 占位符参数
|
args: 占位符参数
|
||||||
"""
|
"""
|
||||||
try:
|
await self.__send_push_message(up, lambda t: t.live_on, args)
|
||||||
await self.__send_push_message(up, lambda t: t.live_on, args)
|
|
||||||
except AtAllLimitedException:
|
|
||||||
await self.send_live_on_at(up, True)
|
|
||||||
|
|
||||||
async def send_live_on_at(self, up: Up, limited: bool = False):
|
async def send_live_on_at(self, up: Up):
|
||||||
"""
|
"""
|
||||||
发送开播 @ 我列表中的 @ 消息
|
发送开播 @ 我列表中的 @ 消息
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
up: 要发送的 UP 主实例
|
up: 要发送的 UP 主实例
|
||||||
limited: 是否为 @全体成员次数达到上限时发送。默认:False
|
|
||||||
"""
|
"""
|
||||||
if not isinstance(up, Up):
|
if not isinstance(up, Up):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
limited = self.__at_all_limited == time.localtime(time.time()).tm_yday
|
||||||
for target in filter(lambda t: t.type == PushType.Group, up.targets):
|
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)])
|
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))
|
await self.send_message(Message(id=target.id, content=ats, type=target.type))
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
"""
|
||||||
|
没有管理员权限异常
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .ApiException import ApiException
|
||||||
|
|
||||||
|
|
||||||
|
class NoPermissionException(ApiException):
|
||||||
|
"""
|
||||||
|
没有管理员权限异常
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.msg = "没有管理员权限"
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
from .ApiException import *
|
from .ApiException import *
|
||||||
|
from .AtAllLimitedException import *
|
||||||
from .CredentialNoBiliJctException import *
|
from .CredentialNoBiliJctException import *
|
||||||
from .CredentialNoBuvid3Exception import *
|
from .CredentialNoBuvid3Exception import *
|
||||||
from .CredentialNoSessdataException import *
|
from .CredentialNoSessdataException import *
|
||||||
from .DataSourceException import *
|
from .DataSourceException import *
|
||||||
from .LiveException import *
|
from .LiveException import *
|
||||||
from .NetworkException import *
|
from .NetworkException import *
|
||||||
|
from .NoPermissionException import *
|
||||||
from .RedisException import *
|
from .RedisException import *
|
||||||
from .ResponseCodeException import *
|
from .ResponseCodeException import *
|
||||||
from .ResponseException import *
|
from .ResponseException import *
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ SIMPLE_CONFIG = {
|
|||||||
# 视为主播网络波动断线重连时,需发送的额外提示消息
|
# 视为主播网络波动断线重连时,需发送的额外提示消息
|
||||||
"UP_DISCONNECT_CONNECT_MESSAGE": "检测到下播后短时间内重新开播,可能是由于主播网络波动引起,本次开播不再重复通知",
|
"UP_DISCONNECT_CONNECT_MESSAGE": "检测到下播后短时间内重新开播,可能是由于主播网络波动引起,本次开播不再重复通知",
|
||||||
|
|
||||||
|
# 当日 @全体成员 达到上限后,需发送的额外提示消息
|
||||||
|
"AT_ALL_LIMITED_MESSAGE": "今日@全体成员次数已达上限,将尝试@指定成员,请需要接收单独@消息的群员使用\"开播@我\"命令进行订阅",
|
||||||
|
# 设置了 @全体成员 但没有管理员权限时,需发送的额外提示消息
|
||||||
|
"NO_PERMISSION_MESSAGE": "已设置@全体成员但没有管理员权限,将尝试@指定成员,请需要接收单独@消息的群员使用\"开播@我\"命令进行订阅",
|
||||||
|
|
||||||
# 动态推送抓取频率和视为新动态的时间间隔,单位:秒
|
# 动态推送抓取频率和视为新动态的时间间隔,单位:秒
|
||||||
"DYNAMIC_INTERVAL": 10,
|
"DYNAMIC_INTERVAL": 10,
|
||||||
|
|
||||||
@@ -168,6 +173,11 @@ FULL_CONFIG = {
|
|||||||
# 视为主播网络波动断线重连时,需发送的额外提示消息
|
# 视为主播网络波动断线重连时,需发送的额外提示消息
|
||||||
"UP_DISCONNECT_CONNECT_MESSAGE": "检测到下播后短时间内重新开播,可能是由于主播网络波动引起,本次开播不再重复通知",
|
"UP_DISCONNECT_CONNECT_MESSAGE": "检测到下播后短时间内重新开播,可能是由于主播网络波动引起,本次开播不再重复通知",
|
||||||
|
|
||||||
|
# 当日 @全体成员 达到上限后,需发送的额外提示消息
|
||||||
|
"AT_ALL_LIMITED_MESSAGE": "今日@全体成员次数已达上限,将尝试@指定成员,请需要接收单独@消息的群员使用\"开播@我\"命令进行订阅",
|
||||||
|
# 设置了 @全体成员 但没有管理员权限时,需发送的额外提示消息
|
||||||
|
"NO_PERMISSION_MESSAGE": "已设置@全体成员但没有管理员权限,将尝试@指定成员,请需要接收单独@消息的群员使用\"开播@我\"命令进行订阅",
|
||||||
|
|
||||||
# 动态推送抓取频率和视为新动态的时间间隔,单位:秒
|
# 动态推送抓取频率和视为新动态的时间间隔,单位:秒
|
||||||
"DYNAMIC_INTERVAL": 10,
|
"DYNAMIC_INTERVAL": 10,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user