182 lines
6.0 KiB
Python
182 lines
6.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Funstat MCP HTTP Server
|
|
提供 HTTP API 接口,使 funstat 功能可以通过 HTTP 调用
|
|
"""
|
|
|
|
import asyncio
|
|
import json
|
|
import logging
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Dict, Any
|
|
from aiohttp import web
|
|
from server import FunstatMCPServer
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# 全局 MCP 服务器实例
|
|
mcp_server = None
|
|
|
|
async def initialize_mcp_server():
|
|
"""初始化 MCP 服务器"""
|
|
global mcp_server
|
|
|
|
api_id = int(os.getenv('TELEGRAM_API_ID', '24660516'))
|
|
api_hash = os.getenv('TELEGRAM_API_HASH', 'eae564578880a59c9963916ff1bbbd3a')
|
|
session_path = os.getenv('SESSION_PATH', os.path.expanduser('~/telegram_sessions/funstat_bot'))
|
|
|
|
mcp_server = FunstatMCPServer(api_id, api_hash, session_path)
|
|
await mcp_server.connect()
|
|
logger.info("✅ Funstat MCP Server 初始化完成")
|
|
|
|
async def handle_search(request):
|
|
"""搜索群组/频道"""
|
|
try:
|
|
data = await request.json()
|
|
keyword = data.get('keyword', '')
|
|
use_cache = data.get('use_cache', True)
|
|
|
|
result = await mcp_server.search(keyword, use_cache)
|
|
return web.json_response({'success': True, 'data': result})
|
|
except Exception as e:
|
|
logger.error(f"搜索失败: {e}")
|
|
return web.json_response({'success': False, 'error': str(e)}, status=500)
|
|
|
|
async def handle_topchat(request):
|
|
"""获取热门聊天"""
|
|
try:
|
|
data = await request.json()
|
|
category = data.get('category', 'all')
|
|
use_cache = data.get('use_cache', True)
|
|
|
|
result = await mcp_server.topchat(category, use_cache)
|
|
return web.json_response({'success': True, 'data': result})
|
|
except Exception as e:
|
|
logger.error(f"获取热门聊天失败: {e}")
|
|
return web.json_response({'success': False, 'error': str(e)}, status=500)
|
|
|
|
async def handle_text(request):
|
|
"""按消息文本搜索"""
|
|
try:
|
|
data = await request.json()
|
|
text = data.get('text', '')
|
|
use_cache = data.get('use_cache', True)
|
|
|
|
result = await mcp_server.search_text(text, use_cache)
|
|
return web.json_response({'success': True, 'data': result})
|
|
except Exception as e:
|
|
logger.error(f"文本搜索失败: {e}")
|
|
return web.json_response({'success': False, 'error': str(e)}, status=500)
|
|
|
|
async def handle_human(request):
|
|
"""按姓名搜索"""
|
|
try:
|
|
data = await request.json()
|
|
name = data.get('name', '')
|
|
use_cache = data.get('use_cache', True)
|
|
|
|
result = await mcp_server.search_human(name, use_cache)
|
|
return web.json_response({'success': True, 'data': result})
|
|
except Exception as e:
|
|
logger.error(f"姓名搜索失败: {e}")
|
|
return web.json_response({'success': False, 'error': str(e)}, status=500)
|
|
|
|
async def handle_user_info(request):
|
|
"""查询用户详情"""
|
|
try:
|
|
data = await request.json()
|
|
user_id = data.get('user_id', '')
|
|
use_cache = data.get('use_cache', True)
|
|
|
|
result = await mcp_server.user_info(user_id, use_cache)
|
|
return web.json_response({'success': True, 'data': result})
|
|
except Exception as e:
|
|
logger.error(f"用户查询失败: {e}")
|
|
return web.json_response({'success': False, 'error': str(e)}, status=500)
|
|
|
|
async def handle_balance(request):
|
|
"""查看积分余额"""
|
|
try:
|
|
data = await request.json()
|
|
use_cache = data.get('use_cache', True)
|
|
|
|
result = await mcp_server.balance(use_cache)
|
|
return web.json_response({'success': True, 'data': result})
|
|
except Exception as e:
|
|
logger.error(f"查询余额失败: {e}")
|
|
return web.json_response({'success': False, 'error': str(e)}, status=500)
|
|
|
|
async def handle_menu(request):
|
|
"""显示菜单"""
|
|
try:
|
|
data = await request.json()
|
|
use_cache = data.get('use_cache', True)
|
|
|
|
result = await mcp_server.menu(use_cache)
|
|
return web.json_response({'success': True, 'data': result})
|
|
except Exception as e:
|
|
logger.error(f"获取菜单失败: {e}")
|
|
return web.json_response({'success': False, 'error': str(e)}, status=500)
|
|
|
|
async def handle_start(request):
|
|
"""欢迎消息"""
|
|
try:
|
|
data = await request.json()
|
|
use_cache = data.get('use_cache', True)
|
|
|
|
result = await mcp_server.start(use_cache)
|
|
return web.json_response({'success': True, 'data': result})
|
|
except Exception as e:
|
|
logger.error(f"获取欢迎消息失败: {e}")
|
|
return web.json_response({'success': False, 'error': str(e)}, status=500)
|
|
|
|
async def handle_health(request):
|
|
"""健康检查"""
|
|
return web.json_response({
|
|
'status': 'ok',
|
|
'server': 'funstat-mcp',
|
|
'connected': mcp_server is not None and mcp_server.client.is_connected()
|
|
})
|
|
|
|
async def on_startup(app):
|
|
"""应用启动时初始化"""
|
|
await initialize_mcp_server()
|
|
|
|
async def on_cleanup(app):
|
|
"""应用关闭时清理"""
|
|
if mcp_server:
|
|
await mcp_server.client.disconnect()
|
|
logger.info("MCP Server 已断开连接")
|
|
|
|
def create_app():
|
|
"""创建 Web 应用"""
|
|
app = web.Application()
|
|
|
|
# 注册路由
|
|
app.router.add_post('/funstat/search', handle_search)
|
|
app.router.add_post('/funstat/topchat', handle_topchat)
|
|
app.router.add_post('/funstat/text', handle_text)
|
|
app.router.add_post('/funstat/human', handle_human)
|
|
app.router.add_post('/funstat/user_info', handle_user_info)
|
|
app.router.add_post('/funstat/balance', handle_balance)
|
|
app.router.add_post('/funstat/menu', handle_menu)
|
|
app.router.add_post('/funstat/start', handle_start)
|
|
app.router.add_get('/health', handle_health)
|
|
|
|
# 注册启动和清理回调
|
|
app.on_startup.append(on_startup)
|
|
app.on_cleanup.append(on_cleanup)
|
|
|
|
return app
|
|
|
|
if __name__ == '__main__':
|
|
port = int(os.getenv('FUNSTAT_PORT', '8090'))
|
|
app = create_app()
|
|
logger.info(f"🚀 启动 Funstat HTTP Server 在端口 {port}")
|
|
web.run_app(app, host='127.0.0.1', port=port)
|