# 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建立網站
建立一個app.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
執行app.py的方法(Flask官方的建議方法)
```bash=
$ (Linux的bash/csh)
$ export FLASK_APP=app.py
$ export FLASK_DEBUG=on
$ (Windows的power shell)
$ $env:FLASK_APP = "app"
$ $env:FLASK_DEBUG = "on"
$ (Windows的cmd)
$ set FLASK_APP=app
$ set FLASK_DEBUG=on
```
然後執行
$ flask run --port 8000
(記得檢查是否有安裝flask,用pip list檢查看看)
在開發階段可加上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