import os from fastapi import FastAPI, Request, HTTPException from fastapi.middleware.cors import CORSMiddleware from linebot import LineBotApi, WebhookHandler from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, TextSendMessage import logging from backend.services.nlp_service import NLPService from backend.services.database_service import DatabaseService from backend.config import settings from backend.database.connection import test_database_connection # 設定日誌 logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) app = FastAPI(title="LINE Bot API", version="1.0.0") # CORS 設定 app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # LINE Bot 初始化 line_bot_api = LineBotApi(settings.LINE_CHANNEL_ACCESS_TOKEN) handler = WebhookHandler(settings.LINE_CHANNEL_SECRET) # 服務初始化 nlp_service = NLPService() db_service = DatabaseService() @app.get("/") def greet_json(): return {"Hello": "LINE Bot API is running!"} @app.get("/health") def health_check(): # 檢查資料庫連線 db_status = "connected" if test_database_connection() else "disconnected" return { "status": "healthy", "message": "LINE Bot API is operational", "database": db_status, "database_url": f"postgresql://{settings.DB_HOST}:{settings.DB_PORT}/{settings.DB_NAME}" } @app.post("/webhook") async def callback(request: Request): """LINE Bot Webhook 端點""" signature = request.headers.get('X-Line-Signature', '') body = await request.body() try: handler.handle(body.decode('utf-8'), signature) except InvalidSignatureError: logger.error("Invalid signature") raise HTTPException(status_code=400, detail="Invalid signature") return {"status": "ok"} @handler.add(MessageEvent, message=TextMessage) def handle_message(event): """處理 LINE 訊息""" try: user_message = event.message.text user_id = event.source.user_id logger.info(f"收到訊息: {user_message} from {user_id}") # 使用 NLP 服務分析訊息 analysis_result = nlp_service.analyze_message(user_message) # 根據分析結果調用對應的資料庫方法 response_data = db_service.execute_query(analysis_result) # 格式化回應訊息 reply_message = nlp_service.format_response(response_data, analysis_result, user_message) # 回覆訊息 line_bot_api.reply_message( event.reply_token, TextSendMessage(text=reply_message) ) except Exception as e: logger.error(f"處理訊息時發生錯誤: {str(e)}") line_bot_api.reply_message( event.reply_token, TextSendMessage(text="抱歉,處理您的訊息時發生錯誤,請稍後再試。") ) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=7860)