fix messages

This commit is contained in:
jxxghp
2024-07-02 13:50:41 +08:00
parent 9484093d22
commit 15a7297099
26 changed files with 555 additions and 233 deletions

View File

@@ -1,10 +1,6 @@
from abc import abstractmethod, ABCMeta
from typing import Tuple, Union
from app.db.systemconfig_oper import SystemConfigOper
from app.schemas import Notification
from app.schemas.types import SystemConfigKey, MessageChannel
class _ModuleBase(metaclass=ABCMeta):
"""
@@ -49,38 +45,3 @@ class _ModuleBase(metaclass=ABCMeta):
模块测试, 返回测试结果和错误信息
"""
pass
def checkMessage(channel_type: MessageChannel):
"""
检查消息渠道及消息类型,如不符合则不处理
"""
def decorator(func):
def wrapper(self, message: Notification, *args, **kwargs):
# 检查消息渠道
if message.channel and message.channel != channel_type:
return None
else:
# 检查消息类型开关
if message.mtype:
switchs = SystemConfigOper().get(SystemConfigKey.NotificationChannels) or []
for switch in switchs:
if switch.get("mtype") == message.mtype.value:
if channel_type == MessageChannel.Wechat and not switch.get("wechat"):
return None
if channel_type == MessageChannel.Telegram and not switch.get("telegram"):
return None
if channel_type == MessageChannel.Slack and not switch.get("slack"):
return None
if channel_type == MessageChannel.SynologyChat and not switch.get("synologychat"):
return None
if channel_type == MessageChannel.VoceChat and not switch.get("vocechat"):
return None
if channel_type == MessageChannel.WebPush and not switch.get("webpush"):
return None
return func(self, message, *args, **kwargs)
return wrapper
return decorator

View File

@@ -22,7 +22,7 @@ class EmbyModule(_ModuleBase):
if not mediaservers:
return
for server in mediaservers:
if server.type == "emby":
if server.type == "emby" and server.enabled:
self._servers[server.name] = Emby(**server.config)
def get_server(self, name: str) -> Optional[Emby]:
@@ -86,6 +86,12 @@ class EmbyModule(_ModuleBase):
:param args: 请求参数
:return: 字典解析为消息时需要包含title、text、image
"""
source = args.get("source")
if source:
server = self.get_server(source)
if not server:
return None
return server.get_webhook_message(form, args)
for server in self._servers.values():
result = server.get_webhook_message(form, args)
if result:

View File

@@ -22,7 +22,7 @@ class JellyfinModule(_ModuleBase):
if not mediaservers:
return
for server in mediaservers:
if server.type == "jellyfin":
if server.type == "jellyfin" and server.enabled:
self._servers[server.name] = Jellyfin(**server.config)
def get_server(self, name: str) -> Optional[Jellyfin]:
@@ -86,6 +86,12 @@ class JellyfinModule(_ModuleBase):
:param args: 请求参数
:return: 字典解析为消息时需要包含title、text、image
"""
source = args.get("source")
if source:
server = self.get_server(source)
if not server:
return None
return server.get_webhook_message(body)
for server in self._servers.values():
result = server.get_webhook_message(body)
if result:

View File

