本篇使用 Flask 架設伺服器,不建議使用,在此僅作記錄用。
上一篇的 Line BOT 簡介中,BOT 可以自動回覆訊息,但功能極為陽春。雖然也可以設定 AI 自動回覆訊息,但這功能將於 2024/05/15 停用。
所以我們必需架設一台伺服器,分析客戶端傳入的內容才決定要如何回應,最終將回應訊息透過 BOT 傳送給客戶端手機,示意圖如下。
Line Channel access token
在底下的伺服器代碼中,有二個很重要的變數要設定,分別是 Line Channel acccess token 及 Line secret。因為 Line 網站上查詢這二個變數的位置有變,所以先說明一下取得的方式。
請先由 https://developers.line.biz/zh-hant/ 選擇 Console,再按下 Messaging API。
接下來再選擇 Messageing API 分頁
往下拉後,會看到 Channel access token,第一次需按下 issue 按鈕產生新的 access token,日後若要變更,可以按下 Reissue。請把 access token 複製記下,等會要填入 python 代碼中的 access_token 變數。
再切換到 Basic settings 分頁
往下拉即可看到 Channel secret,此數字也需記要,要填入後面 python 代碼的 secret 變數中。
Line BOT 設定
請進入 Line BOT 網站的設定/Messaging API,將聊天關掉,Webhook 打開。
Django 伺服器
Webhook Url 最後要加 “/”,比如 https://xxx.ddns.net/line/
本例以 Linux 作為
Flask 伺服器
本例以 Linux 作為說明,請在 Linux 下設定好虛擬環境後,先安裝如下套件
mkdir bot cd bot python3 -m venv .venv source .venv/bin/activate pip install flask line-bot-sdk
然後使用 flask 架設網站,請新增 linebotServer.py 檔案,代碼如下
#!/server/linebot/.venv/bin/python3 from flask import Flask, request import json from linebot import LineBotApi, WebhookHandler from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, TextSendMessage app = Flask(__name__) @app.route("/thomas", methods=['POST']) def thomas(): body = request.get_data(as_text=True) #取得收到的訊息 try: json_data = json.loads(body) # json 格式化訊息內容 access_token = '你的 Line channel access token' secret = '你的 Line secret' line_bot_api = LineBotApi(access_token) # 確認 token 是否正確 handler = WebhookHandler(secret) # 確認 secret 是否正確 signature = request.headers['X-Line-Signature'] # 加入回傳的 headers handler.handle(body, signature) # 綁定訊息回傳的相關資訊 tk = json_data['events'][0]['replyToken'] # 取得回傳訊息的 Token type = json_data['events'][0]['message']['type'] # 取得 LINe 收到的訊息類型 if type=='text': msg = json_data['events'][0]['message']['text'] # 取得 LINE 收到的文字訊息 print(msg) # 印出內容 reply = msg else: reply = '你傳的不是文字呦~' print(reply) line_bot_api.reply_message(tk,TextSendMessage(reply))# 回傳訊息 except: print("error",body) # 如果發生錯誤,印出收到的內容 return 'OK' # 驗證 Webhook 使用,不能省略 if __name__ == "__main__": app.run(host="0.0.0.0", port=7001)
假設你的網域為 https://xxx.ddns.net,則上述的 @app.route(“/thomas“, methods=[“post”]) 表示要連接你的伺服器網域為 https://xxx.ddns.net/thomas,然後函數名稱可以隨便訂。
這樣有個好處,就是你可以一直接其它人的案子,比如客戶的帳號是 jerry,可以依樣寫個 @app.route(‘jerry’, methods=[‘post’]) 及 def jerry(),然後把網域 https://xxx.ddns.net/jerry 發送給客戶,共同使相同的 xxx.ddns.net 網域。
另外 flask 預設使用的 port 為 5000,且不允許外部連線,所以如果要改變 port 及允許外部連線,需改成
app.run(host='0.0.0.0', port=7001)
最後記得要執行此程式,啟動伺服器
Nginx 設定
接下來需設定 Nginx,本例以 Linux 作為說明,請執行如下指令
sudo vim /etc/nginx/sites-available/default
然後在裏面新增如下藍色的設定。請注意,黑色的部份是本人原本就設定好的 php 轉址,而且必需要有 ssl 認証,因為 Line BOT 的 webhook 只接受 https 的協定。
server {
server_name mahalphp.ddns.net;
root /data/server/wordpress;
add_header X-Frame-Options SAMEORIGIN;#禁止網頁被內崁
index index.php index.html;
location ~* \.(ico|css|js|gif|jpe?g|png|ogg|ogv|svg|svgz|eot|otf|woff)(\?.+)?$ {
expires max;
log_not_found off;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location /thomas {
proxy_pass http://localhost:7001;
proxy_set_header Host $http_host;#將客戶端的 HOST 傳入 Django
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mahalphp.ddns.net/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mahalphp.ddns.net/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
最後請重啟 nginx
sudo systemctl restart nginx
設定 ip 分享器
請將 ip 分享器打開,選擇 port forwarding 將 443 port 指向到伺服器 ip。至於 7001 port 則是由 Nginx 在內部進行跳轉,所以不需要 forwarding。
設定 Line BOT Webhook
再次進入 Line BOT 網頁中的 Messaging API,Webhook URL 選 Edit,將網址 https://xxx.ddns.net/thomas 填入,然後按下 Verify 驗証,如果成功就會顯示 success
測試
執行上面的代碼後使用 Line 與 BOT 聊天,此時客戶輸入什麼,BOT 就會以同樣的訊息回應。
開機自動啟動 Python Server
先將 linebotServer.py 改成 755 權限
sudo chmod 755 /server/linebot/linebotServer.py
然後於 /etc/init.d 底下新增 linebot 檔案,內容如下
#!/bin/sh /server/linebot/linebotServer.py
接下來於 rc3.d 目錄下設定軟連結
cd /etc/rc3.d sudo ln -s ../init.d/linebot S99linebot
重新開機後,就會自動啟動 linebotServer.py 伺服器了