# Line Bot Lesson 2 - Reply Message
:house: [回筆記首頁](https://www.mirai.tw)
###### tags: `python` `Line` `Bot` `api`
[toc]
試試看這個 line-bot吧!
![LINE-BOT-QR-CODE](https://qr-official.line.me/gs/M_612kbvhf_BW.png)
在上個課程中我們測試了傳給LineBOT的文字訊息時會觸發 MessageEvent, message=TextMessage
,回傳時也是文字訊息。
這次我們要練習回傳一項或多項的文字、圖片、貼圖、位置、聲音、影片與快速選單。
官方文件(https://developers.line.biz/en/reference/messaging-api/#text-message)
### 1. 回傳文字訊息
在下方程式中 TextSendMessage 不用再輸入type參數
```json
Example:
{
"type": "text",
"text": "Hello, world"
}
```
```python=!
可直接回傳文字訊息,也可用QuickReply,不過在PC的Line看不到...
要不要使用這功能自己決定...可以對這個Robot試試@Menu...
message=TextSendMessage(
text='菜單',
quick_reply=QuickReply(
items=[
QuickReplyButton(action=MessageAction(label='咖哩飯',text='咖哩飯')),
QuickReplyButton(action=MessageAction(label='牛肉麵',text='牛肉麵')),
QuickReplyButton(action=MessageAction(label='豬排飯',text='豬排飯')),
QuickReplyButton(action=MessageAction(label='餛飩麵',text='餛飩麵'))
]
)
)
```
### 2. 回傳圖片訊息
在下方程式中 ImageSendMessage 不用再輸入type參數
```json
Example:
{
"type": "sticker",
"packageId": "446",
"stickerId": "1988"
}
```
### 3. 回傳貼圖訊息
在下方程式中 StickerSendMessage 不用再輸入type參數
```json
Example:
{
"type": "image",
"originalContentUrl": "https://example.com/original.jpg",
"previewImageUrl": "https://example.com/preview.jpg"
}
```
貼圖所在位置
https://developers.line.biz/en/docs/messaging-api/sticker-list/#sticker-definitions
### 4. 回傳位置訊息
在下方程式中 LocationSendMessage 不用再輸入type參數
```json
Example:
{
"type": "location",
"title": "my location",
"address": "1-6-1 Yotsuya, Shinjuku-ku, Tokyo, 160-0004, Japan",
"latitude": 35.687574,
"longitude": 139.72922
}
```
### 5. 回傳聲音訊息
在下方程式中 AudioSendMessage 不用再輸入type參數,接收 m4a檔
```json
Example:
{
"type": "audio",
"originalContentUrl": "https://example.com/original.m4a",
"duration": 60000
}
```
### 6. 回傳影片訊息
在下方程式中 VideoSendMessage 不用再輸入type參數
```json
Example:
{
"type": "video",
"originalContentUrl": "https://example.com/original.mp4",
"previewImageUrl": "https://example.com/preview.jpg",
"trackingId": "track-id" (optional)
}
```
建立一個linebot2.py檔(這個範例使用Flask框架)
並複製以下程式碼, 記得要改成你自己的Token&Secret
```python
LINE_CHANNEL_ACCESS_TOKEN='XXXXX'
LINE_CHANNEL_SECRET='XXXXX'
from flask import Flask, request, abort
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError, LineBotApiError
from linebot.models import MessageEvent, MessageAction, TextMessage, TextSendMessage, \
ImageSendMessage, StickerSendMessage, LocationSendMessage, AudioSendMessage, VideoSendMessage
app = Flask(__name__)
line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)
@app.route("/", methods=["POST"])
def callback():
signature = request.headers['X-Line-Signature']
body = request.get_data(as_text=True)
app.logger.info("Request body: ",body)
try:
handler.handle(body, signature)
except InvalidSignatureError:
app.logger.info("Token or Secret is wrong.")
abort(400)
except LineBotApiError as e:
app.logger.info("Error-log: " + str(e))
return 'OK'
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
text=event.message.text
if text=='@Text':
message=TextSendMessage('Thank you!')
else:
message=TextSendMessage(text+',I am Robot')
if text=='@Image':
message=ImageSendMessage('https://whsh.tc.edu.tw/var/file/78/1078/img/1567/logo20211017.png','https://whsh.tc.edu.tw/var/file/78/1078/img/1567/logo20211017.png')
if text=='@Sticker':
message=StickerSendMessage('6325','10979912')
if text=='@Location':
message=LocationSendMessage('文華高中','No 240, Ningxia Rd., Xitun Dist., Taichung City 407, Taiwan ( R.O.C )',24.170274955359506, 120.6598460293551)
if text=='@Audio':
message=AudioSendMessage('https://app3.mirai.tw/static/MyMister.m4a',20000)
if text=='@Video':
message=VideoSendMessage('https://app3.mirai.tw/static/goodday.mp4',\
'https://app3.mirai.tw/static/goodday.jpg')
line_bot_api.reply_message(event.reply_token,message)
```
```bash
執行linebot2.py的方法(Flask官方的建議方法)
```bash=
$ (Linux的bash/csh)
$ export FLASK_APP=linebot2.py
$ export FLASK_DEBUG=on
$ (Windows的power shell)
$ $env:FLASK_APP = "linebot2"
$ $env:FLASK_DEBUG = "on"
$ (Windows的cmd)
$ set FLASK_APP=linebot2
$ 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/callback2)
打開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也是!~~
### C. 以gunicorn產生webhook並填入這個的Webhook URL
先在專案中安裝 gunicron (pip install gunicorn)
再執行
```
gunicorn -w 1 -b 0.0.0.0:8000 -b [::1]:8000 linebot2:app
```
若一切正常,則可以推到背景執行(登出後依然會執行)
```
gunicorn -w 1 -b 0.0.0.0:8000 -b [::1]:8000 linebot2: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": "/callback2"
},
"action": {
"pass":"applications/callback2"
}
},
{
"action": {
"pass": "applications/pythonapp"
}
}
],
"applications": {
"pythonapp": {
"type": "python",
"path": "/home/kevin/app/",
"home": "/home/kevin/env/",
"module": "app",
"user": "kevin",
},
"callback2": {
"type": "python",
"path": "/home/kevin/app/",
"home": "/home/kevin/env/",
"module": "linebot2",
"user": "kevin",
"callable": "app"
}
}
}
```
參考資料: ![reference]: https://qiu-yan-ming.gitbook.io/python-chatbot/shi-yong-line-bot-sdk