twilio
GoogleHome

TwilioとGoogle Homeで構内放送システムを構築する

はじめに

構内放送システムってご存知でしょうか。病院や工場、オフィスなどでよく見かける、アナウンスを一斉配信できる、あのシステムです。
あまり知られていませんが、実は電話システムと連携して作られていることが多いのです。専門用語では、ページングシステムといいます。
PBX(電話交換機)にページング拡張装置をつけて、アンプを通してスピーカーに繋いでおき、電話機の特番を押して話をすると、スピーカーから音声が流れるしくみです。装置やスピーカーの設置、配線など、実は結構初期費用がかかるのですが、今回はこれをGoogle HomeとTwilioでサクッと作ってしまいたいと思います。

準備

必要なもの

  • Google Home mini(Homeでもminiでも構いません)
  • Node.js(7.x以上)とPython(2.x)が動作するPC
  • Twilioのアカウント(トライアルアカウントでも動くと思います)

動作のしくみ

  1. Twilioで購入した050番号に電話をかけます。
  2. メッセージを吹き込んだら電話を切ります。
  3. Google Homeと同じネットワークに設置したPC経由でメッセージが通知されます。
  4. Google Homeでメッセージが再生されます。

構築

手順

  1. PC上にgoogle-home-notifierをセットアップします。
  2. google-home-notifierを起動します。
  3. Twilio上で録音するしくみを作ります。
  4. 録音したデータをWebhookするしくみを作ります。
  5. 電話番号を購入して、録音できるようにします。
  6. テストします。

google-home-notifierのセットアップ

google-home-nogifierは、Google Homeに対して音声を再生したり、音楽(mp3)を再生したりすることができるアプリケーションです。Nodeのモジュールとしての提供の他、プロキシーサーバーとして動作するプログラムも提供しています。
プログラムはgithubで公開されており、MITライセンスに基づき利用できます(商用利用も可能です)。
今回はプロキシーを使って、PCを介してTwilioとGoogle Homeをつなごうと思います。
以下の作業はPC上で行います。Node.js(バージョン7以上)とPython(バージョン2.x系)がインストールされていることを確認しておいてください。

  1. 適当なディレクトリに移動します。
  2. 以下の手順でインストールをします。
sh
$ git clone https://github.com/noelportugal/google-home-notifier
$ cd google-home-notifier
$ npm install

google-home-notifierの起動

インストールができたら、一部コードを変更します。そのためには、Google HomeのIPアドレスを事前に調べておく必要があります。
スマホのGoogle Homeアプリを起動して、でバイスの設定画面の一番下に書かれているIPアドレスを控えておきます。
GoogleHomeIPアドレス.png

次に、移動したディレクトリの中のexample.jsというファイルを編集します。

example.js
var express = require('express');
var googlehome = require('./google-home-notifier');
var ngrok = require('ngrok');
var bodyParser = require('body-parser');
var app = express();
const serverPort = 8091; // default port

var deviceName = 'Google Home';
var ip = '192.168.1.20'; // default IP

var urlencodedParser = bodyParser.urlencoded({ extended: false });

9行目のipアドレス(192.168.1.20)を、先程調べたGoogle HomeのIPアドレスに変更して保存します。
では実行してみましょう。

sh
$ node example.js
Endpoints:
    http://192.168.1.20:8091/google-home-notifier
    https://xxxxx.ngrok.io/google-home-notifier
GET example:
curl -X GET https://xxxxx.ngrok.io/google-home-notifier?text=Hello+Google+Home  - to play given text
curl -X GET https://xxxxx.ngrok.io/google-home-notifier?text=http%3A%2F%2Fdomain%2Ffile.mp3 - to play from given url
POST example:
curl -X POST -d "text=Hello Google Home" https://xxxxx.ngrok.io/google-home-notifier - to play given text
curl -X POST -d "http://domain/file.mp3" https://xxxxx.ngrok.io/google-home-notifier - to play from given url

