4
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Google Home でLINEのメッセージを”おしゃべり”双方向通信(コミュニケーション)をしてみよう.

Last updated at Posted at 2018-09-23

#1. イントロダクション.
 家族間でのやりとりにLineを使っていますが,小学生の娘はスマホがないので,コミュニケーションに参加できません.それなら,Google Home miniを使えば参加できるのでは?と思って,Qiitaの同様のページを参考にいちから作ってみました.
 私のようにプログラム初心者が躓くところも詳しく書いてみます.参考サイトにリンクすることでページをスマートにすることもできますが,この順番で実行することでできるようになった方が便利だと思い,すべてのフローを記しました.
そのため長文になりますがご容赦ください.

##1.1. 参考にしたページ
以下のサイトの内容,プログラムを参考にしました.ありがとうございます.

LineとGoogle Homeで双方向のやりとりをする
LINEに送信したメッセージを、Google Homeで読み上げ、家族に通知
google-home-notifierが「Error: get key failed from google」を吐いたので対策してみた
Macにnode.jsをインストールする手順。
IFTTTを使ってGoogle HomeからLineを送信する

##1.2. 構築環境
 OS環境:macOS Sierra (macOSならば,どれでも同じと思います.)
Google Home mini:秋葉原のじゃんぱら秋葉原本店で中古を2480円で買いました.

##1.3. 環境構築
自分のmacをLineからのメッセージを受け取ったときに,Google Homeにその内容を送信するサーバーとして動かす必要があります.
そのサーバーのプログラムはjavascriptで動いており,そのjavascriptのコードを動かすために,node.jsというモジュール(ソフトのようなもの)をmacにインストールします.
まずは,その手順について説明します.

###1.3.1. Homebrewのインストール

macOS用のパッケージマネージャー,つまりmacで色々なプログラムやコードを動かすための,モジュール(ソフト)をインストールするのに便利なツールをまずインストールします.

Homebrew公式サイトの一番上にある”インストール”の下の下記のコマンド(2018年9月23日時点)をコピーし,それをmacのターミナルにペーストしてリターンで実行します.

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

その後,以下のコマンドでバージョンを確認します.
きちんとインストールできたの確認にもなります.

$ brew -v

上記のコマンドを実行し,以下のように表示されれば,インストールは完了です.

********:~ user$ brew -v
Homebrew 1.7.4
Homebrew/homebrew-core (git revision 29c4cf; last commit 2018-09-17)

###1.3.2. Nodebrewのインストール
次にNodebrewをインストールします.Nodebrewは,次にインストールするNode.jsのための環境構築,と思っています.
(この説明で間違えていたらご指摘ください)

以下のコマンドを実行します.

$ brew install nodebrew

インストールの確認は,いつもと同じくバージョンの確認で行います.

$ nodebrew -v

すると,以下のように表示されればOKです.

**********:~ user$ nodebrew -v
nodebrew 1.0.0

Usage:
    nodebrew help                         Show this message
    nodebrew install <version>            Download and install <version> (from binary)
    nodebrew compile <version>            Download and install <version> (from source)
    nodebrew install-binary <version>     Alias of `install` (For backword compatibility)
    nodebrew uninstall <version>          Uninstall <version>
    nodebrew use <version>                Use <version>
    nodebrew list                         List installed versions
    nodebrew ls                           Alias for `list`
    nodebrew ls-remote                    List remote versions
    nodebrew ls-all                       List remote and installed versions
    nodebrew alias <key> <value>          Set alias
    nodebrew unalias <key>                Remove alias
    nodebrew clean <version> | all        Remove source file
    nodebrew selfupdate                   Update nodebrew
    nodebrew migrate-package <version>    Install global NPM packages contained in <version> to current version
    nodebrew exec <version> -- <command>  Execute <command> using specified <version>

Example:
    # install
    nodebrew install v8.9.4

    # use a specific version number
    nodebrew use v8.9.4

###1.3.3. Node.jsのインストール
ここでようやく目的のNode.jsをインストールします.
Node.jsのバージョンを確認し,目的にあったバージョン(プログラムによっては,古いバージョンに対応したものがあり,最新のものが動かないことがある)をインストールしますが,私は以下のコマンドで最新版をインストールしました.

$ nodebrew install-binary latest

そして,どのバージョンのモジュールがダウンロードされたか確認します.

**********:~ user$ nodebrew list

