Fix bug: Agent process message correctly in Telegeram Gorup

This commit is contained in:
Liu Zhicong
2023-10-01 02:09:44 -07:00
parent 55b2701faa
commit 431f0d4ff2
6 changed files with 247 additions and 58 deletions
+89 -37
View File
@@ -5,7 +5,7 @@ import uuid
import time
import aiofiles
from telegram import Update
from telegram import Update,Message
from telegram import Bot
from telegram.ext import Updater
from telegram.error import Forbidden, NetworkError
@@ -17,7 +17,7 @@ from .knowledge_base import KnowledgeBase
from .tunnel import AgentTunnel
from .storage import AIStorage
from .contact_manager import ContactManager,Contact,FamilyMember
from .agent_message import AgentMsg
from .agent_message import AgentMsg,AgentMsgType
logger = logging.getLogger(__name__)
@@ -79,6 +79,7 @@ class TelegramTunnel(AgentTunnel):
logger.info(f"tunnel {self.tunnel_id} is starting...")
self.bot = Bot(self.tg_token)
self.bot_username = (await self.bot.get_me()).username
self.update_queue = asyncio.Queue()
self.bot_updater = Updater(self.bot,update_queue=self.update_queue)
@@ -114,21 +115,62 @@ class TelegramTunnel(AgentTunnel):
async def _process_message(self, msg: AgentMsg) -> None:
logger.warn(f"process message {msg.msg_id} from {msg.sender} to {msg.target}")
async def conver_tg_msg_to_agent_msg(self,update:Update) -> AgentMsg:
async def conver_tg_msg_to_agent_msg(self,message:Message) -> AgentMsg:
agent_msg = AgentMsg()
agent_msg.topic = "_telegram"
agent_msg.msg_id = "tg_msg#" + str(update.message.message_id) + "#" + uuid.uuid4().hex
agent_msg.msg_id = "tg_msg#" + str(message.message_id) + "#" + uuid.uuid4().hex
agent_msg.target = self.target_id
agent_msg.body = update.message.text
agent_msg.body = message.text
agent_msg.create_time = time.time()
#if update.message.photo is not None:
# agent_msg.body_mime = "image"
# agent_msg.body = update.message.photo[-1].get_file().download()
messag_type = message.chat.type
if messag_type == "supergroup" or messag_type == "group":
agent_msg.target = f"tg_group{message.chat_id}"
agent_msg.msg_type = AgentMsgType.TYPE_GROUPMSG
agent_msg.mentions = []
else:
agent_msg.msg_type = AgentMsgType.TYPE_MSG
if message.entities:
for entity in message.entities:
if entity.type == 'mention':
mention = message.text[entity.offset:entity.offset+entity.length]
if mention == '@' + self.bot_username:
agent_msg.mentions.append(self.target_id)
else:
agent_msg.mentions.append(mention)
if message.caption_entities:
for entity in message.caption_entities:
if entity.type == 'mention':
mention = message.caption[entity.offset:entity.offset+entity.length]
if mention == '@' + self.bot_username:
agent_msg.mentions.append(self.target_id)
else:
agent_msg.mentions.append(mention)
return agent_msg
def is_bot_mentioned(self,message:Message):
if message.entities:
for entity in message.entities:
if entity.type == 'mention':
mention = message.text[entity.offset:entity.offset+entity.length]
if mention == '@' + self.bot_username:
return True
if message.caption_entities:
for entity in message.caption_entities:
if entity.type == 'mention':
mention = message.caption[entity.offset:entity.offset+entity.length]
if mention == '@' + self.bot_username:
return True
return False
async def on_message(self, bot:Bot, update: Update) -> None:
message = update.message
logger.info(f"on_message: {message.message_id} from {message.from_user.username} ({update.effective_user.username}) to {message.chat.title}({message.chat.id})")
if update.effective_user.is_bot:
logger.warning(f"ignore message from telegram bot {update.effective_user.id}")
return None
@@ -139,12 +181,9 @@ class TelegramTunnel(AgentTunnel):
self.in_process_tg_msg[update.message.message_id] = True
agent_msg = await self.conver_tg_msg_to_agent_msg(message)
cm : ContactManager = ContactManager.get_instance()
reomte_user_name = f"{update.effective_user.id}@telegram"
#owner_tg_username = AIStorage.get_instance().get_user_config().get_value("telegram")
#owner_name = AIStorage.get_instance().get_user_config().get_value("username")
contact : Contact = cm.find_contact_by_telegram(update.effective_user.username)
if contact is None:
@@ -173,37 +212,50 @@ class TelegramTunnel(AgentTunnel):
cm.add_contact(contact.name, contact)
reomte_user_name = contact.name
agent_msg = await self.conver_tg_msg_to_agent_msg(update)
agent_msg.sender = reomte_user_name
self.ai_bus.register_message_handler(reomte_user_name, self._process_message)
#await bot.send_chat_action(chat_id=update.effective_chat.id, action="typing")
resp_msg = await self.ai_bus.send_message(agent_msg)
logger.info(f"process message {agent_msg.msg_id} from {agent_msg.sender} to {agent_msg.target}")
if agent_msg.msg_type == AgentMsgType.TYPE_GROUPMSG:
self.ai_bus.register_message_handler(agent_msg.target, self._process_message)
resp_msg = await self.ai_bus.send_message(agent_msg,self.target_id,agent_msg.target)
else:
self.ai_bus.register_message_handler(reomte_user_name, self._process_message)
resp_msg = await self.ai_bus.send_message(agent_msg)
#await bot.send_chat_action(chat_id=update.effective_chat.id, action="typing")
if resp_msg is None:
await update.message.reply_text(f"System Error: Timeout,{self.target_id} no resopnse! Please check logs/aios.log for more details!")
else:
if resp_msg.body_mime is None:
if resp_msg.body is not None:
knowledge_object = KnowledgeBase().parse_object_in_message(resp_msg.body)
if knowledge_object is not None:
if knowledge_object.get_object_type() == ObjectType.Image:
image = KnowledgeBase().bytes_from_object(knowledge_object)
try:
async with aiofiles.open("tg_send_temp.png", mode='wb') as local_file:
if local_file:
await local_file.write(image)
await update.message.reply_photo("tg_send_temp.png")
except Exception as e:
logger.error(f"save image error: {e}")
return
else:
pos = resp_msg.body.find("audio file")
if pos != -1:
audio_file = resp_msg.body[pos+11:].strip()
if audio_file.startswith("\""):
audio_file = audio_file[1:-1]
await update.message.reply_voice(audio_file)
return
if resp_msg.body is None:
return
if len(resp_msg.body) < 1:
await update.message.reply_text("")
return
knowledge_object = KnowledgeBase().parse_object_in_message(resp_msg.body)
if knowledge_object is not None:
if knowledge_object.get_object_type() == ObjectType.Image:
image = KnowledgeBase().bytes_from_object(knowledge_object)
try:
async with aiofiles.open("tg_send_temp.png", mode='wb') as local_file:
if local_file:
await local_file.write(image)
await update.message.reply_photo("tg_send_temp.png")
except Exception as e:
logger.error(f"save image error: {e}")
return
else:
pos = resp_msg.body.find("audio file")
if pos != -1:
audio_file = resp_msg.body[pos+11:].strip()
if audio_file.startswith("\""):
audio_file = audio_file[1:-1]
await update.message.reply_voice(audio_file)
return
await update.message.reply_text(resp_msg.body)
else:
if resp_msg.body_mime.startswith("image"):