はじめに
- Google homeをしゃべらせると言えば猫も杓子もRaspberry Piだ。
- しまいには、Google Home機能拡張キット「GHKit」まで登場している。
- 僕もGoogle homeを自発的にしゃべらせたいけど、Raspberry Piを持っていない。
- ならば、手持ちのWindows機だけで、何とかしたくなるのが貧乏人の性と言うもの。
前提
- Windows 10 pro バージョン1803
概要
- まず、大雑把な流れを考える。
- IFTTTで、Gmailの新着タイトルと送り主をGoogle Drive Spreadsheetに書き込む
- cronで毎分起動するnode.jpツールで Google Drive Spreadsheetから情報を取得する
- 取得した新着タイトルと送り主を、「Google home喋らせサーバ」に送る
- 最後の怪しい「Google home喋らせサーバ」について補足する
- Windows Subsystem for Linux(WSL)でubuntuを入れる
- nodo.jsをWSLに入れる(最新にする)
- google-home-notifierを入れる
- example.jsを編集する
- nohupで動かしておく
- 順番は適当に入れ替えつつ説明します
IFTTTで、Gmailの新着タイトルと送り主をGoogle Drive Spreadsheetに書き込む
- IFTTTにアクセスしてsignupする
- My Appletsをクリック
- New Appletをクリック
- Thisをクリック
- Gmailをクリック
- Any new email in inboxをクリック
- Thatをクリック
- google sheetsをクリック
- Add row to spreadsheetをクリック
- Formatted rowを{{ReceivedAt}}|||{{FromAddress}}|||{{Subject}}}|||{{FromName}}に変更
- Create Actionをクリック
- Turn Onをクリック
Windows Subsystem for Linux(WSL)でubuntuを入れる
- [Win]キーを押す
- 歯車マークをクリック
- アプリをクリック
- 「アプリと機能」の右側の関連設定の「プログラムと機能」をクリック
- 「プログラムと機能」の左側の「Windowsの機能の有効化または無効化」をクリック
- 「Windowsの機能の有効化または無効化」で「Windows Subsystem for Linux」のチェックボックスをONにする
- 今すぐ再起動で再起動する
- トイレタイム
- Microsoft Storeを開く
- 検索に「Ubuntu」と入力
- [入手]をクリック
- ダウンロードするのでティーブレイク
- ダウンロードが完了したら、[起動]をクリック
- Ubuntuが起動するが、初回はしばらく時間がかかるのでまたトイレタイム
- ユーザー名とパスワード2回を入力
- ここで、「サポートされていないコンソール設定です。この機能を使用するには、従来のコンソールを無効にする必要があります。」というエラーが出たら、コマンドプロンプトのプロパティ、オプションから、「従来のコンソールを使う」チェックをOFFにする、このとき再起動が必要になって、WSLがセットアップの中断となりおかしくなるので、Ubuntuアプリを削除して入れなおすと上手くいった
nodo.jsをWSLに入れる(最新にする)
- まず、node.jsとnpmを入れる
sudo apt-get install -y nodejs npm
- 次に n package を導入
sudo npm cache clean
sudo npm install n -g
- さらに、n package を使って node をinstall
sudo n stable
sudo ln -sf /usr/local/bin/node /usr/bin/node
- バージョン確認
node -v
v10.6.0
- 最初に入れた nodejs, npm は削除
sudo apt-get purge -y nodejs npm
cronで毎分起動するnode.jpツールで Google Drive Spreadsheetから情報を取得する
- 前提モジュールをインストール
sudo npm child_process sleep google-spreadsheet
- googleのデベロッパーコンソールに行って、[プロジェクトを作成]を選ぶ
- [同意して続行]をクリック
- [認証情報に進む]をクリック
- [キャンセル]をクリック
- 「認証情報」のタブを選択し、 [認証情報を作成]をクリック
- 「サービスアカウントキー」をクリック
- サービスアカウントを作成
- KeyTypeはjsonを選択
- jsonを保存
- jsonの中の、"client_email"を調べておく
- Googleスプレッドシートに行く
- [Any new email]と言う名前のスプレッドシートを作る
- urlから、スプレッドシートのIDを調べておく(https://docs.google.com/spreadsheets/d/スプレッドシートのID/edit#gid=0となっている)
- A1にdate、B1にemail、C1にtitle、D1にnameと入力する
- [共有]をクリック
- 「ユーザー」に、上で調べた"client_email"を追加する
- 上のjsonを、WSLの適当なディレクトリに置く
- jsonを置いたディレクトリに以下のスクリプトを作成
vi gmail_watcher.js
- 中身はこんな感じ
gmail_watcher.js
const execSync = require('child_process').execSync;
var sleep = require('sleep');
var GoogleSpreadsheet = require('google-spreadsheet');
var id = 'スプレッドシートのID'
var path = 'フルパスのjsonファイル'
var my_sheet = new GoogleSpreadsheet(id);
var credentials = require(path);
my_sheet.useServiceAccountAuth(credentials, function(err){
my_sheet.getInfo(function(err, data){
data.worksheets[0].getRows(function( err, rows ) {
for(var i in rows) {
var name = rows[i].name;
var title = rows[i].title;
var text = name+'さんから'+title+'と言うメールが来ています';
console.log(text);
text = text.replace(/\'/g, '');
text = text.replace(/\&/g, '');
execSync("curl -X POST -d 'text="+text+"' http://localhost:8080/google-home-notifier");
rows[i].del()
sleep.sleep(10);
}
});
});
});
- 最後にSleep 10秒は、待たないと、1分間に複数メールが来た時に、台詞が消えてしまうのでアドホックに対応したもの。
- node.jsのフルパスを調べる
which node
- cron用のファイルを編集する
vi ~/crontab
- 中身はこんな感じ。nodeとスクリプトのフルパスは適切に変更してください
*/1 * * * * /usr/local/bin/node /home/google_home/gmail_watcher.js >> /var/log/cron.log
- cronに登録する
crontab < ~/crontab
- cronが起動しているか調べる
sudo /etc/init.d/cron status
- 起動していれば、念のため再起動
sudo /etc/init.d/cron restart
- 起動していなければ起動する
sudo /etc/init.d/cron start
- 念のためにシステム起動時にcronが動くようにしておく
sudo systemctl enable cron
- 念には念を入れて、cron.serviceがenabledになっているか調べる
systemctl list-unit-files -t service|grep cron
- 問題がなければ次へ
google-home-notifierを入れる
- 前提モジュールをインストール
sudo npm google-home-notifier
example.jsを編集する
- もとのexample.jsはいじりたくないので、コピーしたものを編集する
cd node_modules/google-home-notifier/
cp example.js myexample.js
vi myexample.js
- deviceNameを自分のGoogle homeのにする
- googlehome.deviceとgooglehome.accentを'ja'にする
- googlehome.ipを、googole homeアプリの右上の[デバイスアイコン]-そのgoogle homeの[:]-[設定]の一番下のIPアドレスにする。
node_modules/google-home-notifier/myexample.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 = 8080;
var deviceName = 'ダイニング ルーム';
googlehome.device(deviceName, 'ja');
googlehome.ip('192.168.xxxx.xxx');
googlehome.accent('ja'); // uncomment for british voice
var urlencodedParser = bodyParser.urlencoded({ extended: false });
app.post('/google-home-notifier', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
console.log(req.body);
var text = req.body.text;
if (text){
try {
googlehome.notify(text, function(notifyRes) {
console.log(notifyRes);
res.send(deviceName + ' will say: ' + text + '\n');
});
} catch(err) {
console.log(err);
res.sendStatus(500);
res.send(err);
}
}else{
res.send('Please POST "text=Hello Google Home"');
}
})
app.listen(serverPort, function () {
ngrok.connect(serverPort, function (err, url) {
console.log('POST "text=Hello Google Home" to:');
console.log(' http://localhost:' + serverPort + '/google-home-notifier');
console.log(' ' +url + '/google-home-notifier');
console.log('example:');
console.log('curl -X POST -d "text=Hello Google Home" ' + url + '/google-home-notifier');
});
})
- テストする
- まず必要なサービスを起動する
sudo service dbus start
sudo service avahi-daemon start
sudo systemctl enable dbus
sudo systemctl enable avahi-daemon
- サーバプログラムを起動する
node myexample.js &
- 以下のようなメッセージが出る
POST "text=Hello Google Home" to:
http://localhost:8080/google-home-notifier
undefined/google-home-notifier
example:
curl -X POST -d "text=Hello Google Home" undefined/google-home-notifier
- 折角なので、日本語をしゃべらせる
curl -X POST -d "text=こんにちはGoogle Home" http://localhost:8080/google-home-notifier
- サーバの後始末をしておく
sudo ps -elf | grep myexample
- 上記コマンドでプロセスIDを調べてkillコマンドで停止させる
nohupで動かしておく
- サーバはターミナルが停止しても動いてほしいので、nohup & で起動しておく
- 通常メッセージとエラーメッセージはファイルに吐くようにしておく
nohup /usr/local/bin/node /home/ubuntu/node_modules/google-home-notifier/myexample.js >> ~/out.log 2>> ~/err.log &
長かったけど以上!
- これで、Gmailが着信したらGoogle homeがしゃべってくれるはずです
追記
- メールタイトルや差出人の名前にアポストロフィーが含まれているとcurlがコケる問題を修正するため、
gmail_watcher.js
にtext = text.replace(/\'/g, '');
を追加した。