こんな感じで表示がされれば実行中です。Endopointsのところで表示されている、https://xxxxx.ngrok.io/google-home-notifier というURL(xxxxxのところには皆さん独自の文字列が表示されています)をメモ帳にコピーしておきます。このURLは起動する度に変わります。
ちなみに終了するにはCtrl-Cを押します。

録音部分のコーディング

再生する側の準備が整ったので、今度は入力側を作っていきます。
1. Twilioの管理コンソールにログインして、Runtime→Functionsを選択します。
2. 新しいFunctionを作成します。テンプレートはBlankを選択します。
3. FUNCTION NAMEに、「Record」、PATHには、「/record」と入力します。
4. ACCESS CONTROLにチェックを入れます。
5. EVENTは「Incoming Voice Calls」を選びます。
6. CODE欄は、以下のコードで上書きします。

Record
exports.handler = function(context, event, callback) {
  let twiml = new Twilio.twiml.VoiceResponse();
  let voiceParams = {}
  voiceParams.language = 'ja-JP'
  voiceParams.voice = 'alice'
  twiml.say(voiceParams, "Google Homeで再生したいメッセージを吹き込んでください。")
  twiml.record({
    recordingStatusCallback: 'https://'+context.DOMAIN_NAME+'/recorded'
  })
  callback(null, twiml);
};

最後に「SAVE」ボタンを押して、変更を保存します。

録音データをWebhookする部分のコーディング

次に、録音が終わったときの処理を作っていきます。
1. もう一つ、新しいFunctionを作成します。テンプレートはBlankを選択します。
2. FUNCTION NAMEに、「Recorded」、PATHには、「/recorded」と入力します。
3. ACCESS CONTROLにチェックを入れます。
4. EVENTは「Select...」のままにしておきます。
5. CODE欄は、以下のコードで上書きします。

Recorded
exports.handler = function(context, event, callback) {
  const got = require('got')
  const url = 'https://XXXXXXX.ngrok.io/google-home-notifier'
  const options = {
    json: true,
    body: {text: event.RecordingUrl}
  }
  got.post(url, options)
  .then(res => {
    console.log(res.body)
    callback(null, 'OK')
  })
  .catch(error => {
    console.log(error)
    callback(error)
  })
};

3行目のhttps://xxxxxx.ngrok.io/google-hone-notifier の部分を、先程控えておいたexamples.jsを実行した時に表示されたURLに書き換えてください。
最後に「SAVE」ボタンを押して、変更を保存します。

電話番号の購入と設定

次に、Twilioで着信させるための電話番号の購入と、設定を行います。
1. Twilioの管理コンソールの「Phone numbers」(電話番号)を選択します。
2. 「番号を購入」を選択します。
3. 国のリストから、「Japan(+81)」を選択し、「検索」ボタンを押します。
4. 購入可能な番号が一覧表示されたら、TYPEが「ローカル」のいずれかの番号の「購入」ボタンを押します。
5. 購入しますか?のダイアログが表示されたら、「この番号を購入する」ボタンを押します。
6. Congratulationsダイアログが表示されたら、「番号を設定する」ボタンを押します。
7. Voice & Faxセクションの中のA CALL COMES INのプルダウンから「Function」を選択し、さらに先程作成した「Record」を選択します。
スクリーンショット 2018-01-11 11.48.46.png

「保存」ボタンを押して設定を完了します。

テスト

以上でセットアップはすべて完了です。
PC側でプログラムが起動中であることを確認して、050番号に電話をかけてみます。
電話がかかるとメッセージが流れるので、発信音の後にメッセージを吹き込みます。
メッセージが終了したら電話を切ります(切らないと続けてメッセージを入れられます)。
Google Home側からメッセージが再生されれば成功です。

まとめ

今回はPCを介してGoogle Homeにデータを送りましたが、PCの代わりにRaspberry Piを使う方法もあります。
詳しくはgoogle-home-notifierのGitHubに記載がありますので参考にしてみてください。

また、音声ファイルだけでなく、文字を日本語で再生させることもできるようなので、色々と試してみると面白いかと思います。