import os import threading import logging import uvicorn from fastapi import FastAPI, Request, HTTPException, Header from linebot import LineBotApi, WebhookHandler from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, TextSendMessage from model import classify_esi # นำเข้าโมเดลที่โหลดไว้แล้ว # ตั้งค่า Logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # โหลด Environment Variables LINE_ACCESS_TOKEN = os.getenv("LINE_ACCESS_TOKEN") LINE_CHANNEL_SECRET = os.getenv("LINE_CHANNEL_SECRET") # Initialize FastAPI app = FastAPI() # Initialize LINE SDK line_bot_api = LineBotApi(LINE_ACCESS_TOKEN) handler = WebhookHandler(LINE_CHANNEL_SECRET) @app.get("/") async def root(): return {"message": "Triage Bot is running for the ER of San Pa Tong Hospital!"} @app.post("/webhook") async def webhook(request: Request, x_line_signature: str = Header(None)): if not x_line_signature: raise HTTPException(status_code=400, detail="Missing X-Line-Signature") body = await request.body() body_text = body.decode("utf-8") # Log ข้อความที่ได้รับจาก LINE logger.info(f"Received webhook event: {body_text}") try: # ✅ ตอบกลับ LINE ทันที เพื่อป้องกัน Timeout threading.Thread(target=handle_webhook, args=(body_text, x_line_signature)).start() return {"status": "OK"} except Exception as e: logger.error(f"Error processing webhook: {e}") return {"status": "Error"}, 500 def handle_webhook(body_text, x_line_signature): """ ฟังก์ชันประมวลผล Webhook แยกต่างหาก """ try: handler.handle(body_text, x_line_signature) except InvalidSignatureError: logger.error("Invalid signature error") except Exception as e: logger.error(f"Error handling webhook: {e}") # Event handler สำหรับข้อความที่ได้รับ @handler.add(MessageEvent, message=TextMessage) def handle_message(event): user_message = event.message.text logger.info(f"User message: {user_message}") # Log ข้อความจากผู้ใช้ esi_level = classify_esi(user_message) # ใช้โมเดล AI วิเคราะห์ ESI response_text = get_triage_response(esi_level) logger.info(f"Bot response: {response_text}") # Log ข้อความที่บอทจะส่ง # ใช้ threading เพื่อให้ bot ตอบกลับเร็วขึ้น threading.Thread(target=reply_message, args=(event.reply_token, response_text)).start() def reply_message(reply_token, message): """ ส่งข้อความตอบกลับผู้ใช้ """ try: line_bot_api.reply_message(reply_token, TextSendMessage(text=message)) logger.info("Reply sent successfully") # Log เมื่อส่งสำเร็จ except Exception as e: logger.error(f"Error sending reply: {e}") def get_triage_response(esi_level): """ รับค่า ESI (1-5) และแปลงเป็นข้อความแนะนำให้ผู้ป่วย """ if esi_level in [1, 2]: return "🚑 อาการของคุณรุนแรง ควรรีบไปห้องฉุกเฉินทันที!" elif esi_level == 3: return "🏥 คุณควรพบแพทย์เร็วที่สุดเพื่อตรวจสอบเพิ่มเติม" elif esi_level in [4, 5]: return "😊 อาการของคุณสามารถรอพบแพทย์ที่ OPD ในวันพรุ่งนี้เช้าได้" else: return "❓ ไม่สามารถประเมินได้ กรุณาลองอธิบายอาการให้ละเอียดขึ้น" if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=7860)