@@ -22,7 +22,7 @@ class PlexModule(_ModuleBase):
if not mediaservers:
return
for server in mediaservers:
if server.type == "plex":
if server.type == "plex" and server.enabled:
self._servers[server.name] = Plex(**server.config)
@staticmethod
@@ -72,6 +72,12 @@ class PlexModule(_ModuleBase):
:param args: 请求参数
:return: 字典解析为消息时需要包含title、text、image
"""
source = args.get("source")
if source:
server = self.get_server(source)
if not server:
return None
return server.get_webhook_message(body)
for server in self._servers.values():
result = server.get_webhook_message(body)
if result:

View File

@@ -33,7 +33,7 @@ class QbittorrentModule(_ModuleBase):
if not downloaders:
return
for server in downloaders:
if server.type == "qbittorrent":
if server.type == "qbittorrent" and server.enabled:
self._servers[server.name] = Qbittorrent(**server.config)
if server.default:
self._default_server_name = server.name

View File

@@ -1,42 +1,91 @@
import json
import re
from typing import Optional, Union, List, Tuple, Any
from typing import Optional, Union, List, Tuple, Any, Dict
from app.core.context import MediaInfo, Context
from app.core.config import settings
from app.helper.notification import NotificationHelper
from app.log import logger
from app.modules import _ModuleBase, checkMessage
from app.modules import _ModuleBase
from app.modules.slack.slack import Slack
from app.schemas import MessageChannel, CommingMessage, Notification
from app.schemas import MessageChannel, CommingMessage, Notification, NotificationConf
class SlackModule(_ModuleBase):
slack: Slack = None
_channel = MessageChannel.Telegram
_configs: Dict[str, NotificationConf] = {}
_clients: Dict[str, Slack] = {}
def init_module(self) -> None:
self.slack = Slack()
"""
初始化模块
"""
clients = NotificationHelper().get_notifications()
if not clients:
return
self._configs = {}
self._clients = {}
for client in clients:
if client.type == "telegram" and client.enabled:
self._configs[client.name] = client
self._clients[client.name] = Slack(**client.config, name=client.name)
@staticmethod
def get_name() -> str:
return "Slack"
def get_client(self, name: str) -> Optional[Slack]:
"""
获取Telegram客户端
"""
return self._clients.get(name)
def get_config(self, name: str) -> Optional[NotificationConf]:
"""
获取Telegram配置
"""
return self._configs.get(name)
def stop(self):
self.slack.stop()
"""
停止模块
"""
for client in self._clients.values():
client.stop()
def test(self) -> Tuple[bool, str]:
"""
测试模块连接性
"""
state = self.slack.get_state()
if state:
return True, ""
return False, "Slack未就续,请检查参数设置和网络连接"
for name, client in self._clients.items():
state = client.get_state()
if not state:
return False, f"Slack {name} 未就续"
return True, ""
def init_setting(self) -> Tuple[str, Union[str, bool]]:
return "MESSAGER", "slack"
pass
@staticmethod
def message_parser(body: Any, form: Any,
def checkMessage(self, message: Notification, source: str) -> bool:
"""
检查消息渠道及消息类型,如不符合则不处理
"""
# 检查消息渠道
if message.channel and message.channel != self._channel:
return False
# 检查消息来源
if message.source and message.source != source:
return False
# 检查消息类型开关
if message.mtype:
conf = self.get_config(source)
if conf:
switchs = conf.switchs or []
if message.mtype.value not in switchs:
return False
return True
def message_parser(self, body: Any, form: Any,
args: Any) -> Optional[CommingMessage]:
"""
解析消息内容,返回字典,注意以下约定值:
@@ -157,6 +206,14 @@ class SlackModule(_ModuleBase):
]
}
"""
# 来源
source = args.get("source")
if not source:
return None
# 获取客户端
client = self.get_client(source)
if not client:
return None
# 校验token
token = args.get("token")
if not token or token != settings.API_TOKEN:
@@ -189,38 +246,50 @@ class SlackModule(_ModuleBase):
username = msg_json.get("user_name")
else:
return None
logger.info(f"收到Slack消息userid={userid}, username={username}, text={text}")
return CommingMessage(channel=MessageChannel.Slack,
logger.info(f"收到来自 {source}Slack消息userid={userid}, username={username}, text={text}")
return CommingMessage(channel=MessageChannel.Slack, source=source,
userid=userid, username=username, text=text)
return None
@checkMessage(MessageChannel.Slack)
def post_message(self, message: Notification) -> None:
"""
发送消息
:param message: 消息
:return: 成功或失败
"""
self.slack.send_msg(title=message.title, text=message.text,
image=message.image, userid=message.userid, link=message.link)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_msg(title=message.title, text=message.text,
image=message.image, userid=message.userid, link=message.link)
@checkMessage(MessageChannel.Slack)
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> None:
"""
发送媒体信息选择列表
:param message: 消息体
:param medias: 媒体信息
:return: 成功或失败
"""
return self.slack.send_meidas_msg(title=message.title, medias=medias, userid=message.userid)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_meidas_msg(title=message.title, medias=medias, userid=message.userid)
@checkMessage(MessageChannel.Slack)
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> Optional[bool]:
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> None:
"""
发送种子信息选择列表
:param message: 消息体
:param torrents: 种子信息
:return: 成功或失败
"""
return self.slack.send_torrents_msg(title=message.title, torrents=torrents,
userid=message.userid)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_torrents_msg(title=message.title, torrents=torrents,
userid=message.userid)

View File

@@ -41,6 +41,10 @@ class Slack:
self._client = slack_app.client
self._channel = channel
# 标记消息来源
if kwargs.get("name"):
self._ds_url = f"{self._ds_url}&source={kwargs.get('name')}"
# 注册消息响应
@slack_app.event("message")
def slack_message(message):

View File

@@ -1,22 +1,48 @@
from typing import Optional, Union, List, Tuple, Any
from typing import Optional, Union, List, Tuple, Any, Dict
from app.core.context import MediaInfo, Context
from app.helper.notification import NotificationHelper
from app.log import logger
from app.modules import _ModuleBase, checkMessage
from app.modules import _ModuleBase
from app.modules.synologychat.synologychat import SynologyChat
from app.schemas import MessageChannel, CommingMessage, Notification
from app.schemas import MessageChannel, CommingMessage, Notification, NotificationConf
class SynologyChatModule(_ModuleBase):
synologychat: SynologyChat = None
_channel = MessageChannel.Telegram
_configs: Dict[str, NotificationConf] = {}
_clients: Dict[str, SynologyChat] = {}
def init_module(self) -> None:
self.synologychat = SynologyChat()
"""
初始化模块
"""
clients = NotificationHelper().get_notifications()
if not clients:
return
self._configs = {}
self._clients = {}
for client in clients:
if client.type == "telegram" and client.enabled:
self._configs[client.name] = client
self._clients[client.name] = SynologyChat(**client.config)
@staticmethod
def get_name() -> str:
return "Synology Chat"
def get_client(self, name: str) -> Optional[SynologyChat]:
"""
获取Telegram客户端
"""
return self._clients.get(name)
def get_config(self, name: str) -> Optional[NotificationConf]:
"""
获取Telegram配置
"""
return self._configs.get(name)
def stop(self):
pass
@@ -24,13 +50,33 @@ class SynologyChatModule(_ModuleBase):
"""
测试模块连接性
"""
state = self.synologychat.get_state()
if state:
return True, ""
return False, "SynologyChat未就续,请检查参数设置、网络连接以及机器人是否可见"
for name, client in self._clients.items():
state = client.get_state()
if not state:
return False, f"Synology Chat {name} 未就续"
return True, ""
def init_setting(self) -> Tuple[str, Union[str, bool]]:
return "MESSAGER", "synologychat"
pass
def checkMessage(self, message: Notification, source: str) -> bool:
"""
检查消息渠道及消息类型,如不符合则不处理
"""
# 检查消息渠道
if message.channel and message.channel != self._channel:
return False
# 检查消息来源
if message.source and message.source != source:
return False
# 检查消息类型开关
if message.mtype:
conf = self.get_config(source)
if conf:
switchs = conf.switchs or []
if message.mtype.value not in switchs:
return False
return True
def message_parser(self, body: Any, form: Any,
args: Any) -> Optional[CommingMessage]:
@@ -45,12 +91,20 @@ class SynologyChatModule(_ModuleBase):
:return: 渠道、消息体
"""
try:
# 来源
source = args.get("source")
if not source:
return None
client = self.get_client(source)
if not client:
return None
# 解析消息
message: dict = form
if not message:
return None
# 校验token
token = message.get("token")
if not token or not self.synologychat.check_token(token):
if not token or not client.check_token(token):
return None
# 文本
text = message.get("text")
@@ -66,34 +120,46 @@ class SynologyChatModule(_ModuleBase):
logger.debug(f"解析SynologyChat消息失败{str(err)}")
return None
@checkMessage(MessageChannel.SynologyChat)
def post_message(self, message: Notification) -> None:
"""
发送消息
:param message: 消息体
:return: 成功或失败
"""
self.synologychat.send_msg(title=message.title, text=message.text,
image=message.image, userid=message.userid, link=message.link)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_msg(title=message.title, text=message.text,
image=message.image, userid=message.userid, link=message.link)
@checkMessage(MessageChannel.SynologyChat)
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> None:
"""
发送媒体信息选择列表
:param message: 消息体
:param medias: 媒体列表
:return: 成功或失败
"""
return self.synologychat.send_meidas_msg(title=message.title, medias=medias,
userid=message.userid)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_meidas_msg(title=message.title, medias=medias,
userid=message.userid)
@checkMessage(MessageChannel.SynologyChat)
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> Optional[bool]:
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> None:
"""
发送种子信息选择列表
:param message: 消息体
:param torrents: 种子列表
:return: 成功或失败
"""
return self.synologychat.send_torrents_msg(title=message.title, torrents=torrents,
userid=message.userid, link=message.link)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_torrents_msg(title=message.title, torrents=torrents,
userid=message.userid, link=message.link)

