chore: initial commit

This commit is contained in:
你的用户名
2025-11-01 21:58:03 +08:00
commit a05a7dd40e
65 changed files with 16590 additions and 0 deletions

181
core/http_server.py Normal file
View File

@@ -0,0 +1,181 @@
#!/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)