# Line Bot Lesson 1 - EchoBot :house: [回筆記首頁](https://www.mirai.tw) ###### tags: `python` `Line` `Bot` `Flask` [toc] Line Bot最簡單的範例就是User傳送給 Line Bot 訊息 Line Bot 就會回覆使用相同的訊息.你可以用這個QR-Code試試! ![Echo Bot](https://i.imgur.com/FSQlMk1.jpg) ### 1. 取得Line Bot API 程式所需資訊 Line Bot API 運行需要Chanel Secret & Channel Token, 請先登入 https://developers.line.biz/zh-hant/ 這裡可用Line掃QR-Code登入。 新增Provider之後,再新增一個channel,把它的Secret和Token複製貼到筆記本內,之後會用到。 ```bash Chanel Secret: 在Basic settings選單下面 Chanel Token: 在Messaging API選單下面 若沒出現可以按issue ``` ### 2. 在python中安裝LINE Bot SDK ```bash 先將pip昇到最新版 pip install --upgrade pip 再安裝LINE Bot SDK pip install line-bot-sdk ``` ### 3. 使用Flask建立網站 建立一個echobot.py檔(這個範例使用Flask框架) 並複製以下程式碼, 記得要改成你自己的Token&Secret ```python LINE_CHANNEL_ACCESS_TOKEN='Your channel token' LINE_CHANNEL_SECRET='Your channel secret' from flask import Flask, request, abort from linebot import LineBotApi, WebhookHandler from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, TextSendMessage app = Flask(__name__) line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN) handler = WebhookHandler(LINE_CHANNEL_SECRET) @app.route("/", methods=["POST"]) def webhook_handler(): # verify signature if needed # add logic to handle the request signature = request.headers['X-Line-Signature'] body = request.get_data(as_text=True) try: handler.handle(body, signature) except InvalidSignatureError: abort(code=400,description="An error has been raised") # 或是 abort(400) 也可以... 目的是要回報 Bad Request,至於為什麼是400...請看文章下方... return 'OK' @handler.add(MessageEvent, message=TextMessage) def handling_message(event): line_bot_api.reply_message(event.reply_token, TextSendMessage(text=event.message.text)) ``` ```bash 執行echobot.py的方法(Flask官方的建議方法) ```bash= $ (Linux的bash/csh) $ export FLASK_APP=echobot.py $ export FLASK_DEBUG=on $ (Windows的power shell) $ $env:FLASK_APP = "echobot" $ $env:FLASK_DEBUG = "on" $ (Windows的cmd) $ set FLASK_APP=echobot $ set FLASK_DEBUG=on ``` 然後執行 $ flask run --port 8000 在開發階段可加上debug可使得flask具備Hot reload功能,不需要一直關閉與重啟。 # 接下來發佈在server上,我們提供3個方法 ### A. 使用ngrok產生webhook並填入這個的Webhook URL 用 [ngrok](https://hackmd.io/@CSL/Hk6aDDQdi) 產生外部鏈結,並在Line的開發網頁中填入這個的Webhook URL (http://URI) 打開Line,加入這個LineBot,測試一下... 它會在server中出現相關 log(紀錄) ``` 從line_api傳來的message body裡面有 > "events": [{ "type":"message", "message":{"type":"text","id":"17294665296744","text":"ABCD\\nedfg\\ncccc\\nddd"}, "webhookEventId":"01GM8GEBNKYT83GP0QJZXYFJ45", "deliveryContext":{"isRedelivery":false}, "timestamp":1671027961089, "source":{"type":"user","userId":"Uc25b496581627ebc921e47b5f6bb5f62"}, "replyToken":"11550933970e4e86aff9f29921463a3b", "mode":"active" }] ``` ### B. 使用deta.sh產生webhook並填入這個的Webhook URL 將程式推送到deta.sh中,方法可參閱 [將LineBot發布到 Deta.sh 中](https://hackmd.io/@CSL/HJcsPvhOj) ~~我現在所有的linebot都放在這裡......這個bot也是!~~ 後記:deta以改變使用方法,我已經放棄這個服務! ### C. 以gunicorn產生webhook並填入這個的Webhook URL 先在專案中安裝 gunicron (pip install gunicorn) 再執行 ``` gunicorn -w 1 -b 0.0.0.0:8000 -b [::1]:8000 echobot:app ``` 若一切正常,則可以推到背景執行(登出後依然會執行) ``` gunicorn -w 1 -b 0.0.0.0:8000 -b [::1]:8000 echobot:app --daemon ``` 其中 (-b 0.0.0.0:port)-ipv4 (-b [::1]:port)-ipv6 可用下列指令查看使用者userid在背景中執行的程式 ``` lsof -i -P | grep userid ``` ### D. 安裝在 Unit/NGINX中 將下面的config.json 寫入unit設定中 ```curl -X PUT --data-binary @config.json --unix-socket /var/run/control.unit.sock http://localhost/config``` ```jsonld= { "listeners": { "*:80": { "pass": "routes" } }, "routes": [ { "match": { "uri": "/static/*" }, "action": { "share": "/home/kevin$uri" } }, { "match": { "uri": "/callback" }, "action": { "pass":"applications/callback" } }, { "action": { "pass": "applications/pythonapp" } } ], "applications": { "pythonapp": { "type": "python", "path": "/home/kevin/app/", "home": "/home/kevin/env/", "module": "app", "user": "kevin", }, "callback": { "type": "python", "path": "/home/kevin/app/", "home": "/home/kevin/env/", "module": "callback", "user": "kevin", "callable": "app" } } } ``` 常見的 HTTP Status code ``` 200 OK :成功 204 No Content :成功,但沒有回傳的內容 4xx : Client 端錯誤 400 Bad Request :請求語法錯誤 401 Unauthorized :未認證 403 Forbidden :沒有權限 404 Not Found :找不到 5xx : Server 端錯誤 500 Internal Server Error :伺服器出錯 502 Bad Gateway :通常是伺服器的某個服務沒有正確執行 503 Service Unavailable :伺服器臨時維護或是掛了無法處理請求 504 Gateway Timeout:伺服器上的服務沒有回應 ``` 參考資料: ![reference]: https://qiu-yan-ming.gitbook.io/python-chatbot/shi-yong-line-bot-sdk