fix: 修复messages类型问题和设备验证问题
1. 使用 get_conversation_history 返回字典列表 2. send_message 增加设备验证回退机制 3. 当 nio 发送失败时回退到 HTTP API 依赖:python-olm, cachetools, atomicwrites, peewee
This commit is contained in:
Binary file not shown.
@@ -106,53 +106,48 @@ class MatrixBot:
|
||||
"""处理加密消息(MegolmEvent)"""
|
||||
logger.info(f"收到加密消息: [{room.room_id}] event_id={event.event_id}")
|
||||
|
||||
# 打印 event 的所有属性来调试
|
||||
logger.info(f"MegolmEvent属性: {dir(event)}")
|
||||
logger.info(f"event.source: {event.source}")
|
||||
logger.info(f"event.sender: {event.sender}")
|
||||
logger.info(f"event.session_id: {event.session_id if hasattr(event, 'session_id') else 'N/A'}")
|
||||
# 检查是否已解密
|
||||
logger.info(f"event.decrypted: {event.decrypted}")
|
||||
|
||||
# 尝试从不同来源获取消息内容
|
||||
try:
|
||||
body = None
|
||||
sender = event.sender
|
||||
|
||||
# 方法1: 从 source 获取
|
||||
if hasattr(event, 'source') and event.source:
|
||||
content = event.source.get('content', {})
|
||||
body = content.get('body', '')
|
||||
sender = event.source.get('sender', event.sender)
|
||||
logger.info(f"从source获取: body={body[:50] if body else 'empty'}")
|
||||
# 方法1: 检查 decrypted 属性
|
||||
if event.decrypted:
|
||||
logger.info(f"消息已解密: {event.decrypted}")
|
||||
# 使用 parse_decrypted_event 获取解密后的完整事件
|
||||
try:
|
||||
decrypted_event = event.parse_decrypted_event(event.decrypted)
|
||||
if decrypted_event:
|
||||
logger.info(f"解密事件类型: {type(decrypted_event)}")
|
||||
if hasattr(decrypted_event, 'body'):
|
||||
body = decrypted_event.body
|
||||
sender = decrypted_event.sender if hasattr(decrypted_event, 'sender') else event.sender
|
||||
logger.info(f"从 decrypted 获取: {body}")
|
||||
except Exception as e:
|
||||
logger.warning(f"parse_decrypted_event 失败: {e}")
|
||||
|
||||
# 方法2: 直接尝试 event.body (nio可能已解密)
|
||||
if hasattr(event, 'body') and event.body:
|
||||
# 方法2: 从 source 获取(如果是自己发的消息)
|
||||
if not body and hasattr(event, 'source') and event.source:
|
||||
content = event.source.get('content', {})
|
||||
# 检查是否有 plaintext body
|
||||
if 'body' in content:
|
||||
body = content.get('body', '')
|
||||
sender = event.source.get('sender', event.sender)
|
||||
logger.info(f"从source.content获取: {body[:50] if body else 'empty'}")
|
||||
|
||||
# 方法3: 直接尝试 event.body (某些情况下可能有)
|
||||
if not body and hasattr(event, 'body') and event.body:
|
||||
body = event.body
|
||||
logger.info(f"从event.body获取: {body[:50]}")
|
||||
|
||||
# 方法3: 检查 room 中的最近事件
|
||||
if not body:
|
||||
# 从 room timeline 查找解密后的消息
|
||||
for timeline_event in room.timeline:
|
||||
if hasattr(timeline_event, 'event_id') and timeline_event.event_id == event.event_id:
|
||||
if hasattr(timeline_event, 'body'):
|
||||
body = timeline_event.body
|
||||
logger.info(f"从room.timeline获取: {body[:50] if body else 'empty'}")
|
||||
|
||||
if body:
|
||||
logger.info(f"解密成功: sender={sender}, body={body[:50]}")
|
||||
await self._process_message(room, sender, body, event.event_id)
|
||||
else:
|
||||
logger.warning(f"加密消息无法解密,event_id={event.event_id}")
|
||||
# 尝试手动解密
|
||||
try:
|
||||
decrypted = await self.client.decrypt_event(event)
|
||||
if decrypted and hasattr(decrypted, 'body'):
|
||||
body = decrypted.body
|
||||
sender = decrypted.sender
|
||||
logger.info(f"手动解密成功: {body[:50]}")
|
||||
await self._process_message(room, sender, body, event.event_id)
|
||||
except Exception as de:
|
||||
logger.error(f"手动解密失败: {de}")
|
||||
logger.warning(f"加密消息无法解密: event_id={event.event_id}")
|
||||
logger.warning(f"event.decrypted={event.decrypted}, 需要密钥")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"处理加密消息失败: {e}")
|
||||
@@ -235,8 +230,8 @@ class MatrixBot:
|
||||
except Exception as e:
|
||||
logger.warning(f"发送输入状态失败: {e}")
|
||||
|
||||
# 获取AI回复
|
||||
messages = conv_service.get_messages(conversation.id)
|
||||
# 获取AI回复 - 使用字典格式
|
||||
messages = conv_service.get_conversation_history(conversation.conversation_id)
|
||||
ai_response = await ai_service.chat(messages)
|
||||
|
||||
# 保存AI回复
|
||||
@@ -287,6 +282,7 @@ class MatrixBot:
|
||||
return False
|
||||
|
||||
try:
|
||||
# 先尝试直接发送
|
||||
await self.client.room_send(
|
||||
room_id,
|
||||
"m.room.message",
|
||||
@@ -298,10 +294,52 @@ class MatrixBot:
|
||||
logger.info(f"Matrix消息发送成功: {room_id}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"发送Matrix消息错误: {e}")
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
error_str = str(e)
|
||||
if "not verified" in error_str or "OlmUnverifiedDeviceError" in error_str:
|
||||
logger.warning(f"设备未验证,尝试验证设备后发送: {e}")
|
||||
try:
|
||||
# 验证所有未验证的设备
|
||||
for user_id, devices in self.client.device_store.items():
|
||||
for device_id, device in devices.items():
|
||||
if not device.verified:
|
||||
logger.info(f"验证设备: {user_id} {device_id}")
|
||||
self.client.verify_device(device)
|
||||
|
||||
# 再次尝试发送
|
||||
await self.client.room_send(
|
||||
room_id,
|
||||
"m.room.message",
|
||||
{
|
||||
"msgtype": "m.text",
|
||||
"body": message
|
||||
}
|
||||
)
|
||||
logger.info(f"Matrix消息发送成功(验证设备后): {room_id}")
|
||||
return True
|
||||
except Exception as e2:
|
||||
logger.error(f"验证设备后发送仍失败: {e2}")
|
||||
# 最后尝试用 HTTP API 发送(不加密)
|
||||
try:
|
||||
import httpx
|
||||
async with httpx.AsyncClient() as http_client:
|
||||
txn_id = f"m{int(asyncio.get_event_loop().time() * 1000)}"
|
||||
resp = await http_client.put(
|
||||
f"{self.homeserver}/_matrix/client/v3/rooms/{room_id}/send/m.room.message/{txn_id}",
|
||||
headers={"Authorization": f"Bearer {self.client.access_token}"},
|
||||
json={"msgtype": "m.text", "body": message}
|
||||
)
|
||||
if resp.status_code == 200:
|
||||
logger.info(f"Matrix消息通过HTTP发送成功: {room_id}")
|
||||
return True
|
||||
else:
|
||||
logger.error(f"HTTP发送失败: {resp.status_code}")
|
||||
return False
|
||||
except Exception as e3:
|
||||
logger.error(f"HTTP发送失败: {e3}")
|
||||
return False
|
||||
else:
|
||||
logger.error(f"发送Matrix消息错误: {e}")
|
||||
return False
|
||||
|
||||
async def disconnect(self):
|
||||
"""断开连接"""
|
||||
|
||||
Reference in New Issue
Block a user