# 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": "image", "originalContentUrl": "https://example.com/original.jpg", "previewImageUrl": "https://example.com/preview.jpg" } ``` ### 3. 回傳貼圖訊息 在下方程式中 StickerSendMessage 不用再輸入type參數 ```json Example: { "type": "sticker", "packageId": "446", "stickerId": "1988" } ``` 貼圖所在位置 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