File size: 2,955 Bytes
f1e04a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7f3ee3b
f1e04a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4804f0f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# 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 伺服器路由
# ------------------------------------------------------------------------------
@app.route("/", methods=["GET"])
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>"""

@app.route("/healthz")
def healthz():
    """健康檢查端點。"""
    return "ok"

@app.route("/static/<path:filename>")
def serve_static(filename):
    """提供靜態檔案(例如,生成的地圖)。"""
    return send_from_directory(config.STATIC_DIR, filename)

# ------------------------------------------------------------------------------
# LINE Webhook 處理器
# ------------------------------------------------------------------------------
@app.route("/callback", methods=["POST"])
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"

@handler.add(MessageEvent, message=TextMessageContent)
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
            )
        )