v10.10.0

最新版(2018年9月23日時点)の10.10.0がインストールされました.

つぎに,このモジュールが使用できるようにします.

$ nodebrew use  v10.10.0

そして,使用できる状態かを以下にて確認します.

*********:~ user$ nodebrew list
v10.10.0

current: v10.10.0

これで,node.jsのv10.10.0が使用できるように選ばれました.
次に,ターミナル起動時にnode.jsが使用できるように,起動時の環境変数を追加します.

$ echo 'export PATH=$PATH:/Users/xxxxx/.nodebrew/current/bin' >> ~/.bashrc

注:xxxxxはUserのHomeDir名になります.おそらく,端末名になっていると思います.Finderをクリックしたとき,左のよく使う項目の家のアイコンにつけられている名前になります.
これをしないと,node.jsを実行するときは,いつもそのモジュールが入っているフォルダのフルパスを入力する必要があります.
それを省略するのが,この”環境変数の追加”と理解しています.
ここまで終わりましたら,ターミナルと一度閉じて再起動します.そのとき,bashrcが読み込まれ,node.jsの場所が確認(保存)されます.

ここで,node.jsでつかう様々なモジュールを管理するためのnpmが使えることを確認します.
このあと紹介するGoogle Homeに話させるGoogle home notifierは,このnpmがインストールされているか確認します.
コマンドは単純です.

********:~ user$ npm -v
6.4.1

v6.4.1がインストールされていることを確認しました.
これで環境構築が終了です.

#2. Lineによるコミュニケーション環境の構築
##2.1. LineのメッセージをGoogle Homeで話す.
linetogooglehome2.png

全体の流れは上記になります.
LINEで送信したメッセージを,LINE Developerを使って,ngrokで公開した家のmacサーバーに送り,そしてmacサーバーが家庭内の同じLAN内にあるGoogle homeに送り,Google Homeがメッセージを読み上げます.

まず,家のmacをサーバーとして動かし,それを外部に公開するngrokを準備します.

###2.1.1. ngrokの環境構築
ngrokは、localhostをXXXXXXXX.ngrok.comで,外部からアクセス可能にするサービスです.家のPCを外部に簡単に公開することができます.例えば,試しにつくったWebアプリを外部環境にてデモンストレーションしたいときに便利です.

ngrokのホームページからosX用のソフトをダウンロードします.

ngrok1.png

"Get started for free ->" をクリックしします.

ngrok2.png

アカウントを作成しログインします.このあと,ngrokを連続して動かすためにもアカウントを作ってください.私はgoogleアカウントよりサインアップ(sign up with Google)しました.

ngrok3_1.png

つぎに,"①Downlad ngrok"にある Download for Mac OS X をクリックしてプログラムをダウンロードします.

macのFinderをひらくと,”ダウンロード”のフォルダにダウンロードしたngrokがあります.
それをコピーし,同じFinderの”アプリケーション”にペースト(移動)してください.

例えば,ダウンロードフォルダに入って,下記のコマンドでも実行できます.

$ mv ngrok /Applications/

そのあと,binフォルダに移動し,ngrokをリンクします.
(以下のコマンドを実行します)

$ cd /usr/local/bin
$ ln -s /Applications/ngrok ngrok

ここで,ngrokが動作するか確認します.コマンドは以下となります.
(当初はこれを忘れていて,ngrokが実行できずエラーとなって動かせませんでした)

$ ngrok http 8080

実行すると以下のような表示がでれば,インストールと実行が成功です.

ngrok_1.png

”12345678”の部分が,ngrokのアドレスになります.
動作確認後は,一度停止します.停止は,右上にあるとおり"Ctrl+C"です.

###2.1.2. google-home-notifierの環境構築
次に,Google Homeが話すための,google-home-notifierをインストールします.
インストールは以下のコマンドで実行します.

$ npm install google-home-notifier

これで,google-home-notifierがダウンロードされます.
homeでダウンロードすれば,そこに上記名のフォルダができているので,確認してください.

ここで注意です.
2018年9月19日ぐらいまでは,このままで使えましたが,それ以降は下記のエラーがでて,LINEにメッセージを送信しても,Googl Homeが話さなくなりました.

Error: get key failed from google

