はじめに
これまででAlexaやiPhoneから家電を操作できるようなりました。
しかし、Alexaはともかくsshでコマンド実行などという操作方法は普通の人に理解させることは容易ではありません。
自分だけが使うならともかく、家族など別の人が使うには難易度が高すぎます。
そこでLINEを使う方法を検討します。
LINEであれば誰でも知っていますし、嬉しいことに無料で使用できるAPIも用意されています。
LINE BOTを構築してRaspberry Piと連携させることを実施します。
Raspberry PiでLINE BOTを作るときの問題点
LineBOTとRaspberry Piを接続するには簡単にはできません。
Raspberry PiからLINEにはLINE Notifyで簡単ですが、LINEからRaspberryPiは少々準備が必要です。
まずは方法を検討します。
方法案1. ドメインを取得して公開する
直接Raspberry PiをWebサーバにする方法です。
ある程度簡単ですが、セキュリティリスクが高いです。
下手に公開して攻撃された場合を考えるとあまりやりたくないですね。
また、固定IPを取得する必要があります。
プロパイダによっては月1000~3000円程度オプション料金が必要になります。
私の契約しているプロパイダは固定IPが使えません。
DynamicDNSを使う方法もありますが、あまりローカルを外に晒す行為はしたくないですね。
方法案2. ngrokを使う
ngrokを使えば簡単にlocalhostをhttpsで外部公開することができます。
しかし、簡単にできるのですが、無料で行うには制限があります。
例えばアクセスする際のURLが起動するたびに変わってしまうことです。
つまり、Raspberry Piが再起動した場合必ずLINE Messaging APIのURLを変更する必要があります。
常用には向きません。
有料プランもありますが、今回はパスします。
また、1と同様にセキュリティリスクがあります。
方法案3. クラウドサービスを使う
AWSやAzure、GCPを使うことでもできそうです。
例えばAzure Web Appsや仮想マシンにLINE BOTに応答するサービスを作って、Raspberry Piとの接続にはAzure VPN Gatewayを使うといった方法が挙げられます。
インターネット向けにAzureが接続を受け持ち、家電の操作は裏足からVPNで接続すればこれまでの方法よりはセキュアに使えることができそうです。
しかし、Azure VPNは従量課金です。
どれくらい使うのか想像できないものであまり使いたくはないですね。。。
方法案4. VPSをレンタルする
クラウドが従量課金で怖いなら、定額のVPSを借りればいいじゃない。
ということで、VPSを検討してみます。
VPSを使えば簡単に固定IPを取得できますし、Raspberry PiとVPNで接続すればある程度セキュアな環境が得られそうです。
一番安いWeb AlenaのVPSで一番ランクの低いもので400円程度で運営可能みたいです。
ただし、やはりランニングコストが必要です。
方法案4. Slackを使う
一番有力な案としてSlackを経由してRaspberry Piに接続することを考えます。
Slack BotをRaspberry Pi上で立ち上げて、それにLINEを接続すれば、外部にサーバ公開することなくLINE BOTが使えるかもしれません。
slackbotのセキュリティリスクは今回は考えないことにします。
この方法をやってみます。
構成図
今回やりたいことの大まかな概要図です。
Raspberry PiにSlackbotを構築する
LINEとの接続の前にまずはSlack Botを作る必要があります。
以下のサイトを参考にさせていただきました。ありがとうございます。
SlackでBOTを作成する
以下のURLからSlackにログインしてBOTを作成します。
BOTが作成できたらチャンネルに招待します。
今回はrasp_botというチャンネルを作ってそこに招待しました。
slackbotのインストール
Raspberry Pi 3にpipで導入します。
Slack Botを動かす
Raspberry Piでの設定を行っていきます。
プラグインファイルを作成します。
SlackBotを実行するスクリプトを書きます。
実行してみます。
$ python3 run.py
エラーが無く「start slackbot」と表示されていれば起動完了です。
Slack上で入力してみます。
今回の設定だと、「おはよう」と言うと、「おはよう」と返してくれました。
設定がない「こんばんは」と入れると反応がありません。
直接「こんばんは」とリプライしてみると、「わかりません。」と上で設定したデフォルトの言葉を返しました。
Slackbotを自動起動するようにsystemdに登録する
自動起動するようにサービス化します。
まず、slackbotを起動するシェルスクリプトを書きます。
実行権限も与えておきます。
ディレクトリはご自身の環境にあったものを使用してください。
$ cd /opt/slackbot/
$ vim start_slackbot.sh
$ chmod +x start_slackbot.sh
次に、systemdへ登録します。
$ sudo vim /etc/systemd/system/slackbot.service
自動起動設定と、サービスの起動を行います。
$ sudo systemctl enable slackbot.service
$ sudo start slackbot.service
以下のようにactive となっていれば起動完了です。
pi@raspberrypi3:/opt/slackbot $ sudo systemctl status slackbot.service
● slackbot.service - Slackbot
Loaded: loaded (/etc/systemd/system/slackbot.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2020-09-10 12:47:45 JST; 3s ago
Main PID: 31612 (start_slackbot.)
Tasks: 12 (limit: 2068)
CGroup: /system.slice/slackbot.service
├─31612 /bin/bash /opt/slackbot/start_slackbot.sh
└─31614 python3 run.py
9月 10 12:47:45 raspberrypi3 systemd[1]: Started Slackbot.
pi@raspberrypi3:/opt/slackbot $
これからplugin.pyなどを編集した場合は以下のコマンドで設定を読み込み直す必要があります。
$ sudo systemctl restart slackbot.service
Slackから家電を操作する
これでSlack上からRaspberry Piにアクセスすることができるようになったので、家電を操作してみます。
先程のプラグインファイルを編集して、エアコンの電源を入れるシェルスクリプトを叩いてみます。
plugin.pyを編集します。
subprocessのインポートと新たなコマンドを認識するように記述を追加します。
正規表現で若干の表記ゆれにも対応できるようにします。
実際に実行してみます。
ブログ上では表現できませんが、たしかにエアコンが反応しました。
これで簡単にSlack経由で家電の操作ができるようになりました!
SlackとLINE BOTを連携する
今回の本題はここからです。
SlackではなくLINEから操作したいのです!
LINE Messaging APIの設定などは終わっている前提です。
前回の記事を参照。
Google App Script (GAS)を利用してオウム返しを作る
以下のサイトを参考にさせていただきました。ありがとうございます。
まず、Google Driveからスプレッドシートを作成します。
スプレッドシート名を適当に入力します。
「ツール」からスクリプトエディタを押します。
プロジェクト名を適当に入れて、以下のスクリプトを入れます。
// LINE developersのメッセージ送受信設定に記載のアクセストークン
var ACCESS_TOKEN = '<Your Access Token>';
function doPost(e) {
// WebHookで受信した応答用Token
var replyToken = JSON.parse(e.postData.contents).events[0].replyToken;
// ユーザーのメッセージを取得
var userMessage = JSON.parse(e.postData.contents).events[0].message.text;
// 応答メッセージ用のAPI URL
var url = 'https://api.line.me/v2/bot/message/reply';
UrlFetchApp.fetch(url, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + ACCESS_TOKEN,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': replyToken,
'messages': [{
'type': 'text',
'text': userMessage,
}],
}),
});
return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
公開タブから公開します。
一番下の欄を「全員(匿名ユーザを含む)」を選択します。
今回はなぜか英語表記になったので、「Anyone, even anonymous」を選びます。
最後にデプロイをクリックします。
すると、APIのURLが表示されますので、コピーしておきます。
このURLをLINE Messaging APIのWebhook URLに登録します。
これでLINEにメッセージを送ってみます。
メッセージがおうむ返しされていれば完成です。
こんなに簡単にサーバレスでLINE BOTが作れるなんて・・・感激です。
GASからメッセージの内容をSlackに投稿する
次は、GASからSlackにそのままメッセージを投稿するように設定します。
参考にしたサイトはこちらです。ありがとうございます。
まずはSlackのIncoming WebHooksを登録します。
先程のRaspberry PiのBOTがいるrasp_botのチャネルに投稿するように設定します。
追加すると、Webhook URLが表示されるのでこれをメモっておきます。
先程のGASのスクリプトを少し修正してSlackにポストされるようにします。
LINEのアクセストークンと、SlackのWebhoolURLを忘れずに入れてください。
// LINE developersのメッセージ送受信設定に記載のアクセストークン
var ACCESS_TOKEN = '自分のLINEのアクセストークンを入れてね';
var postUrl = 'slackのWebHookURLを入れてね';
var username = 'LINE'; // 通知時に表示されるユーザー名
var icon = ':globe_with_meridians:'; // 通知時に表示されるアイコン
function doPost(e) {
// WebHookで受信した応答用Token
var replyToken = JSON.parse(e.postData.contents).events[0].replyToken;
// ユーザーのメッセージを取得
var userMessage = JSON.parse(e.postData.contents).events[0].message.text;
// 応答メッセージ用のAPI URL
var url = 'https://api.line.me/v2/bot/message/reply';
UrlFetchApp.fetch(url, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + ACCESS_TOKEN,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': replyToken,
'messages': [{
'type': 'text',
'text': userMessage,
}],
}),
});
sendSlack(userMessage);
return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
function sendSlack(message) {
var jsonData =
{
"username" : username,
"icon_emoji": icon,
"text" : message
};
var payload = JSON.stringify(jsonData);
var options =
{
"method" : "post",
"contentType" : "application/json",
"payload" : payload
};
UrlFetchApp.fetch(postUrl, options);
}
これでもう一度公開しなおします。
Project versionはNewを選択しないと正しくデプロイされないらしいのでNewを選択します。
LINEでもう一度メッセージを送ってみます。
このとき、Raspberry Piで忘れずにslackbotを起動しておきましょう。
Slackで応答があれば完成です!
エアコンもしっかりと反応しました。
あとは実用的な運用にするために、LINEのオウム返しを止めて、Raspberry PiからLINE Notifyに通知を飛ばせば良いでしょう。
LINE BOTの機能を使えばこのようなこともできます。
適当に作ったので文字や画像がずれているのは気にしないでください・・・
ちなみに食事のボタンは以前作成した「今日のご飯は?」スキルです。
LINE Notifyから返信されるようにしています。
LINE BOTが他人に友達登録されると家電を勝手に操作されてしまいます。
LINE BOTの取り扱いにはご注意ください。
以上、LINE BOTで家電を操作する方法でした。
コメント