Node.js
ifttt
GoogleHome
スマートスピーカー
google-home-notifier

Google Home miniとイチャイチャしながらご飯を食べる

はじめに

上京して一人暮らしをはじめ、二年が経とうとしています。
寂しい。

Google Home miniを購入してみましたが、コンビニ店員さんとのやり取りのような会話しかなく
心の隙間を埋めてくれることはありませんでした…。

ということで、
Google Home miniとキャッキャウフフしようと試みた記録になります。

概要

「美味しいね。(料理名)」と話しかけると、それっぽいコメントを返してくれます。
スクリーンショット 2018-03-01 0.37.14.png

1.どうやって "それっぽい" コメントをしてもらうか

機械学習などで生成することも考えましたが、
ぐるなびさんの応援口コミAPIがありましたので、こちらをお借りしました!

応援口コミAPIで、話しかけたときの料理名と"美味しい"という単語を含むコメントを取得することで、
料理に対してコメントの"それっぽさ"が出そうな気がします。

ぐるなびWebサービスアカウントを発行し、クエリ用のURLを生成します。
API テストツールがありましたので、サクサクと行えました:raised_hands:

話しかけたときの料理名と"美味しい"という文字列を含むコメントが欲しいので、このようになりました。

https://api.gnavi.co.jp/PhotoSearchAPI/20150630/?keyid=[ACCESS_TOKEN]&format=json&menu_name=[料理名]&comment=美味しい&hit_per_page=50

2.ハートフルコミュニケーションの準備

2.1.声を発してもらう(google-home-notifier)

"それっぽい" コメントを得ることは出来そうなので、
そのコメントを喋らせる準備をしていきたいと思います!

文字で出力するだけでは、心の隙間を埋めることは難しそうですからね!

まずは、声をかけた反応ではなく、指定した言葉を自発的に喋らせたいのですが、
こちらの記事を参考に進めたところ、特に詰まることなく喋ってくれました。
GoogleHomeスピーカーに外部からプッシュして自発的に話してもらいます

:pray::pray::pray: すばらしい記事をありがとうございます :pray::pray::pray:

google-home-notifier が POST を受け取る

POST で受け取った文字列を Google Home に喋らせる

という部分はすでに実現出来ているので、

google-home-notifier が POST を受け取る

POST で受け取った文字列を使って、ぐるなびAPIからコメント取得

取得したコメントを良きように加工

加工したコメントを Google Home に喋らせる

というように修正します。

gnavi.js
.
.
app.post('/google-home-notifier', urlencodedParser, function (req, res) {

  if (!req.body) return res.sendStatus(400)
  console.log(req.body);

  // ぐるなびAPIの利用
  var token = [ACCESS_TOKEN];
  var menu_name = req.body.text;

  var url = "https://api.gnavi.co.jp/PhotoSearchAPI/20150630/?keyid=" + token + "&format=json&menu_name=" + encodeURIComponent(menu_name) + "&comment=" + encodeURIComponent('美味しい') + "&hit_per_page=50";

  var result;
  var text;

  https.get(url, (json) => {
    let body = '';
    json.setEncoding('utf8');

    json.on('data', (chunk) => {
      body += chunk;
    });

    json.on('end', (json) => {
      result = JSON.parse(body);

      // 取得した50件からランダムで一つ選ぶ
      var index = Math.floor( Math.random() * 50 );
      // "美味しい"が含まれている一文だけを抽出
      text = result.response[index].photo.comment.match(/[^。!!♪☆★]*?美味しい[^。!!♪☆★]*/)[0];

  console.log("comment:" + text);

  if (req.query.ip) {
     ip = req.query.ip;
  }

  var language = 'ja'; // default language code
  if (req.query.language) {
    language;
  }

  googlehome.ip(ip, language);
  googlehome.device(deviceName,language);

  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 GET "text=Hello Google Home"');
  }
    });
  }).on('error', (e) => {
    console.log(e.message); // エラー時
  });

})
.
.

2.2.声に反応してもらう(IFTTT)

料理に対するコメントを言ってくれるようになりました!
あとは、話しかけた時に答えてくれるようにすれば完璧ですね!

IFTTT を使って、「OK Google, 美味しいね ○○」と話しかけたら
2.1で設定した google-home-notifier に POST されるように設定します。

以下のように設定しました。

※ 最初、「読み方で揺れそうだし、漢字よりひらがなの方が安定しそう」と思って、"おいしいね"と設定していたら反応しなくて詰まりました。
 GoogleHomeアプリで確認すると"美味しいね"と表記されていたので、そちらに合わせると動きました。
 
ifttt.png

3.イチャイチャする

こんな感じになりました。

反応おっっっっっっっっっそ!!!!!!!!

Raspberry pi zero W ではなくて、もう少しスペックのいいやつを使えば良くなるのか、
通信している以上仕方のない遅延なのか……

まとめ

あんまりイチャイチャ感も出ず、ハートフルコミュニケーションとは程遠い出来だった……
でもやってて楽しかったのでOKです:thumbsup:

映画『ハウルの動く城』カルシファーが僕の理想のスマートホームなので、
もっと楽しくて便利な使い方を模索していきたいです。

拙い文章でしたが、ここまで読んでいただきありがとうございました!

余談

IFTTT の設定を確認中に色々話しかけていたのですが、
「この○○美味しいね」って話しかけると、デフォルトでめちゃくちゃ可愛かった。
お試しあれ。