perf: 对于 Telegram 群聊,将回复机器人的消息视为唤醒机器人 (#2926)
* reply as at for tg Add handling for bot replies in group messages. * style: type checking and ruff format --------- Co-authored-by: Soulter <905617992@qq.com>
This commit is contained in:
@@ -95,9 +95,8 @@ class TelegramPlatformAdapter(Platform):
|
||||
|
||||
@override
|
||||
def meta(self) -> PlatformMetadata:
|
||||
return PlatformMetadata(
|
||||
name="telegram", description="telegram 适配器", id=self.config.get("id")
|
||||
)
|
||||
id_ = self.config.get("id") or "telegram"
|
||||
return PlatformMetadata(name="telegram", description="telegram 适配器", id=id_)
|
||||
|
||||
@override
|
||||
async def run(self):
|
||||
@@ -117,6 +116,10 @@ class TelegramPlatformAdapter(Platform):
|
||||
)
|
||||
self.scheduler.start()
|
||||
|
||||
if not self.application.updater:
|
||||
logger.error("Telegram Updater is not initialized. Cannot start polling.")
|
||||
return
|
||||
|
||||
queue = self.application.updater.start_polling()
|
||||
logger.info("Telegram Platform Adapter is running.")
|
||||
await queue
|
||||
@@ -194,6 +197,11 @@ class TelegramPlatformAdapter(Platform):
|
||||
return cmd_name, description
|
||||
|
||||
async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
if not update.effective_chat:
|
||||
logger.warning(
|
||||
"Received a start command without an effective chat, skipping /start reply."
|
||||
)
|
||||
return
|
||||
await context.bot.send_message(
|
||||
chat_id=update.effective_chat.id, text=self.config["start_message"]
|
||||
)
|
||||
@@ -206,15 +214,20 @@ class TelegramPlatformAdapter(Platform):
|
||||
|
||||
async def convert_message(
|
||||
self, update: Update, context: ContextTypes.DEFAULT_TYPE, get_reply=True
|
||||
) -> AstrBotMessage:
|
||||
) -> AstrBotMessage | None:
|
||||
"""转换 Telegram 的消息对象为 AstrBotMessage 对象。
|
||||
|
||||
@param update: Telegram 的 Update 对象。
|
||||
@param context: Telegram 的 Context 对象。
|
||||
@param get_reply: 是否获取回复消息。这个参数是为了防止多个回复嵌套。
|
||||
"""
|
||||
if not update.message:
|
||||
logger.warning("Received an update without a message.")
|
||||
return None
|
||||
|
||||
message = AstrBotMessage()
|
||||
message.session_id = str(update.message.chat.id)
|
||||
|
||||
# 获得是群聊还是私聊
|
||||
if update.message.chat.type == ChatType.PRIVATE:
|
||||
message.type = MessageType.FRIEND_MESSAGE
|
||||
@@ -225,10 +238,13 @@ class TelegramPlatformAdapter(Platform):
|
||||
# Topic Group
|
||||
message.group_id += "#" + str(update.message.message_thread_id)
|
||||
message.session_id = message.group_id
|
||||
|
||||
message.message_id = str(update.message.message_id)
|
||||
_from_user = update.message.from_user
|
||||
if not _from_user:
|
||||
logger.warning("[Telegram] Received a message without a from_user.")
|
||||
return None
|
||||
message.sender = MessageMember(
|
||||
str(update.message.from_user.id), update.message.from_user.username
|
||||
str(_from_user.id), _from_user.username or "Unknown"
|
||||
)
|
||||
message.self_id = str(context.bot.username)
|
||||
message.raw_message = update
|
||||
@@ -247,22 +263,32 @@ class TelegramPlatformAdapter(Platform):
|
||||
)
|
||||
reply_abm = await self.convert_message(reply_update, context, False)
|
||||
|
||||
message.message.append(
|
||||
Comp.Reply(
|
||||
id=reply_abm.message_id,
|
||||
chain=reply_abm.message,
|
||||
sender_id=reply_abm.sender.user_id,
|
||||
sender_nickname=reply_abm.sender.nickname,
|
||||
time=reply_abm.timestamp,
|
||||
message_str=reply_abm.message_str,
|
||||
text=reply_abm.message_str,
|
||||
qq=reply_abm.sender.user_id,
|
||||
if reply_abm:
|
||||
message.message.append(
|
||||
Comp.Reply(
|
||||
id=reply_abm.message_id,
|
||||
chain=reply_abm.message,
|
||||
sender_id=reply_abm.sender.user_id,
|
||||
sender_nickname=reply_abm.sender.nickname,
|
||||
time=reply_abm.timestamp,
|
||||
message_str=reply_abm.message_str,
|
||||
text=reply_abm.message_str,
|
||||
qq=reply_abm.sender.user_id,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if update.message.text:
|
||||
# 处理文本消息
|
||||
plain_text = update.message.text
|
||||
if (
|
||||
message.type == MessageType.GROUP_MESSAGE
|
||||
and update.message
|
||||
and update.message.reply_to_message
|
||||
and update.message.reply_to_message.from_user
|
||||
and update.message.reply_to_message.from_user.id == context.bot.id
|
||||
):
|
||||
plain_text2 = f"/@{context.bot.username} " + plain_text
|
||||
plain_text = plain_text2
|
||||
|
||||
# 群聊场景命令特殊处理
|
||||
if plain_text.startswith("/"):
|
||||
@@ -328,15 +354,25 @@ class TelegramPlatformAdapter(Platform):
|
||||
|
||||
elif update.message.document:
|
||||
file = await update.message.document.get_file()
|
||||
message.message = [
|
||||
Comp.File(file=file.file_path, name=update.message.document.file_name),
|
||||
]
|
||||
file_name = update.message.document.file_name or uuid.uuid4().hex
|
||||
file_path = file.file_path
|
||||
if file_path is None:
|
||||
logger.warning(
|
||||
f"Telegram document file_path is None, cannot save the file {file_name}."
|
||||
)
|
||||
else:
|
||||
message.message.append(Comp.File(file=file_path, name=file_name))
|
||||
|
||||
elif update.message.video:
|
||||
file = await update.message.video.get_file()
|
||||
message.message = [
|
||||
Comp.Video(file=file.file_path, path=file.file_path),
|
||||
]
|
||||
file_name = update.message.video.file_name or uuid.uuid4().hex
|
||||
file_path = file.file_path
|
||||
if file_path is None:
|
||||
logger.warning(
|
||||
f"Telegram video file_path is None, cannot save the file {file_name}."
|
||||
)
|
||||
else:
|
||||
message.message.append(Comp.Video(file=file_path, path=file.file_path))
|
||||
|
||||
return message
|
||||
|
||||
|
||||
Reference in New Issue
Block a user