View File

@@ -3,44 +3,95 @@ from typing import Optional, Union, List, Tuple, Any, Dict
from app.core.context import MediaInfo, Context
from app.core.config import settings
from app.helper.notification import NotificationHelper
from app.log import logger
from app.modules import _ModuleBase, checkMessage
from app.modules import _ModuleBase
from app.modules.telegram.telegram import Telegram
from app.schemas import MessageChannel, CommingMessage, Notification
from app.schemas import MessageChannel, CommingMessage, Notification, NotificationConf
class TelegramModule(_ModuleBase):
telegram: Telegram = None
_channel = MessageChannel.Telegram
_configs: Dict[str, NotificationConf] = {}
_clients: Dict[str, Telegram] = {}
def init_module(self) -> None:
self.telegram = Telegram()
"""
初始化模块
"""
clients = NotificationHelper().get_notifications()
if not clients:
return
self._configs = {}
self._clients = {}
for client in clients:
if client.type == "telegram" and client.enabled:
self._configs[client.name] = client
self._clients[client.name] = Telegram(**client.config, name=client.name)
@staticmethod
def get_name() -> str:
return "Telegram"
def get_client(self, name: str) -> Optional[Telegram]:
"""
获取Telegram客户端
"""
return self._clients.get(name)
def get_config(self, name: str) -> Optional[NotificationConf]:
"""
获取Telegram配置
"""
return self._configs.get(name)
def stop(self):
self.telegram.stop()
"""
停止模块
"""
for client in self._clients.values():
client.stop()
def test(self) -> Tuple[bool, str]:
"""
测试模块连接性
"""
state = self.telegram.get_state()
if state:
return True, ""
return False, "Telegram未就续,请检查参数设置和网络连接"
for name, client in self._clients.items():
state = client.get_state()
if not state:
return False, f"Telegram {name} 未就续"
return True, ""
def init_setting(self) -> Tuple[str, Union[str, bool]]:
return "MESSAGER", "telegram"
pass
def message_parser(self, body: Any, form: Any,
def checkMessage(self, message: Notification, source: str) -> bool:
"""
检查消息渠道及消息类型,如不符合则不处理
"""
# 检查消息渠道
if message.channel and message.channel != self._channel:
return False
# 检查消息来源
if message.source and message.source != source:
return False
# 检查消息类型开关
if message.mtype:
conf = self.get_config(source)
if conf:
switchs = conf.switchs or []
if message.mtype.value not in switchs:
return False
return True
def message_parser(self, source: str, body: Any, form: Any,
args: Any) -> Optional[CommingMessage]:
"""
解析消息内容,返回字典,注意以下约定值:
userid: 用户ID
username: 用户名
text: 内容
:param source: 消息来源(渠道配置名称)
:param body: 请求体
:param form: 表单
:param args: 参数
@@ -69,6 +120,14 @@ class TelegramModule(_ModuleBase):
}
}
"""
# 获取渠道
client = self.get_client(source)
if not client:
return None
# 获取配置
config = self.get_config(source)
if not config:
return None
# 校验token
token = args.get("token")
if not token or token != settings.API_TOKEN:
@@ -84,59 +143,75 @@ class TelegramModule(_ModuleBase):
# 获取用户名
user_name = message.get("from", {}).get("username")
if text:
logger.info(f"收到Telegram消息userid={user_id}, username={user_name}, text={text}")
logger.info(f"收到来自 {source}Telegram消息userid={user_id}, username={user_name}, text={text}")
# 检查权限
admin_users = config.config.get("admins")
user_list = config.config.get("users")
chat_id = config.config.get("chat_id")
if text.startswith("/"):
if settings.TELEGRAM_ADMINS \
and str(user_id) not in settings.TELEGRAM_ADMINS.split(',') \
and str(user_id) != settings.TELEGRAM_CHAT_ID:
self.telegram.send_msg(title="只有管理员才有权限执行此命令", userid=user_id)
if admin_users \
and str(user_id) not in admin_users.split(',') \
and str(user_id) != chat_id:
client.send_msg(title="只有管理员才有权限执行此命令", userid=user_id)
return None
else:
if settings.TELEGRAM_USERS \
and not str(user_id) in settings.TELEGRAM_USERS.split(','):
if user_list \
and not str(user_id) in user_list.split(','):
logger.info(f"用户{user_id}不在用户白名单中,无法使用此机器人")
self.telegram.send_msg(title="你不在用户白名单中,无法使用此机器人", userid=user_id)
client.send_msg(title="你不在用户白名单中,无法使用此机器人", userid=user_id)
return None
return CommingMessage(channel=MessageChannel.Telegram,
return CommingMessage(channel=MessageChannel.Telegram, source=source,
userid=user_id, username=user_name, text=text)
return None
@checkMessage(MessageChannel.Telegram)
def post_message(self, message: Notification) -> None:
"""
发送消息
:param message: 消息体
:return: 成功或失败
"""
self.telegram.send_msg(title=message.title, text=message.text,
image=message.image, userid=message.userid, link=message.link)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_msg(title=message.title, text=message.text,
image=message.image, userid=message.userid, link=message.link)
@checkMessage(MessageChannel.Telegram)
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> None:
"""
发送媒体信息选择列表
:param message: 消息体
:param medias: 媒体列表
:return: 成功或失败
"""
return self.telegram.send_meidas_msg(title=message.title, medias=medias,
userid=message.userid, link=message.link)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_meidas_msg(title=message.title, medias=medias,
userid=message.userid, link=message.link)
@checkMessage(MessageChannel.Telegram)
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> Optional[bool]:
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> None:
"""
发送种子信息选择列表
:param message: 消息体
:param torrents: 种子列表
:return: 成功或失败
"""
return self.telegram.send_torrents_msg(title=message.title, torrents=torrents,
userid=message.userid, link=message.link)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_torrents_msg(title=message.title, torrents=torrents,
userid=message.userid, link=message.link)
def register_commands(self, commands: Dict[str, dict]):
"""
注册命令,实现这个函数接收系统可用的命令菜单
:param commands: 命令字典
"""
self.telegram.register_commands(commands)
for client in self._clients.values():
client.register_commands(commands)

View File

@@ -41,6 +41,9 @@ class Telegram:
_bot = telebot.TeleBot(self._telegram_token, parse_mode="Markdown")
# 记录句柄
self._bot = _bot
# 标记渠道来源
if kwargs.get("name"):
self._ds_url = f"{self._ds_url}&source={kwargs.get('name')}"
@_bot.message_handler(commands=['start', 'help'])
def send_welcome(message):

View File

@@ -30,7 +30,7 @@ class TransmissionModule(_ModuleBase):
if not downloaders:
return
for server in downloaders:
if server.type == "transmission":
if server.type == "transmission" and server.enabled:
self._servers[server.name] = Transmission(**server.config)
if server.default:
self._default_server_name = server.name

View File

@@ -3,6 +3,7 @@ from typing import Optional, Union, List, Tuple, Any, Dict
from app.core.config import settings
from app.core.context import Context, MediaInfo
from app.helper.notification import NotificationHelper
from app.log import logger
from app.modules import _ModuleBase, checkMessage
from app.modules.vocechat.vocechat import VoceChat
@@ -10,10 +11,19 @@ from app.schemas import MessageChannel, CommingMessage, Notification
class VoceChatModule(_ModuleBase):
vocechat: VoceChat = None
_clients: Dict[str, VoceChat] = {}
def init_module(self) -> None:
self.vocechat = VoceChat()
"""
初始化模块
"""
self._clients = {}
clients = NotificationHelper().get_notifications()
if not clients:
return
for client in clients:
if client.type == "vocechat" and client.enabled:
self._clients[client.name] = VoceChat(**client.config)
@staticmethod
def get_name() -> str:
@@ -32,7 +42,7 @@ class VoceChatModule(_ModuleBase):
return False, "获取VoceChat频道失败"
def init_setting(self) -> Tuple[str, Union[str, bool]]:
return "MESSAGER", "vocechat"
pass
@staticmethod
def message_parser(body: Any, form: Any,

View File

@@ -3,24 +3,50 @@ from typing import Optional, Union, List, Tuple, Any, Dict
from app.core.config import settings
from app.core.context import Context, MediaInfo
from app.helper.notification import NotificationHelper
from app.log import logger
from app.modules import _ModuleBase, checkMessage
from app.modules import _ModuleBase
from app.modules.wechat.WXBizMsgCrypt3 import WXBizMsgCrypt
from app.modules.wechat.wechat import WeChat
from app.schemas import MessageChannel, CommingMessage, Notification
from app.schemas import MessageChannel, CommingMessage, Notification, NotificationConf
from app.utils.dom import DomUtils
class WechatModule(_ModuleBase):
wechat: WeChat = None
_channel = MessageChannel.Wechat
_configs: Dict[str, NotificationConf] = {}
_clients: Dict[str, WeChat] = {}
def init_module(self) -> None:
self.wechat = WeChat()
"""
初始化模块
"""
clients = NotificationHelper().get_notifications()
if not clients:
return
self._configs = {}
self._clients = {}
for client in clients:
if client.type == "wechat" and client.enabled:
self._configs[client.name] = client
self._clients[client.name] = WeChat(**client.config)
@staticmethod
def get_name() -> str:
return "微信"
def get_client(self, name: str) -> Optional[WeChat]:
"""
获取Telegram客户端
"""
return self._clients.get(name)
def get_config(self, name: str) -> Optional[NotificationConf]:
"""
获取Telegram配置
"""
return self._configs.get(name)
def stop(self):
pass
@@ -28,13 +54,14 @@ class WechatModule(_ModuleBase):
"""
测试模块连接性
"""
state = self.wechat.get_state()
if state:
return True, ""
return False, "获取微信token失败"
for name, client in self._clients.items():
state = client.get_state()
if not state:
return False, f"企业微信 {name} 未就续"
return True, ""
def init_setting(self) -> Tuple[str, Union[str, bool]]:
return "MESSAGER", "wechat"
pass
def message_parser(self, body: Any, form: Any,
args: Any) -> Optional[CommingMessage]:
@@ -49,6 +76,14 @@ class WechatModule(_ModuleBase):
:return: 渠道、消息体
"""
try:
# 消息来源
source = args.get("source")
if not source:
return None
# 获取客户端
client = self.get_client(source)
if not client:
return None
# URL参数
sVerifyMsgSig = args.get("msg_signature")
sVerifyTimeStamp = args.get("timestamp")
@@ -113,7 +148,7 @@ class WechatModule(_ModuleBase):
wechat_admins = settings.WECHAT_ADMINS.split(',')
if wechat_admins and not any(
user_id == admin_user for admin_user in wechat_admins):
self.wechat.send_msg(title="用户无权限执行菜单命令", userid=user_id)
client.send_msg(title="用户无权限执行菜单命令", userid=user_id)
return None
# 根据EventKey执行命令
content = DomUtils.tag_value(root_node, "EventKey")
@@ -127,49 +162,81 @@ class WechatModule(_ModuleBase):
if content:
# 处理消息内容
return CommingMessage(channel=MessageChannel.Wechat,
return CommingMessage(channel=MessageChannel.Wechat, source=source,
userid=user_id, username=user_id, text=content)
except Exception as err:
logger.error(f"微信消息处理发生错误:{str(err)}")
return None
@checkMessage(MessageChannel.Wechat)
def checkMessage(self, message: Notification, source: str) -> bool:
"""
检查消息渠道及消息类型,如不符合则不处理
"""
# 检查消息渠道
if message.channel and message.channel != self._channel:
return False
# 检查消息来源
if message.source and message.source != source:
return False
# 检查消息类型开关
if message.mtype:
conf = self.get_config(source)
if conf:
switchs = conf.switchs or []
if message.mtype.value not in switchs:
return False
return True
def post_message(self, message: Notification) -> None:
"""
发送消息
:param message: 消息内容
:return: 成功或失败
"""
self.wechat.send_msg(title=message.title, text=message.text,
image=message.image, userid=message.userid, link=message.link)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_msg(title=message.title, text=message.text,
image=message.image, userid=message.userid, link=message.link)
@checkMessage(MessageChannel.Wechat)
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> None:
"""
发送媒体信息选择列表
:param message: 消息内容
:param medias: 媒体列表
:return: 成功或失败
"""
# 先发送标题
self.wechat.send_msg(title=message.title, userid=message.userid, link=message.link)
# 再发送内容
return self.wechat.send_medias_msg(medias=medias, userid=message.userid)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
# 先发送标题
client.send_msg(title=message.title, userid=message.userid, link=message.link)
# 再发送内容
client.send_medias_msg(medias=medias, userid=message.userid)
@checkMessage(MessageChannel.Wechat)
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> Optional[bool]:
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> None:
"""
发送种子信息选择列表
:param message: 消息内容
:param torrents: 种子列表
:return: 成功或失败
"""
return self.wechat.send_torrents_msg(title=message.title, torrents=torrents,
userid=message.userid, link=message.link)
for conf in self._configs.values():
if not self.checkMessage(message, conf.name):
continue
client = self.get_client(conf.name)
if client:
client.send_torrents_msg(title=message.title, torrents=torrents,
userid=message.userid, link=message.link)
def register_commands(self, commands: Dict[str, dict]):
"""
注册命令,实现这个函数接收系统可用的命令菜单
:param commands: 命令字典
"""
self.wechat.create_menus(commands)
for client in self._clients.values():
client.create_menus(commands)