diff --git a/ai_chat.db b/ai_chat.db index 2cde05c..e6c3e50 100644 Binary files a/ai_chat.db and b/ai_chat.db differ diff --git a/services/__pycache__/matrix_service.cpython-310.pyc b/services/__pycache__/matrix_service.cpython-310.pyc index 7e6b654..e4f2e78 100644 Binary files a/services/__pycache__/matrix_service.cpython-310.pyc and b/services/__pycache__/matrix_service.cpython-310.pyc differ diff --git a/services/matrix_service.py b/services/matrix_service.py index cfc98be..8e32b48 100644 --- a/services/matrix_service.py +++ b/services/matrix_service.py @@ -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): """断开连接"""