Spaces:
Sleeping
Sleeping
| # app.py | |
| # 首先匯入 config,以設定環境變數 | |
| import config | |
| from flask import Flask, request, abort, send_from_directory | |
| from linebot.v3 import WebhookHandler | |
| from linebot.v3.exceptions import InvalidSignatureError | |
| from linebot.v3.messaging import ( | |
| Configuration, ApiClient, MessagingApi, | |
| ReplyMessageRequest | |
| ) | |
| from linebot.v3.webhooks import MessageEvent, TextMessageContent | |
| # 匯入指令處理器 | |
| from command_handler import process_message | |
| # ------------------------------------------------------------------------------ | |
| # Flask & LINE Bot 設定 | |
| # ------------------------------------------------------------------------------ | |
| app = Flask(__name__) | |
| line_config = Configuration(access_token=config.CHANNEL_ACCESS_TOKEN) | |
| handler = WebhookHandler(config.CHANNEL_SECRET) | |
| # ------------------------------------------------------------------------------ | |
| # Web 伺服器路由 | |
| # ------------------------------------------------------------------------------ | |
| def home(): | |
| """渲染首頁,包含說明與狀態。""" | |
| base = (config.HF_SPACE_URL or request.url_root).rstrip("/") | |
| webhook_url = f"{base}/callback" | |
| static_hint = f"{base}/static/<filename>" | |
| channel_ok = "✅" if config.CHANNEL_ACCESS_TOKEN and config.CHANNEL_SECRET else "⚠️" | |
| space_ok = "✅" if config.HF_SPACE_URL else "ℹ️" | |
| return f""" | |
| <!doctype html> | |
| <html lang="zh-Hant"><head> | |
| </html>""" | |
| def healthz(): | |
| """健康檢查端點。""" | |
| return "ok" | |
| def serve_static(filename): | |
| """提供靜態檔案(例如,生成的地圖)。""" | |
| return send_from_directory(config.STATIC_DIR, filename) | |
| # ------------------------------------------------------------------------------ | |
| # LINE Webhook 處理器 | |
| # ------------------------------------------------------------------------------ | |
| def callback(): | |
| """處理來自 LINE 平台的傳入 Webhooks。""" | |
| signature = request.headers.get("X-Line-Signature") | |
| body = request.get_data(as_text=True) | |
| try: | |
| handler.handle(body, signature) | |
| except InvalidSignatureError: | |
| abort(400) | |
| return "OK" | |
| def handle_message(event): | |
| """ | |
| 處理來自使用者的文字訊息並回覆。 | |
| 所有邏輯都委派給 command_handler。 | |
| """ | |
| # 決定用於生成圖片連結的基礎 URL | |
| base_url = request.url_root.rstrip("/") | |
| # 從處理器獲取回覆訊息 | |
| reply_messages = process_message(event.message.text, base_url) | |
| # 發送回覆 | |
| with ApiClient(line_config) as api_client: | |
| line_bot_api = MessagingApi(api_client) | |
| line_bot_api.reply_message_with_http_info( | |
| ReplyMessageRequest( | |
| reply_token=event.reply_token, | |
| messages=reply_messages | |
| ) | |
| ) |