feat:删除消息能力

This commit is contained in:
jxxghp
2025-06-22 09:37:01 +08:00
parent 3d92b57f24
commit bd241a5164
7 changed files with 167 additions and 22 deletions
+14 -1
View File
@@ -22,7 +22,7 @@ from app.helper.service import ServiceConfigHelper
from app.log import logger from app.log import logger
from app.schemas import TransferInfo, TransferTorrent, ExistMediaInfo, DownloadingTorrent, CommingMessage, Notification, \ from app.schemas import TransferInfo, TransferTorrent, ExistMediaInfo, DownloadingTorrent, CommingMessage, Notification, \
WebhookEventInfo, TmdbEpisode, MediaPerson, FileItem, TransferDirectoryConf WebhookEventInfo, TmdbEpisode, MediaPerson, FileItem, TransferDirectoryConf
from app.schemas.types import TorrentStatus, MediaType, MediaImageType, EventType from app.schemas.types import TorrentStatus, MediaType, MediaImageType, EventType, MessageChannel
from app.utils.object import ObjectUtils from app.utils.object import ObjectUtils
@@ -641,6 +641,19 @@ class ChainBase(metaclass=ABCMeta):
return self.messagequeue.send_message("post_torrents_message", message=message, torrents=torrents, return self.messagequeue.send_message("post_torrents_message", message=message, torrents=torrents,
immediately=True if message.userid else False) immediately=True if message.userid else False)
def delete_message(self, channel: MessageChannel, source: str,
message_id: Union[str, int], chat_id: Optional[Union[str, int]] = None) -> bool:
"""
删除消息
:param channel: 消息渠道
:param source: 消息源(指定特定的消息模块)
:param message_id: 消息ID
:param chat_id: 聊天ID(如群组ID
:return: 删除是否成功
"""
return self.run_module("delete_message", channel=channel, source=source,
message_id=message_id, chat_id=chat_id)
def metadata_img(self, mediainfo: MediaInfo, def metadata_img(self, mediainfo: MediaInfo,
season: Optional[int] = None, episode: Optional[int] = None) -> Optional[dict]: season: Optional[int] = None, episode: Optional[int] = None) -> Optional[dict]:
""" """
+12 -2
View File
@@ -1,4 +1,3 @@
import gc
import re import re
from typing import Any, Optional, Dict, Union, List from typing import Any, Optional, Dict, Union, List
@@ -275,6 +274,14 @@ class MessageChain(ChainBase):
_current_page = 0 _current_page = 0
# 保存缓存 # 保存缓存
self.save_cache(user_cache, self._cache_file) self.save_cache(user_cache, self._cache_file)
# 删除原消息
if ChannelCapabilityManager.supports_deletion(channel):
self.delete_message(
channel=channel,
source=source,
message_id=original_message_id,
chat_id=original_chat_id
)
# 发送种子数据 # 发送种子数据
logger.info(f"搜索到 {len(contexts)} 条数据,开始发送选择消息 ...") logger.info(f"搜索到 {len(contexts)} 条数据,开始发送选择消息 ...")
self.__post_torrents_message(channel=channel, self.__post_torrents_message(channel=channel,
@@ -505,6 +512,9 @@ class MessageChain(ChainBase):
""" """
处理按钮回调 处理按钮回调
""" """
global _current_media
# 提取回调数据 # 提取回调数据
callback_data = text[9:] # 去掉 "CALLBACK:" 前缀 callback_data = text[9:] # 去掉 "CALLBACK:" 前缀
logger.info(f"处理按钮回调:{callback_data}") logger.info(f"处理按钮回调:{callback_data}")
@@ -537,7 +547,7 @@ class MessageChain(ChainBase):
text=page_text, text=page_text,
original_message_id=original_message_id, original_chat_id=original_chat_id) original_message_id=original_message_id, original_chat_id=original_chat_id)
else: else:
# 发送新消息 # 处理新消息
self.handle_message(channel=channel, source=source, userid=userid, username=username, self.handle_message(channel=channel, source=source, userid=userid, username=username,
text=page_text) text=page_text)
except IndexError: except IndexError:
+23
View File
@@ -320,3 +320,26 @@ class SlackModule(_ModuleBase, _MessageBase[Slack]):
userid=message.userid, buttons=message.buttons, userid=message.userid, buttons=message.buttons,
original_message_id=message.original_message_id, original_message_id=message.original_message_id,
original_chat_id=message.original_chat_id) original_chat_id=message.original_chat_id)
def delete_message(self, channel: MessageChannel, source: str,
message_id: str, chat_id: Optional[str] = None) -> bool:
"""
删除消息
:param channel: 消息渠道
:param source: 指定的消息源
:param message_id: 消息IDSlack中为时间戳)
:param chat_id: 聊天ID(频道ID
:return: 删除是否成功
"""
success = False
for conf in self.get_configs().values():
if channel != self._channel:
continue
if source != conf.name:
continue
client: Slack = self.get_instance(conf.name)
if client:
result = client.delete_msg(message_id=message_id, chat_id=chat_id)
if result:
success = True
return success
+43 -8
View File
@@ -13,12 +13,10 @@ from app.core.metainfo import MetaInfo
from app.log import logger from app.log import logger
from app.utils.string import StringUtils from app.utils.string import StringUtils
lock = Lock() lock = Lock()
class Slack: class Slack:
_client: WebClient = None _client: WebClient = None
_service: SocketModeHandler = None _service: SocketModeHandler = None
_ds_url = f"http://127.0.0.1:{settings.PORT}/api/v1/message?token={settings.API_TOKEN}" _ds_url = f"http://127.0.0.1:{settings.PORT}/api/v1/message?token={settings.API_TOKEN}"
@@ -433,9 +431,9 @@ class Slack:
meta = MetaInfo(torrent.title, torrent.description) meta = MetaInfo(torrent.title, torrent.description)
link = torrent.page_url link = torrent.page_url
title_text = f"{meta.season_episode} " \ title_text = f"{meta.season_episode} " \
f"{meta.resource_term} " \ f"{meta.resource_term} " \
f"{meta.video_term} " \ f"{meta.video_term} " \
f"{meta.release_group}" f"{meta.release_group}"
title_text = re.sub(r"\s+", " ", title_text).strip() title_text = re.sub(r"\s+", " ", title_text).strip()
free = torrent.volume_factor free = torrent.volume_factor
seeder = f"{torrent.seeders}" seeder = f"{torrent.seeders}"
@@ -493,9 +491,9 @@ class Slack:
meta = MetaInfo(torrent.title, torrent.description) meta = MetaInfo(torrent.title, torrent.description)
link = torrent.page_url link = torrent.page_url
title_text = f"{meta.season_episode} " \ title_text = f"{meta.season_episode} " \
f"{meta.resource_term} " \ f"{meta.resource_term} " \
f"{meta.video_term} " \ f"{meta.video_term} " \
f"{meta.release_group}" f"{meta.release_group}"
title_text = re.sub(r"\s+", " ", title_text).strip() title_text = re.sub(r"\s+", " ", title_text).strip()
free = torrent.volume_factor free = torrent.volume_factor
seeder = f"{torrent.seeders}" seeder = f"{torrent.seeders}"
@@ -552,6 +550,43 @@ class Slack:
logger.error(f"Slack消息发送失败: {msg_e}") logger.error(f"Slack消息发送失败: {msg_e}")
return False return False
def delete_msg(self, message_id: str, chat_id: Optional[str] = None) -> Optional[bool]:
"""
删除Slack消息
:param message_id: 消息时间戳(Slack消息ID
:param chat_id: 频道ID
:return: 删除是否成功
"""
if not self._client:
return None
try:
# 确定要删除消息的频道ID
if chat_id:
target_channel = chat_id
else:
target_channel = self.__find_public_channel()
if not target_channel:
logger.error("无法确定要删除消息的Slack频道")
return False
# 删除消息
result = self._client.chat_delete(
channel=target_channel,
ts=message_id
)
if result.get("ok"):
logger.info(f"成功删除Slack消息: channel={target_channel}, ts={message_id}")
return True
else:
logger.error(f"删除Slack消息失败: {result.get('error', 'unknown error')}")
return False
except Exception as e:
logger.error(f"删除Slack消息异常: {str(e)}")
return False
def __find_public_channel(self): def __find_public_channel(self):
""" """
查找公共频道 查找公共频道
+23
View File
@@ -286,6 +286,29 @@ class TelegramModule(_ModuleBase, _MessageBase[Telegram]):
original_message_id=message.original_message_id, original_message_id=message.original_message_id,
original_chat_id=message.original_chat_id) original_chat_id=message.original_chat_id)
def delete_message(self, channel: MessageChannel, source: str,
message_id: int, chat_id: Optional[int] = None) -> bool:
"""
删除消息
:param channel: 消息渠道
:param source: 指定的消息源
:param message_id: 消息ID
:param chat_id: 聊天ID
:return: 删除是否成功
"""
success = False
for conf in self.get_configs().values():
if channel != self._channel:
continue
if source != conf.name:
continue
client: Telegram = self.get_instance(conf.name)
if client:
result = client.delete_msg(message_id=message_id, chat_id=chat_id)
if result:
success = True
return success
def register_commands(self, commands: Dict[str, dict]): def register_commands(self, commands: Dict[str, dict]):
""" """
注册命令,实现这个函数接收系统可用的命令菜单 注册命令,实现这个函数接收系统可用的命令菜单
+29
View File
@@ -336,6 +336,35 @@ class Telegram:
logger.error(f"回应回调查询失败:{str(e)}") logger.error(f"回应回调查询失败:{str(e)}")
return False return False
def delete_msg(self, message_id: int, chat_id: Optional[int] = None) -> Optional[bool]:
"""
删除Telegram消息
:param message_id: 消息ID
:param chat_id: 聊天ID
:return: 删除是否成功
"""
if not self._telegram_token or not self._telegram_chat_id:
return None
try:
# 确定要删除消息的聊天ID
if chat_id:
target_chat_id = chat_id
else:
target_chat_id = self._telegram_chat_id
# 删除消息
result = self._bot.delete_message(chat_id=target_chat_id, message_id=int(message_id))
if result:
logger.info(f"成功删除Telegram消息: chat_id={target_chat_id}, message_id={message_id}")
return True
else:
logger.error(f"删除Telegram消息失败: chat_id={target_chat_id}, message_id={message_id}")
return False
except Exception as e:
logger.error(f"删除Telegram消息异常: {str(e)}")
return False
def __edit_message(self, chat_id: str, message_id: int, text: str, def __edit_message(self, chat_id: str, message_id: int, text: str,
buttons: Optional[List[List[dict]]] = None, buttons: Optional[List[List[dict]]] = None,
image: Optional[str] = None) -> Optional[bool]: image: Optional[str] = None) -> Optional[bool]:
+12
View File
@@ -145,6 +145,8 @@ class ChannelCapability(Enum):
MENU_COMMANDS = "menu_commands" MENU_COMMANDS = "menu_commands"
# 支持消息编辑 # 支持消息编辑
MESSAGE_EDITING = "message_editing" MESSAGE_EDITING = "message_editing"
# 支持消息删除
MESSAGE_DELETION = "message_deletion"
# 支持回调查询 # 支持回调查询
CALLBACK_QUERIES = "callback_queries" CALLBACK_QUERIES = "callback_queries"
# 支持富文本 # 支持富文本
@@ -182,6 +184,7 @@ class ChannelCapabilityManager:
ChannelCapability.INLINE_BUTTONS, ChannelCapability.INLINE_BUTTONS,
ChannelCapability.MENU_COMMANDS, ChannelCapability.MENU_COMMANDS,
ChannelCapability.MESSAGE_EDITING, ChannelCapability.MESSAGE_EDITING,
ChannelCapability.MESSAGE_DELETION,
ChannelCapability.CALLBACK_QUERIES, ChannelCapability.CALLBACK_QUERIES,
ChannelCapability.RICH_TEXT, ChannelCapability.RICH_TEXT,
ChannelCapability.IMAGES, ChannelCapability.IMAGES,
@@ -205,6 +208,8 @@ class ChannelCapabilityManager:
channel=MessageChannel.Slack, channel=MessageChannel.Slack,
capabilities={ capabilities={
ChannelCapability.INLINE_BUTTONS, ChannelCapability.INLINE_BUTTONS,
ChannelCapability.MESSAGE_EDITING,
ChannelCapability.MESSAGE_DELETION,
ChannelCapability.CALLBACK_QUERIES, ChannelCapability.CALLBACK_QUERIES,
ChannelCapability.RICH_TEXT, ChannelCapability.RICH_TEXT,
ChannelCapability.IMAGES, ChannelCapability.IMAGES,
@@ -290,6 +295,13 @@ class ChannelCapabilityManager:
""" """
return cls.supports_capability(channel, ChannelCapability.MESSAGE_EDITING) return cls.supports_capability(channel, ChannelCapability.MESSAGE_EDITING)
@classmethod
def supports_deletion(cls, channel: MessageChannel) -> bool:
"""
检查渠道是否支持消息删除
"""
return cls.supports_capability(channel, ChannelCapability.MESSAGE_DELETION)
@classmethod @classmethod
def get_max_buttons_per_row(cls, channel: MessageChannel) -> int: def get_max_buttons_per_row(cls, channel: MessageChannel) -> int:
""" """