#はじめに
この記事は全4章からなる記事の第2章です。
- IoTを駆使してお年寄りの家を見守る「だけじゃない」システムを作った【SORACOM Summer Challenge 2020】
- LTE-M Buttonが押されたらLINE BotへPushメッセージを送る【SORACOM】 今ココ
- 【Raspberry Pi】人感センサーが感知したらtimestampをFirebase Realtime Databaseに格納する
-
SORACOMと家電とLINE Botを連携させる【Python / Flask / Raspberry Pi】 全ソース公開
#きっかけ
離れて暮らす年老いた親に何かがあったときにLTE-M Buttonが押されるという想定です。SORACOM LagoonからLINE Notifyに通知をする機能はありますが、テキストメッセージで通知が来るだけでその後のアクションを選択できないのでLINE Botを作ることにしました。
このようにボタンが1つだけというシンプルな機構だと機械が苦手なお年寄りでも見た目でわかるのでいいですね。
動作環境
Raspberry Pi 3 Model B
Python 3.7.3
Flask==1.1.2
line-bot-sdk==1.16.0
LTE-M ButtonとLINE Botを連携するまで
###① SORACOM Lagoonからアラートを発する
具体的な使い方に関しては公式のSORACOM Lagoon を利用してダッシュボードを作成するとSORACOM Lagoon を利用してアラートを設定するに詳しく書かれているので割愛させていただきます。
LTE-M Buttonは1クリックが1、ダブルクリックが2、長押しが3というInt型のデータが送信されます。今回は緊急時ですからどんなボタン操作が行われるかわかりません。そこで、値が0.5以上(すべてのボタン操作)でアラートを送るという形にしました(画像参照)。
また、通知チャンネルではWebhook
を選択します。URLは後で設定するので今はhttps://test.example
とでもしておいてください。
② LINE Botを登録する
LINE Developersから新しいChannelを作成します。「Choose a channel type to continue」ではMessaging APIとしてください。
Basic settings
にあるChannel secret
とMessaging API
のChannel access token
は後で使うので控えておいてください。
③ ラズパイをサーバとして使う
Raspberry Pi上でFlaskを動かしてWebhookを受け取ったり、メッセージを返したりします。各種設定は[Python・ラズパイでLINE BOTを作ってみる!](Python・ラズパイでLINE BOTを作ってみる!)に従ってください。
注意点
上記サイト、pyenv-virtualenvの設定は無視してもいいですが、それ以外の.bash_profile等の書き換えは必ず行ってください。そうでないと動きません。
また、上記サイト内にも書かれているようにChannel secretやChannel access tokenは環境変数に設定するようにしてください。
④ Pushメッセージを送る
Pushメッセージを送るにはuserId
を知る必要があります。このuserId
は個人で任意に設定した、友だち追加するときに使うIDとは別物ですので別の方法で知る必要があります。
次のコードを使えばテキストメッセージを送るとuserId
を返してくれます。
from flask import Flask, request, abort
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage
import os
app = Flask(__name__)
LINE_BOT_ACCESS_TOKEN = os.environ["LINE_BOT_ACCESS_TOKEN"]
LINE_BOT_CHANNEL_SECRET = os.environ["LINE_BOT_CHANNEL_SECRET"]
line_bot_api = LineBotApi(LINE_BOT_ACCESS_TOKEN)
handler = WebhookHandler(LINE_BOT_CHANNEL_SECRET)
@app.route("/callback", 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:
abort(400)
return 'OK'
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
profile = line_bot_api.get_profile(event.source.user_id)
messages = str(profile.user_id)
line_bot_api.reply_message(event.reply_token, TextSendMessage(text=messages))
if __name__ == "__main__":
port = int(os.getenv("PORT", 6000))
app.run(host="0.0.0.0", port=port)
きちんと設定できていればこのようにUから始まるIDが返ってくるはずです。
ここまでできたら、ようやくSORACOM Lagoonとの連携です。
先ほどのコードに少し追記します。/webhook
にPOST
があったときにユーザにPushメッセージを送れるようにします。import
も追加しているので注意してください。
from flask import Flask, request, abort
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage
import os
import json #追加
app = Flask(__name__)
LINE_BOT_ACCESS_TOKEN = os.environ["LINE_BOT_ACCESS_TOKEN"]
LINE_BOT_CHANNEL_SECRET = os.environ["LINE_BOT_CHANNEL_SECRET"]
line_bot_api = LineBotApi(LINE_BOT_ACCESS_TOKEN)
handler = WebhookHandler(LINE_BOT_CHANNEL_SECRET)
# 以下追記
@app.route("/webhook", methods=['POST'])
def webhook():
print(json.dumps(request.get_json(), indent=2))
object = request.get_json()
if object['title'] == "[Alerting] Emergency alert":
user_id = "U03xxxxxx(先ほど取得したuserId)"
messages = TextSendMessage(text="アラートがきました")
line_bot_api.push_message(user_id, messages=messages)
return request.get_data()
# ここまで
@app.route("/callback", 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:
abort(400)
return 'OK'
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
profile = line_bot_api.get_profile(event.source.user_id)
messages = str(profile.user_id)
line_bot_api.reply_message(event.reply_token, TextSendMessage(text=messages))
if __name__ == "__main__":
port = int(os.getenv("PORT", 6000))
app.run(host="0.0.0.0", port=port)
最後にSORACOM Lagoonの通知チャネルを設定します。
Raspberry Pi上で動かしてるngrokのURLを入力し、末尾に/webhook
を追加します。こうすることでLagoonからのWebhookを受け取ることができます。
デモ動画
[YouTube] SORACOM LTE-M Buttonを押すとLINEへ通知する
予想以上に反応が早い!これなら緊急時に1秒でも早く行動することができますね。