こちらの続きです。
LINEのメッセージをGoogleHomeで読み上げる RaspberryPiセットアップ編
前回までのあらすじ
- Raspberry Pi3 Model B をセットアップ済み
- MacBook Air OSX Yosemite(10.10.5)
- ラズパイにNode.jsをインストール済み
- google-home-notifierが動くことをごくカンタンに確認済み
- Macとラズパイはssh接続したmacのターミナル、またはVNC接続した画面越しに行う(ラズパイにマウスとキーボードをつないでいないため)
今回やりたいこと
LINEのメッセージを読み上げて欲しい!
幸い、ジャストヒットな記事があったのでこちらに沿ってやってみます。
LINEに送信したメッセージを、Google Homeで読み上げ、家族に通知
1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest
1. LINEのbot(Messaging API)を作成する
IFTTTでLINEをトリガーにできればよかったのですが、どうやらできないようです。代わりにbotに話しかけることをトリガーするとのこと。
具体的な作成手順は参考にした記事の通りなので、割愛します。
ポイントは以下です。
- プラン → Developer Trial
- Webhook送信 → 利用する
- 自動応答メッセージ → 利用しない
- 作ったbotと友達になる
2. Node.jsのプロジェクト作成
今回のソースを保存しておく任意のディレクトリを作成します。
- ラズパイに任意のディレクトリを作り、作業ディレクトリとする。
- 作業ディレクトリ内でNode.jsの設定ファイルを作成する npm init
- いろいろ聞かれるが適当にEnter連打でとりあえずOK
- 作業ディレクトリ内でコマンド実行
npm install google-home-notifier ngrok @line/bot-sdk express
今回はgoogle-home-notifierの他にngrok, @line/bot-sdk, expressの3つも利用します。
そして、作業ディレクトリ内に以下のファイルを作製します。
'use strict';
const express = require('express');
const line = require('@line/bot-sdk');
const googlehome = require('google-home-notifier');
// for express
const port = 3000; // ngrokのポートと合わせる
const app = express();
// for LINE
const config = {
channelSecret: '', // Messaging APIのChannel Secret
channelAccessToken: '' // Messaging APIのアクセストークン(ロングターム)
};
const replyPrefixText = 'メッセージを受け付けました : ';
// for googlehome
const language = 'ja';
googlehome.device('Google Home', language);
googlehome.ip('192.168.XXX.XXX', language); // google home のIPを設定する
const speakPrefixText = '新しいメッセージです。';
app.post('/webhook', line.middleware(config), (req, res) => {
console.log(req.body.events);
Promise
.all(req.body.events.map(handleEvent))
.then((result) => res.json(result));
});
const client = new line.Client(config);
function handleEvent(event) {
if (!checkEvent(event)) {
return Promise.resolve(null);
}
return googlehomeSpeak(event.message.text)
.then(speakedText => lineReplyMessage(event.replyToken, speakedText));
}
function checkEvent(event){
if(event.type !== 'message') return false;
if(event.message.type !== 'text') return false;
// LINE の Channel基本設定 から「接続確認」をするとreplyTokenが以下の固定値になるらしい
// 実在しないreplyTokenなので応答しないようにfalseを返す
if(event.replyToken === '00000000000000000000000000000000') return false;
if(event.replyToken === 'ffffffffffffffffffffffffffffffff') return false;
return true;
}
function googlehomeSpeak(text) {
return new Promise((resolve, reject) => {
googlehome.notify(speakPrefixText + text, (res) => {
console.log('googlehome response : ' + res + ', speech_text : ' + text);
resolve(text);
});
});
}
function lineReplyMessage(replyToken, text) {
return client.replyMessage(replyToken, {
type: 'text',
text: replyPrefixText + text
});
}
app.listen(port);
console.log(`Server running at ${port}`);
以下の記事を参考にさせていただきました。
LINEに送信したメッセージを、Google Homeで読み上げ、家族に通知
1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest
promiseでgoogle homeでしゃべる→LINEに返信するという順番に動作するよう制御したので、LINEで返信が来る=google homeでしゃべっているということになります。
3. Messaging APIのセキュリティ情報をコピーする
上記のserver.jsはLINEのセキュリティ情報を設定する箇所があります。
先程作製したMessaging APIの「Channel基本設定」画面から以下の値をserver.jsにコピーします。
コピー元(LINEのChannel基本設定画面)
- Channel Secret
- アクセストークン(ロングターム)
※最初は未設定なのですぐ横のボタンで発行します
コピー先
// for LINE
const config = {
channelSecret: '', // Messaging APIのChannel Secret
channelAccessToken: '' // Messaging APIのアクセストークン(ロングターム)
};
これでserver.jsが完成です。
4. ngrokに会員登録しauthtokenを登録する
ngrokは会員登録せずに使うと8時間しか起動できません。なので、会員登録し、発行されるauthtokenを登録します。
- https://ngrok.com/ から「Get started for free」ボタンを押して進める
- 登録後に表示される「Setup & Installation」画面の「③Connect your account」にあるauthtokenをメモする。
- 先程作った作業ディレクトリで以下のコマンドを実行する
npx ngrok authtoken XXXXXXXX
以下のようなログが出ればOK
Authtoken saved to configuration file: ~~~~~~~~~
XXXXXXXXはメモしたauthtokenです。
今回はngrokを-g(グローバル)ではなくローカルにインストールしているので、npxを使ってngrokコマンドを実行しています。
5. Node.jsのサーバーを起動する
作成したserver.jsを起動します。そして、ローカル起動したserver.jsをngrokで外部に公開します。
- ssh接続したターミナルではなく、VNC接続してラズパイ本体でターミナルを2つ起動する。
- 1つ目のターミナルでserver.jsがあるディレクトリに移動し、以下を実行する
node server.js
以下のようなログが出ればOK
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
Server running at 3000
- 2つ目のターミナルでserver.jsがあるディレクトリに移動し、以下を実行する
npx ngrok http 3000
以下のようなログが出ればOK
Session Status online
Account <アカウント名> (Plan: Free)
Version 2.2.8
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://XXXXXXXX.ngrok.io -> localhost:3000
Forwarding https://XXXXXXXX.ngrok.io -> localhost:3000
もし、ngrokを会員登録せずに実行した場合、Accountの行の代わりに以下のような表示になります。表示されているとおり8時間しか起動できません。
Session Expires 7 hours, 59 minutes
6. LINEのMessaging APIにURLを設定
ngrokで設定したURLをLINEのAPIに設定します。
- LINEのChannel基本設定画面のWebhook URLに「XXXXXXXX.ngrok.io/webhook」を設定し、更新ボタンを押す(XXXXはngrokで作製したURL)。
- 「接続確認」ボタンを押して成功すればOK
これで準備完了です!
7. botとトークしてみる
友達になったbotとトークしてみます。
自分:こんにちは
bot:メッセージを受け付けました:こんにちは
おおおおーーー!
そして少し遅れて
google home: 新しいメッセージです。こんにちは
しゃべったーーー!
嬉しい!!
※2018/05/13
ngrokのフリープランを使い、8時間制約を回避する手順を追加しました。
daaaaaasukeさんありがとうございました!