142 lines
5.3 KiB
Python
142 lines
5.3 KiB
Python
"""
|
|
Facebook API客户端
|
|
封装与RapidAPI Facebook接口的交互
|
|
通过 RapidAPI MCP 服务器调用
|
|
"""
|
|
|
|
import aiohttp
|
|
import json
|
|
from typing import List, Optional
|
|
from loguru import logger
|
|
|
|
# 支持相对导入和绝对导入
|
|
try:
|
|
from ..config import Config
|
|
from ..models.schemas import SearchResultItem
|
|
except ImportError:
|
|
from config import Config
|
|
from models.schemas import SearchResultItem
|
|
|
|
|
|
class FacebookClient:
|
|
"""Facebook API客户端 - 通过 RapidAPI MCP 服务器调用"""
|
|
|
|
def __init__(self, config: Config):
|
|
"""
|
|
初始化客户端
|
|
|
|
Args:
|
|
config: 配置对象
|
|
"""
|
|
self.config = config
|
|
# 使用 RapidAPI MCP 服务器
|
|
self.mcp_url = config.facebook_mcp_url
|
|
self.headers = {
|
|
"x-api-host": config.facebook_api_host,
|
|
"x-api-key": config.facebook_api_key,
|
|
"Content-Type": "application/json"
|
|
}
|
|
self.timeout = aiohttp.ClientTimeout(total=config.timeout)
|
|
|
|
async def search(self, keyword: str, limit: int = 10) -> List[SearchResultItem]:
|
|
"""
|
|
搜索Facebook内容 - 通过 RapidAPI MCP 服务器
|
|
|
|
Args:
|
|
keyword: 搜索关键词
|
|
limit: 返回结果数量限制
|
|
|
|
Returns:
|
|
搜索结果列表
|
|
"""
|
|
try:
|
|
# 通过 RapidAPI MCP 服务器调用 Search_post 工具
|
|
mcp_request = {
|
|
"jsonrpc": "2.0",
|
|
"id": "1",
|
|
"method": "tools/call",
|
|
"params": {
|
|
"name": "Search_post",
|
|
"arguments": {
|
|
"query": keyword,
|
|
"recent_posts": True # 获取最近的帖子
|
|
}
|
|
}
|
|
}
|
|
|
|
async with aiohttp.ClientSession(timeout=self.timeout) as session:
|
|
async with session.post(
|
|
self.mcp_url,
|
|
headers=self.headers,
|
|
json=mcp_request
|
|
) as response:
|
|
if response.status != 200:
|
|
error_text = await response.text()
|
|
logger.error(f"RapidAPI MCP错误: {response.status} - {error_text}")
|
|
raise Exception(f"RapidAPI MCP请求失败: {response.status}")
|
|
|
|
mcp_response = await response.json()
|
|
|
|
# 检查 MCP 响应是否有错误
|
|
if "error" in mcp_response:
|
|
error_msg = mcp_response["error"].get("message", "Unknown error")
|
|
logger.error(f"RapidAPI MCP工具调用错误: {error_msg}")
|
|
raise Exception(f"RapidAPI MCP工具调用失败: {error_msg}")
|
|
|
|
# 解析 MCP 响应
|
|
result = mcp_response.get("result", {})
|
|
content = result.get("content", [])
|
|
|
|
if not content:
|
|
logger.warning(f"搜索关键词 '{keyword}' 未获得结果")
|
|
return []
|
|
|
|
# 第一个 content 包含 JSON 字符串
|
|
content_text = content[0].get("text", "{}")
|
|
data = json.loads(content_text)
|
|
|
|
# 解析搜索结果
|
|
results = []
|
|
items = data.get("results", [])
|
|
|
|
for item in items[:limit]:
|
|
author_info = item.get("author", {})
|
|
reactions = item.get("reactions", {})
|
|
|
|
results.append(SearchResultItem(
|
|
title=item.get("message", "")[:100] or f"Post {item.get('post_id', '')}",
|
|
url=item.get("url", ""),
|
|
snippet=item.get("message", "")[:500],
|
|
author=author_info.get("name", ""),
|
|
likes=reactions.get("like", 0) + reactions.get("love", 0),
|
|
cover_image=item.get("image", {}).get("uri", "") if item.get("image") else None
|
|
))
|
|
|
|
logger.info(f"搜索关键词 '{keyword}' 获得 {len(results)} 条结果")
|
|
return results
|
|
|
|
except json.JSONDecodeError as e:
|
|
logger.error(f"JSON解析错误: {e}")
|
|
raise Exception(f"响应解析失败: {str(e)}")
|
|
except aiohttp.ClientError as e:
|
|
logger.error(f"RapidAPI MCP网络错误: {e}")
|
|
raise Exception(f"网络请求失败: {str(e)}")
|
|
except Exception as e:
|
|
logger.error(f"Facebook搜索异常: {e}")
|
|
raise
|
|
|
|
async def search_by_mcp(self, keyword: str, limit: int = 10) -> List[SearchResultItem]:
|
|
"""
|
|
通过MCP服务器搜索Facebook内容(已弃用,search方法已使用MCP)
|
|
|
|
Args:
|
|
keyword: 搜索关键词
|
|
limit: 返回结果数量限制
|
|
|
|
Returns:
|
|
搜索结果列表
|
|
"""
|
|
# search 方法已经通过 MCP 调用,此方法保留用于兼容性
|
|
return await self.search(keyword, limit)
|
|
|