LoginSignup
5
8

More than 5 years have passed since last update.

Windows機だけで、Gmailが届いたらGoogle homeがしゃべるようにしてみた

Last updated at Posted at 2018-07-14

はじめに

  • Google homeをしゃべらせると言えば猫も杓子もRaspberry Piだ。
  • しまいには、Google Home機能拡張キット「GHKit」まで登場している。
  • 僕もGoogle homeを自発的にしゃべらせたいけど、Raspberry Piを持っていない。
  • ならば、手持ちのWindows機だけで、何とかしたくなるのが貧乏人の性と言うもの。

前提

  • Windows 10 pro バージョン1803

概要

  • まず、大雑把な流れを考える。
  1. IFTTTで、Gmailの新着タイトルと送り主をGoogle Drive Spreadsheetに書き込む
  2. cronで毎分起動するnode.jpツールで Google Drive Spreadsheetから情報を取得する
  3. 取得した新着タイトルと送り主を、「Google home喋らせサーバ」に送る
  • 最後の怪しい「Google home喋らせサーバ」について補足する
  1. Windows Subsystem for Linux(WSL)でubuntuを入れる
  2. nodo.jsをWSLに入れる(最新にする)
  3. google-home-notifierを入れる
  4. example.jsを編集する
  5. 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.jstext = text.replace(/\'/g, '');を追加した。
5
8
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
5
8