| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- import os
- import json
- import logging
- import asyncio
- import sys
- from typing import Optional
- # 将项目根目录添加到 python 路径,确保可以作为独立脚本运行
- PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..", ".."))
- if PROJECT_ROOT not in sys.path:
- sys.path.append(PROJECT_ROOT)
- from agent.tools.builtin.feishu.feishu_client import FeishuClient, FeishuMessageEvent, FeishuDomain
- from agent.tools.builtin.feishu.chat import (
- FEISHU_APP_ID,
- FEISHU_APP_SECRET,
- get_contact_by_id,
- load_chat_history,
- save_chat_history,
- update_unread_count,
- _convert_feishu_msg_to_openai_content
- )
- # 配置日志
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
- logger = logging.getLogger("FeishuWebsocket")
- class FeishuMessageListener:
- def __init__(self):
- self.client = FeishuClient(
- app_id=FEISHU_APP_ID,
- app_secret=FEISHU_APP_SECRET,
- domain=FeishuDomain.FEISHU
- )
- def handle_incoming_message(self, event: FeishuMessageEvent):
- """处理收到的飞书消息事件"""
- # 1. 识别联系人
- # 优先使用 sender_open_id 匹配联系人,如果没有则尝试 chat_id
- contact = get_contact_by_id(event.sender_open_id) or get_contact_by_id(event.chat_id)
-
- if not contact:
- logger.warning(f"收到未知发送者的消息: open_id={event.sender_open_id}, chat_id={event.chat_id}")
- # 对于未知联系人,我们可以选择忽略,或者记录到 'unknown' 分类
- contact = {"name": "未知联系人", "open_id": event.sender_open_id}
- contact_name = contact.get("name")
- logger.info(f"收到来自 [{contact_name}] 的消息: {event.content[:50]}...")
- # 2. 转换为 OpenAI 多模态格式
- # 构造一个类似 get_message_list 返回的字典对象,以便重用转换逻辑
- msg_dict = {
- "message_id": event.message_id,
- "content_type": event.content_type,
- "content": event.content, # 对于 text, websocket 传来的已经是解析后的字符串;对于 image 则是原始 JSON 字符串
- "sender_id": event.sender_open_id,
- "sender_type": "user" # WebSocket 收到的一般是用户消息,除非是机器人自己的回显(通常会过滤)
- }
-
- openai_content = _convert_feishu_msg_to_openai_content(self.client, msg_dict)
- # 3. 维护聊天记录
- history = load_chat_history(contact_name)
- new_message = {
- "role": "user",
- "message_id": event.message_id,
- "timestamp": os.path.getmtime(os.path.join(os.path.dirname(__file__), "chat.py")), # 简单模拟一个时间戳,实际应使用事件时间
- "content": openai_content
- }
- history.append(new_message)
- save_chat_history(contact_name, history)
- # 4. 更新未读计数
- update_unread_count(contact_name, increment=1)
- logger.info(f"已更新 [{contact_name}] 的聊天记录并增加未读计数")
- def start(self):
- """启动监听"""
- logger.info("正在启动飞书消息实时监听...")
- try:
- self.client.start_websocket(
- on_message=self.handle_incoming_message,
- blocking=True
- )
- except KeyboardInterrupt:
- logger.info("监听已停止")
- except Exception as e:
- logger.error(f"监听过程中出现错误: {e}")
- if __name__ == "__main__":
- listener = FeishuMessageListener()
- listener.start()
|