Rasbperry Pi 結合 LINE messageing API
使用 LINE 來串接各種 iot 裝置已經是很普遍的應用,這篇文章要說明如何讓 rasbperry Pi 搭配 ngrok (也可改用 heroku) 來串接 LINE messaging API。最初的版本是在PC上執行,當然要換到 Pi 上也是沒問題的,這樣與 pi 互動的方式就更多啦!
建立 LINE messaging API
請用您的LINE帳號登入LINE開發者網站,並於首頁中找到 Messageing API,根據頁面說明來操作。
請根據說明先建立 provider,再建立一個 channel (類型為 messageing API)。這裡比較瑣碎,請按照說明完成各欄位就好:
完成了,這個 channel 叫做 “發發想聊天“,雖然說是聊天,但基本上只是一個回話機器人( echo bot),只會把你丟過去的訊息原封不動傳回來而已。
接下來的設定都會在 [Basic settings] 與 [Messaging API] 兩個標籤下完成,先看到 [Basic settings]:這裡是 channel 基本設定,往下拉會看到 channel secret,這需要紀錄在 .py 檔案中,否則呼叫會失敗。
接著看到 [Messaging API],首先會看到加好友用的 basic ID 與 qrcode,記得先加好友喔!
點選 Auto-reply(自動回復) 右邊的 [Edit]…
這時會新開一個頁面,請依序設定之後回到原本的頁面。
- Auto-response – Disabled (因為要透過程式回復)
- Webhooks – Enabled (允取外部程式掛接)
最後看到頁面最下方的 Channel access token,按一下 issue (派發),就會產生一大串 token,這一樣要寫在 .py 中。完成如下:
於 Pi (Linux)安裝 ngrok (參考資料)
Pi 會使用 ngrok 來掛階 LINE messaging API,使用起來很簡單。本範例作為示範性質,後續如有持續執行或更高頻率存取等進階需求的話,可改用 heroku 或其他軟體。
請開啟 pi terminal 輸入以下指令來安裝並執行 ngrok
wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-arm.zip --no-check-certificate (後者代表不檢查憑證)
unzip ngrok-stable-linux-arm.zip
./ngrok --version (檢查版本,可不做)
接著在8000 port 啟動一個 http 服務用於掛接 LINE messaging API:
請把 https://XXXX.ngrok.io 這一整段複製起來,這就是我們要設定的 webhook。請注意要有 https!
注意每次啟動 ngrok ,forwarding 網址(上述的 XXXX )都會改變,session 在一兩小時後之後也會過期。您也可以改用 heroku 或其他付費服務來有更好更穩定的執行效果。。
接著要回到 LINE Messaging API 來設定 webhook,把上述網址加上 /callback 作為 Webhook URL:
https://XXXX.ngrok.io/callback
app-handler.py
這個程式需要修改 channel_secret 和 channel_access_token,修改 ‘ ‘ 內容即可。
接著會在 message_text(event) 中,透過 line_bot_api.reply_message() 語法,把所接收到的內容 (event.message.text) 搭配 token 直接發送回去,這就是回話機器人的原理啦~
後續的 if (‘開’ == in_w): 這一段可先不理會,這是後續用於掛接 Linkit 7697 等無法直接連接 LINE 等裝置的做法。
# -*- coding: utf-8 -*- #此段可以中文註解,否則會執行錯誤
import os
import sys
from argparse import ArgumentParser
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__)
path=sys.argv[0]
print(path)
led_status = ""
#要改channel_secret和channel_access_token
channel_secret = 'XXX'
channel_access_token = 'OOO'
if channel_secret is None:
print('Specify LINE_CHANNEL_SECRET as environment variable.')
sys.exit(1)
if channel_access_token is None:
print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
sys.exit(1)
line_bot_api = LineBotApi(channel_access_token)
handler = WebhookHandler(channel_secret)
@app.route("/callback", methods=['POST'])
def callback():
# get X-Line-Signature header value
signature = request.headers['X-Line-Signature']
# get request body as text
body = request.get_data(as_text=True)
app.logger.info("Request body: " + body)
# handle webhook body
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
@app.route("/")
def control_led():
global led_status
return led_status
@handler.add(MessageEvent, message=TextMessage)
def message_text(event):
global led_status
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=event.message.text)
)
print (event.message.text)
in_w = event.message.text[0]
#in_w = event.message.text
print (in_w)
if ('開' == in_w):
led_status = '1'
elif('關' == in_w):
led_status = '0'
print ("led狀態:" + led_status)
if __name__ == "__main__":
arg_parser = ArgumentParser(
usage='Usage: python ' + __file__ + ' [--port <port>] [--help]'
)
arg_parser.add_argument('-p', '--port', default=8000, help='port')
arg_parser.add_argument('-d', '--debug', default=False, help='debug')
options = arg_parser.parse_args()
app.run(debug=options.debug, port=options.port)
app_handler.py
執行
執行時,如果您是直接接電腦螢幕,需開啟兩個 terminal,分別執行 ngrok 與 .py。如果是透過 ssh 連入,則需要連入兩次。
請先確認 ngrok 執行起來,webhook 都設定正確之後,再於另一個 terminal 執行以下程式
python app_handler.py
好的,請開啟 LINE 掃描先前建立時的 qrcode 來加入好友吧,丟訊息過去就會回話喔!
grok 頁面也會看到對應的狀態,200 OK 代表一次成功的操作(順利回話了)。
您也可以透過網路瀏覽器開啟 <pi ip>:4040 檢視相關後台畫面
延伸挑戰
請參考 line bot api 要求 raspberry pi 拍一張照片發送回去,挑戰看看吧!之後再寫文章和大家分享囉