# 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():
"""[修改] 渲染一個簡潔的機器人狀態首頁。"""
return """
LINE Bot Server Status
✓ LINE Bot Server is Running
This is the backend service for the Earthquake Alert Bot.
The service is active and listening for webhook events from LINE.
"""
@app.route("/healthz")
def healthz():
"""健康檢查端點。"""
return "ok"
@app.route("/static/")
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。
"""
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
)
)