これは,このモジュールが使用しているgoogle-tts-apiのバージョンがアップし,応答にて返信されるTKKの数字が異なることが原因と思われます.
その解消のために,google-home-notifierにあるgoogle-tts-apiのkey.jsを修正します.
key.jsは”node_modules/google-tts-api/lib/key.js”にあります.
ここでは,evalのあとのTKKの表記部分を修正しています.
プログラムは,アプリのテキストエディタなどで開いて修正してみてください.

key.js(修正前)
var fetch = require('isomorphic-fetch');
var host = 'https://translate.google.com';

/**
 * Get Key from https://translate.google.com
 *
 * @param   {Number!} timeout  default is 10000ms
 * @return  Promise(key: String)
 */
module.exports = function (timeout) {
  return fetch(host, {
    timeout: timeout || 10 * 1000
  })
  .then(function (res) {
    if (res.status !== 200) {
      throw new Error('request to ' + host + ' failed, status code = ' + res.status + ' (' + res.statusText + ')');
    }
    return res.text();
  })
  .then(function (html) {
    var TKK = null;

    try {
      eval(html.match(/TKK=eval\(\'\(.*\)\'\);/g)[0]); //Before
    } catch (e) {
      throw new Error('get key failed from google');
    }

    return TKK;
  });
};
key.js(修正後)
var fetch = require('isomorphic-fetch');
var host = 'https://translate.google.com';

/**
 * Get Key from https://translate.google.com
 *
 * @param   {Number!} timeout  default is 10000ms
 * @return  Promise(key: String)
 */
module.exports = function (timeout) {
  return fetch(host, {
    timeout: timeout || 10 * 1000
  })
  .then(function (res) {
    if (res.status !== 200) {
      throw new Error('request to ' + host + ' failed, status code = ' + res.status + ' (' + res.statusText + ')'); 
    }
    return res.text();
  })
  .then(function (html) {
    var TKK = null;

    try {
      eval(html.match(/TKK='[0-9]+.[0-9]+'/g)[0]);   //After
      if (TKK === null) throw null;
    } catch (e) {
      throw new Error('get key failed from google');
    }

    return TKK;
  });
};

次に,LINEからのメッセージの受信およびGoogle Homeへ送信するためのサーバーの設定をします.
以下のプログラムとなります.

server_for_line.js
const config = require('./config/default.json');

// for http server
const http = require('http');

// for googlehome
const googlehome = require('google-home-notifier');
const language = 'ja';

function googlehome_init() {
  googlehome.device(config.googlehome_name, language);
  googlehome.ip(config.googlehome_ip, language);
}

function googlehome_speak(text) {
  googlehome.notify(text, function (res) {
    console.log('googlehome_res : ' + res + '   speech_text : ' + text);
  });
}

// main()
googlehome_init();

http.createServer(function (request, response) {
  let post_data = '';

  request.on('data', function (chunk) {
    post_data += chunk;
  });

  request.on('end', function () {
    console.log('post_data : ' + post_data);

    const webhook = JSON.parse(post_data).events[0];
    if (webhook.type != 'message' || webhook.message.type != 'text') {
      return;
    }

    // 特定の人からのメッセージのみ発話
    if (config.speakable_userid == '' || webhook.source.userId == config.speakable_userid) {
      const data_text = webhook.message.text;
      googlehome_speak(config.beginning_sentence + data_text);
    }

    response.writeHead(200, { 'Content-Type': 'text/plain' });
    response.end();
  });
}).listen(config.server_port);

”特定の人からのメッセージのみ発信”として,IDを登録することで発信するひとを選択することができるみたいですが,私は使っていません.次に,Google Homeの設定コードを作成します.

default.json
{
    "server_port": "8080",

    "googlehome_ip": "192.168.**.**", 
    "googlehome_name": "device name of google home",

    "beginning_sentence": "メッセージが届きました。",
    "speakable_userid": ""
}

ここでは,Google HomeのIPアドレスを上記の**.**をご自分のGoogle HomeのIPに修正します.
使用しているGoogle HomeのIPアドレスは,Google Homeのスマホのアプリから確認してください.設定のページの一番下に書いてあります.

上記の2つのプログラム(コード)は以下のフォルダにいれます.

google-home-notifier
-server_for_line.js
-config/default.json

server_for_line.jsはgoogle-home-notifierのフォルダに置き,default.jsonはgoogle-home-notifierにconfigのフォルダをつくり,その中に置きます.

これでmacのサーバーとしての設定が終了です.では,サーバー動作させます.
ここで,ngrokを動作させるための"ngrok http 8080"をそのまま入力すると,ngrokは8時間動作した後に停止します.
その後再起動させると,ngrokのアドレスが変わるため,LINEからメッセージを送信してもエラーがでてGoogle Homeは話しません.

そのためngrokのアドレスを8時間以上継続して使用するためにサインインし,承認をもらいます.

ngrok_2.png

ngrokのホームページにサインインし,左のメニューから”Auth”を選びます.
そうすると,Authtokenをゲットできますので,それをコピーし,以下のコマンドを実行します.

$ ngrok authtoken ******************************

もちろん,********************が取得したAuthtokenになります.
こちらを実行すると,継続してい使用するためのファイル(ngrok.yml )自動で作成され設定されます.

このあと,ngrokを起動してみます.

$ ngrok http 8080
ngrok by @inconshreveable                                       (Ctrl+C to quit)
                                                                                
Session Status                online                                            
Account                       ********** (Plan: Free)                       
Version                       2.2.8                                             
Region                        United States (us)                                
Web Interface                 http://127.0.0.1:4040                             
Forwarding                    http://12345678.ngrok.io -> localhost:8080        
Forwarding                    https://12345678.ngrok.io -> localhost:8080       
                                                                                
Connections                   ttl     opn     rt1     rt5     p50     p90       
                              0       0       0.00    0.00    0.00    0.00      
                                                                                

これにより,Accountのよこに(Plan: Free)となり,Accountもサインインの名前になっていることを確認してください.
これで準備はOKです.
また,このままでは使用しているサーバーの地域がUS(アメリカ)となっており,LINEのメッセージを送信してから,一度メッセージがアメリカにいき,そのあと日本に帰ってくる,ということで時間がかかります.
このままだと,メッセージを送ってから受信するまで時間がかかることから,エラー(タイムアウト)が起こる可能性があります.
(私は,はじめは大丈夫でしたが,少ししてからタイムアウトのエラーが発生し,Google Homeが話さなくなりました)

そのため,使用するサーバーの地域をアジアに選択して,サーバーを起動します.

$ ngrok http -region=ap 8080

ngrok by @inconshreveable                                       (Ctrl+C to quit)
                                                                                
Session Status                online                                            
Account                       ********* (Plan: Free)                       
Version                       2.2.8                                             
Region                        Asia Pacific (ap)                                 
Web Interface                 http://127.0.0.1:4040                             
Forwarding                    http://12345678.ap.ngrok.io -> localhost:8080     
Forwarding                    https://12345678.ap.ngrok.io -> localhost:8080    
                                                                                
Connections                   ttl     opn     rt1     rt5     p50     p90       
                              0       0       0.00    0.00    0.00    0.00      
                                                                                
                                                                              

これによって,RegionがAsia Pacificになり,https://のアドレスにも12345678.ap.ngrokとapがつきます.
これでサーバーの起動は終了です.

この状態にて,ターミナルをもうひとつ開きます(シェル→新規ウィンドウ).
ここで,サーバーを起動させた状態にしておくことが重要です.
2回言います.サーバーを起動させた状態で実行してください.
(私はこれがわからず,半日試行錯誤していました.)

google-home-notifierのフォルダにはいり,sever_for_line.jsを起動します.
コマンドは以下となります.

$ node server_for_line.js

これを起動させても,なんら応答はありません.ここでサーバーであるmac側の設定は終了です.
つぎに,LINE DeveloperでLINEにメッセージを送信したとき,このサーバーにそのメッセージが送信されるよう設定します.

###2.1.3. LINE Developersの環境構築
LINE Developersにアクセスします.

line develop.png

ここで,Messaging APIをクリックします.
line develop2.png

つぎに,ここの「今すぐ始めよう」をクリックします.
そして,次のページで「新規プロバイダーの作成」を選び,適当な名前をつけます.
ここでは,"GoogleHomeTalk"としました.

そして,次のページの「アプリ名」や「アプリの説明」は,ここでは適当ですが「googlehometalk」「google home talkする」といれ,プランは「For Developer」を選びます.
大業種や小業種は個人ですので,「個人」「個人(その他)」を選びました.
メールアドレスを使用しているアドレスを入力します.
そして確認をクリックし,次のページで利用規約を確認後に「作成」を押します.

そうすると,次のページが開きます.
line develop3.png
]
ここで作成した「googlehometalk」をクリックし,設定します.

linedevelop2.png

ページの中頃に行き,上記の部分を設定します.
Webhook送信:編集をクリックし「利用する」に設定.
Webhook URL: 編集をクリックし,サーバー立ち上げ時に表示されたngrokのアドレスを入力する.
Botグループトーク参加:編集をクリックし,「利用する」に設定.

ここでWebhook URLを登録したあと,接続確認をクリックすると,デフォルトのメッセージが送信され,
Google Homeが「メッセージが届きました.Hello, World」と話します.

ターミナルには以下が表示されます.

googlehome_res : Device notified   speech_text : メッセージが届きました。Hello, world

これで,LINEにメッセージを送信し,Google Homeに話をさせる設定は終了です.やっと5合目です.

##2.2. Google Homeに話した内容をLineに送信する.

lineIFTTT2.png

Google Homeに話してLineにメッセージを送信するのは,IFTTTを使いました.関連するサイトにはGoogle Homeにメッセージを送信するとき使用したngrokを使ったものもありますが,ここでは使用していません.

IFTTTのホームページにいき,Google アカウントでサインインします.
また,このあとLINEのサービスを使用しますが,そのときのLINEのアカウントも登録します.私はGoogleのアカウントで連携していたため,そちらでサインインしました.(すでに登録しているため,それらの作業の説明はここでは割愛します.)

では,IFTTTを設定していきます.

IFTTT1.png

IFTTTにログイン後,"Services"をクリックし,その横にある”New Applet”を選びます.

IFTTT11.png

この画面で”+this”をクリックします.

IFTTT2.png

Choose a serviceと聞かれるので,検索欄に"google"と入力します.
すると,”Google Assistant”が表示されますので(ここでは左端),それをクリックして選びます.

IFTTT3.png

その中で,4つのトリガーのどれを選択するか聞かれますので,今回は”OK Google”後に話した内容をメッセージで送りますので,"Say a phrase with a text ingredient"を選択します.

IFTTT5.png

ここでは,各項目(What do you want to say?など)を,上記のとおりまずは入力します.動作確認後は,みなさん好きなように設定してください.
入力後に"Create a trigger"をクリックし保存します.
次は,このアクションを受けての反応です."that"をクリックします.

IFTTT7.png
検索欄に”line”と入力し,lineのアプリを表示し,これをクリックします.

IFTTT9.png
"line Send message"のあとに,Recipientで送り先を選択します.
ここではデフォルトの"1:1でLine Notifyから選択"を選んでいますが,私だけでなく家族みんなで使用(共有)したいので,Google Homeで話す家族内のlineグループを作成し,いまはそれを選んでいます.
”Message”欄はそのままで,Saveをクリックします.

IFTTT12.png

そして,このアプリのタイトル(ここでは,"if you say ""Line$", then send a message")として,このアプリをONします.

これで,Google Homeに話してLINEにメッセージを送る設定は終了です.ご自身のLineのアプリに,Line Notifiyの承認が届きますので,こちらを承認してください.

#3. まとめ
Google HomeとLINEを使ったコミュニケーションのサービスを作りました.
いまでは,家族内のLINEのやりとりは,Google Homeも含めたものをメインに使っています.
スマホを持っていない娘とのやりとりもありますが,Googl HomeがスピーカーのようにLINEメッセージを読み上げてくれるので,とても便利です.
私が会社から帰宅するときLINEにメッセージを送っても”既読”にならないときがありますが,ここに送っておけば家族みんなに音声で通知できるので,誰かは聞いてくれてるでしょう(たぶん).
私は初めて使うプログラムやサービスだったので,設定までに2日間かかりましたが,ここに書きました原理さえわかってしまえば,それほど難しくありません.
ただ,数日前にあったような関連するモジュールがアップデートされると,それを読み出しているプログラムは停止しますので,注意が必要です.でも,そのときは誰かが解決し,それを共有してくる世界ですので,すぐにサービスが再開できます.感謝!
便利なサービスですので,Google Homeをお持ちの方,もしくは検討されている方は,ぜひ試してみてください.

#4. その他
macをサーバーとして使用するため,電源をオフすることやスリープすることができません.
電気代が心配なため,次はRaspberryPiをngrokのサーバーとして使用することを考えています.

ngrokでRaspberry Piのデスクトップをインタネットに公開

4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?