音声メモをGoogleHomeで記録してMacのShellから遊ぶお話

# 1. はじめに
[Livesense - 関 Advent Calendar](https://qiita.com/advent-calendar/2017/livesense-kan)の14日目を担当する @Otakumesi です。

AdventCalendarのお題が「関」なので、GoogleHomeとShellを繋げる（"関"係させる）話をします。

みなさん、GoogleHomeを買いましたか？

自分は勢いで買ってしまいました。
GoogleHomeを買ったからには、遊んでみないわけにはいかないですよね。
ちなみに、最近の私のマイブームは`say "OK, Google"`を`okgoogle`コマンドとしてaliasの登録をしたり、Macの`say`コマンドを使ってGoogleHomeに話しかけることです。

それでは、導入はここまでにして本題に入ります。

# 2. 今回やったこと
その場でなにかが思いついたものの「手元にパソコンやスマートフォンがなかった」なんて経験があると思います。
そういうときには、GoogleHomeに声をかけるだけでメモができれば、そしてそのメモをパソコンで参照ができれば楽だと思いませんでしょうか。

「**GoogleHomeを使って音声をメモって、そのメモをShellで取り出してクリップボードに突っ込む**」ということをやってみました。

![home-shell.png](https://qiita-image-store.s3.amazonaws.com/0/97363/35228962-33fd-97d0-2302-f3e6ae67c1aa.png)

# 3. 使ったツール・サービス
* GoogleHome
* [IFTTT](https://ifttt.com/)
* [Firebase](https://firebase.google.com/?hl=ja)
* Mac
* Zsh（Bash）

# 4. GoogleHomeを通じて音声メモを保存する
まずは「OK, Google。メモして。明日は日曜日。」とGoogleHomeに話かけると、FirebaseのDBに「明日は日曜日。」というメッセージが記録をされていく仕組みを作ります。
GoogleHomeとFirebaseと繋げる仕組みには、IFTTTを利用していきます。

## Firebaseの設定をする
### Firebaseを使う
音声メモのメッセージを記録するDBとして、FirebaseのリアルタイムDBを使います。

Firebaseとは、Googleが提供しているmBaaSです。
開発に必要な様々なサービスを提供していますが、今回はリアルタイムDB利用します。

### Fireabaseの利用を開始する

まず、Firebaseのプロジェクトを作成します。
https://console.firebase.google.com/ にアクセスをして「プロジェクトを追加」を選択しましょう。

下記のような画面が表示されますが、プロジェクト名やプロジェクトIDは自由につけてください。

![スクリーンショット 2017-12-10 22.52.24.png](https://qiita-image-store.s3.amazonaws.com/0/97363/cdd2ecf5-dde7-175e-de37-a9a224fd6dda.png)

### リアルタイムDBを使う

プロジェクトを作成したら、左のメニューから「Database」を選んで利用を開始します。

利用開始後に表示されるページで、ページ内の「ルール」タブを選択して、DBの権限などの設定をします。

今回は作業を簡単にするためにセキュリティを考慮せずに、誰でも読み書きできるようにしてしまいます。
そのため、以下のように`.read`と`.write`の値を`true`を設定しましょう。
※この設定ではプロジェクトIDが漏れたら、第三者がこのDBに読み書きできてしまうので注意してください。

![スクリーンショット 2017-12-10 23.08.13.png](https://qiita-image-store.s3.amazonaws.com/0/97363/5de31921-b5c8-5a42-f25e-cd8af8bc8dd9.png)

```json:ルールの設定のサンプル
{
  "rules": {
    "message": {
      ".read": true,
      ".write": true
    }
  }
}
```

これでFirebaseの設定は完了しました。
次はGoogleHomeとFirebaseを繋げる手段を用意します。

## IFTTTのAppletを作成する
### IFTTTを使う
GoogleHomeからFirebaseに繋げる手段として、IFTTTを使います。
IFTTTは**コレ（This）した時にアレ（That）する**という形で様々なサービスを組み合わせることのできるWebサービスです。

IFTTTには、「GoogleHomeと連携するサービス」と「Webhookを投げるサービス」を提供されているため、この二つを組み合わせてAppletを作成します。
※IFTTTの使い方は[この記事](http://www.atmarkit.co.jp/ait/articles/1711/22/news031.html)が参考になります。

### Appletの作成をし、トリガーの設定をする

https://ifttt.com/create を開いて「+this」をクリックしてトリガーを設定をします。

今回は「GoogleHomeに対して話しかける」ことをトリガーにするため、サービスの中から「GoogleAssistant」を探し出して選びましょう。
選択をするとさらに下記のような選択肢が表示されますが、**Say a phrase with a text ingredient**を利用します。

![スクリーンショット 2017-12-10 21.48.03.png](https://qiita-image-store.s3.amazonaws.com/0/97363/96b4676a-28b6-9e59-2c49-5fe3181126a2.png)

次の画面ではGoogleHomeがどういう言葉に反応して、どう答えて欲しいか、どう解釈してほしいかを設定します。

![hai2.png](https://qiita-image-store.s3.amazonaws.com/0/97363/99023d3a-d54b-829d-4543-c0fefa18cc24.png)

**What do you want to say?**に「メモして $」と入力します。
そうすると、GoogleHomeは「メモして」というキーワードに反応して、IFTTTとの連携を呼び出してくれるようになります。
また、**$**はワイルドカードのようなもので、「メモして」以降の言葉がここで認識されます。（後述するアクションで、**$**で受け取った値を利用します。）

(optional)となっているところを利用すると、「メモして」以外の言葉も同じくキーワードにすることができます。

**What do you want the Asisstant to say in response?**には、このトリガーが実行された後のGoogleHomeの返事を書きます。

最後に、**Language**ですが、これは言葉の通りに言語を選択しましょう。

### アクションの設定をする

トリガーの作成が終わると、また選択画面に戻りるため「+that」を選択してアクションを設定します。
サービスの中から「Webhook」を選んで、「Make a web request」を利用します。

![スクリーンショット 2017-12-13 18.38.46.png](https://qiita-image-store.s3.amazonaws.com/0/97363/5385a30b-fac4-d6b1-9e31-e7b043a88167.png)

この画面ではGoogleHomeがトリガーを解釈した後に、どういうアクションをおこなうのかを設定します。

今回はFirebaseにメッセージを登録するため、**URL**にはFireabaseのURLを入力します。
さきほどのサンプル通りの設定であれば、URLは`https://${FIREBASE_PROJECT_ID}.firebaseio.com/message.json`で問題ないです。
※ `${FIREBASE_PROJECT_ID}`には設定したFirebaseのプロジェクトIDをいれてください。

**Method**はFirebaseに書き込みをおこなうため、`POST`に設定します。

**Content Type**も`application/json`にしましょう。

そして、さきほどのトリガー設定時に「メモして。 $」と入力しましたが、この`$`の部分を`{{TextField}}`として受け取ることができます。
そのため、**Body**でには以下のように記述をします。

```json:Bodyのサンプル
{"text": "{{TextField}}"}
```

![hai.png](https://qiita-image-store.s3.amazonaws.com/0/97363/5697f7a0-5359-35f3-9099-afe5d2ec6bb7.png)

入力が終わったら「Create action」をクリックしましょう。

これでGoogleHomeに「メモして。XXXXX」と話しかければ、メッセージが`{"text": "XXXXX"}`という形式でFirebaseのDBに登録されるようになりました。

![スクリーンショット 2017-12-14 0.13.04.png](https://qiita-image-store.s3.amazonaws.com/0/97363/b033fd81-f465-eeda-6e89-2983e216daa0.png)

# 5. ShellからFirebaseのデータを利用する
## ShellからFirebaseのデータを利用する
それでは、Shellからメッセージを利用してみます。

Firebaseはリソースのエンドポイントを叩くとJSONを返してくれます。
そのため、`curl`で`https://${FIREBASE_PROJECT_ID}.firebaseio.com/message.json`に対してリクエストを投げれば、Firebaseにの`message`に保存されているメッセージを得ることができます。

```sh
$ curl https://${FIREBASE_PROJECT_ID}.firebaseio.com/message.json
{"-L0FKci4hltOsazXKs0k":{"text":"明日 は マック を 受け取り に 行く"},"-L0FQY-NR-KS2nlUBP9L":{"text":"明日 は 飲み 会
"},"-L0FQrMh_dGigSFCr4Wn":{"text":"滑 舌 悪い と 辛い"}}%    
```

## JSONをパースする

しかし、得られる値はJSON形式のため、そのまま利用することはできません。
そのため、ShellでJSONを利用するために、`jq`を利用します。
※`jq`については[この記事](https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af)が参考になります。

`jq`を利用して、以下のようなコマンドを叩くとFirebaseに保存されたメッセージの一覧になって出力されます。

```sh
# curlの-sで進捗状況を非表示にする
$ curl -s 'https://${FIREBASE_PROJECT_ID}.firebaseio.com/message.json' | jq .[].text -r
明日 は マック を 受け取り に 行く:
明日 は 飲み 会
滑 舌 悪い と 辛い
```

`.[]`でキーに関係なく`message`の中身を配列として全て取り出し、それらを`.text`で`text`属性のみを返すようにフィルタしています。
そして、`-r`をつけて結果からダブルクオーテーションをなくしました。

これでFirebaseのメッセージを取得することができました。

## メッセージの絞込みをする

とはいえ、このままではDBに登録したメッセージが羅列されているだけに過ぎません。
そこで、メッセージの絞込みをできるようにするため、`peco`というツールを利用します。
※`peco`のについて[この記事](https://qiita.com/xtetsuji/items/05f6f4c1b17854cdd75b)が参考になります。

以下のコマンドを実行すると、下記のような画面で音声メモを絞り込んで探すことができます。
`curl -s 'https://${FIREBASE_PROJECT_ID}.firebaseio.com/message.json' | jq .[].text -r | peco`

これを`google-home-memo`というaliasにしておくことで、下記のように使えます。

![peco-message.gif](https://qiita-image-store.s3.amazonaws.com/0/97363/da90f4da-1038-3127-6c1e-b3cff6db5127.gif)

## google-home-memoを利用する

この結果をパイプで渡すことで様々なことに使えます。

```sh:利用例（Mac）
google-home-memo | pbcopy # クリップボードに入れて使えます
google-home-memo | say    # Macが喋ってくれます
```

GoogleHomeの可能性の幅が広がりますね（？）

# 最後に
いかがだったでしょうか。
こんなアホらしいエントリを最後まで読んでいただきありがとうございました。

今回はGoogleHomeとFirebaseを繋げる手段としてIFTTTを使いましたが、この方法だとでは、FirebasのDBを公開な状態にしなければならず、良いやり方ではないと思います。
これを日常的に使ってみたいという物好きな方はDialogFlow経由で利用してみるのがいいかもしれません。

# 参考文献
[新着メールを知らせてくれるGoogle Home](https://qiita.com/tetotetote/items/4d6ac866b716695fa4c9#_reference-e0362f4ee834c2c58f28)
[さまざまなサービスが連携できる「IFTTT（イフト）」の使い方](http://www.atmarkit.co.jp/ait/articles/1711/22/news031.html)
[jq コマンドを使う日常のご紹介](https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af)
[pecoの基礎の基礎](https://qiita.com/xtetsuji/items/05f6f4c1b17854cdd75b)