-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
92 lines (73 loc) · 2.72 KB
/
Copy pathapp.py
File metadata and controls
92 lines (73 loc) · 2.72 KB
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
86
87
88
89
90
91
92
"""
app.py
------
LINE Messaging API webhook(Flask)。收到文字訊息就回覆股價 / 新聞 / 展望。
"""
import os
import logging
from flask import Flask, request, abort
from linebot.v3 import WebhookHandler
from linebot.v3.exceptions import InvalidSignatureError
from linebot.v3.messaging import (
Configuration,
ApiClient,
MessagingApi,
ReplyMessageRequest,
TextMessage,
ShowLoadingAnimationRequest,
)
from linebot.v3.webhooks import MessageEvent, TextMessageContent
from services import build_reply
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
CHANNEL_SECRET = os.environ.get("LINE_CHANNEL_SECRET")
CHANNEL_ACCESS_TOKEN = os.environ.get("LINE_CHANNEL_ACCESS_TOKEN")
if not CHANNEL_SECRET or not CHANNEL_ACCESS_TOKEN:
logger.warning(
"尚未設定 LINE_CHANNEL_SECRET / LINE_CHANNEL_ACCESS_TOKEN,webhook 會無法運作。"
)
app = Flask(__name__)
configuration = Configuration(access_token=CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(CHANNEL_SECRET or "dummy")
@app.route("/", methods=["GET"])
def health():
"""健康檢查 / 讓部署平台知道服務活著。"""
return "LINE stock bot is running.", 200
@app.route("/callback", methods=["POST"])
def callback():
signature = request.headers.get("X-Line-Signature", "")
body = request.get_data(as_text=True)
try:
handler.handle(body, signature)
except InvalidSignatureError:
logger.warning("簽章驗證失敗,請確認 Channel secret。")
abort(400)
return "OK"
@handler.add(MessageEvent, message=TextMessageContent)
def handle_message(event):
user_text = event.message.text
with ApiClient(configuration) as api_client:
line_bot_api = MessagingApi(api_client)
# 顯示「輸入中…」動畫,讓使用者知道在查詢(best-effort)
try:
user_id = getattr(event.source, "user_id", None)
if user_id:
line_bot_api.show_loading_animation(
ShowLoadingAnimationRequest(chat_id=user_id, loading_seconds=30)
)
except Exception as e: # noqa: BLE001
logger.info("loading 動畫略過: %s", e)
try:
reply_text = build_reply(user_text)
except Exception as e: # noqa: BLE001
logger.exception("build_reply 發生錯誤")
reply_text = "查詢時發生錯誤,請稍後再試 🙏"
line_bot_api.reply_message(
ReplyMessageRequest(
reply_token=event.reply_token,
messages=[TextMessage(text=reply_text)],
)
)
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app.run(host="0.0.0.0", port=port)