音声で作業工数を記録して進捗をバーンダウンチャートで確認できるシステムを作成【スプレッドシート（GASでHTTPサーバ化）＋GoogleAssistant＋Dialogflow＋Googleサイト】

# 作ったもの

　Google Homeから音声で作業工数を記録できて、ダッシュボードで進捗のバーンダウンチャートを確認できるシステム。


## バーンダウンチャート
↓のようなグラフ
![image6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186338/facd9b54-9d5d-886b-0dd2-8a9434c5b194.png)
　使用例：[バーンダウンチャートで子どもの夏休みの宿題を「マネジメント」した話](https://backlog.com/ja/blog/manage-kids-summer-homework-with-burn-down-chart/)


# 動機
## なぜ音声記録か
### 早い
*   スマートスピーカーは常時スタンバイ状態なので、アプリ起動を待たずにいきなり入力できる
    *   スマホだと入力までに何ステップもかかってしまう。
    *   電源ON　＞　ロック解除　＞　アプリ起動　＞　入力

### 楽
*   入力に手を使わなくて済むので、ながら作業で入力ができる
*   1日に使用できるWillパワー（意志力）は限られている。Willパワーを消費しない楽な入力方法には価値がある。

記録が早く楽になることで、敷居が下がり、習慣化しやすくなる。

## IFTTTに対するメリット

[IFTTT](https://ifttt.com/)でも簡単に音声記録システムは作れるが、Dialogflowで作れば以下のようなメリットが得られる。

*   日付値を扱いやすい形式で記録できる
    *   IFTTT：「March 3, 2019 at 10:40PM」のような形式。日時ごとの集計がしにくい。
    *   Dialogflow：「2020/05/02 10:38:36」のような形式。スプレッドシート標準の日付関数で扱える。
*   一貫した文字列タグでシートに記録できる
    *   IFTTT：音声認識の表記ゆれがログデータのタグに反映されてしまうため、集計時に文字列一致が使えない。
    *   Dialogflow：EntityのEntryを定義するので、音声認識の表記ゆれを吸収してくれる。一貫したタグでログデータを記録できるため、集計時に文字列一致が使える。
*   応用が利く
    *   GASでHTTPサーバ化するので、POSTリクエストを受け付けるときに複雑な処理が追加できる。

# 構成
## 大まかな動作の流れ
　 Google HomeやAndroidスマートフォンを通してGoogleアシスタントに作業内容・時間を伝えると、Google Apps ScriptでHTTPサーバー化したGoogleスプレッドシートにログが蓄積され、スプレッドシート上で集計してグラフ化されたバーンダウンチャートが、Googleサイトで作成した自分用のダッシュボードに表示される。

## システム構成


### 音声記録部分
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186338/f9f1e996-ba9b-3303-9411-31d4fa341412.png)

### 閲覧部分
![image8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186338/1f0cb6ef-7872-f128-60ad-a26b19d9849b.png)

## 工数記録のフロー
![image8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186338/8497095f-03b7-f775-260e-4a5c23bd6868.png)

# 作成手順

（youtube動画）
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Dialogflowで音声記録システムを作る <a href="https://t.co/R3Hzp8nrdt">https://t.co/R3Hzp8nrdt</a> <a href="https://twitter.com/YouTube?ref_src=twsrc%5Etfw">@YouTube</a>さんから <a href="https://twitter.com/hashtag/output?src=hash&amp;ref_src=twsrc%5Etfw">#output</a></p>&mdash; lilacs2039 (@lilacs2039) <a href="https://twitter.com/lilacs2039/status/1259342437631160323?ref_src=twsrc%5Etfw">May 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



## 使用アプリのリンク集

*   Actions on Google　Webコンソール \
    [https://console.actions.google.com/](https://console.actions.google.com/)
*   DialogFlow　Webコンソール \
    [https://dialogflow.cloud.google.com/#/agents](https://dialogflow.cloud.google.com/#/agents)
*   Googleスプレッドシートのテンプレート（拙作）　[https://docs.google.com/spreadsheets/d/1LzH29bLqq5hnjsGysyNavO5jqdI6b2TpO6FuiQ7s2Yc/edit?usp=sharing](https://docs.google.com/spreadsheets/d/1LzH29bLqq5hnjsGysyNavO5jqdI6b2TpO6FuiQ7s2Yc/edit?usp=sharing)
*   Google Sites \
    [https://sites.google.com/new](https://sites.google.com/new)

# 各アプリについて
### Actions on Google
Google アシスタントの開発プラットフォーム。Dialogflowで作成したエージェントをテストしたり、デプロイしたりできる。

参考サイト

* Actions on Googleの公式Docs　会話アクションの概説
  * [https://developers.google.com/assistant/conversational/overview] 
> ![image10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186338/de73fa68-97b4-aad3-1009-2eec20fe27f4.png)
> Actions on Googleの公式Docs　会話アクションの外観　より。Dialogflowを使用した場合の会話の全体像

### Dialogflow

　Dialogflowは、会話型UIを設計して音声応答システムが作れる自然言語理解プラットフォーム。人間の入力から、発音の曖昧さや表記ゆれ、言い回しの違いをいい感じに吸収して、コンピューターが扱いやすい形式に変換してくれる。

> ![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186338/f1898c68-bd96-fcc0-35de-910162511703.png)
> Dialogflowの公式Docs　Dialogflowの基本より
> インテントのマッチングとエンドユーザーへの回答の基本フロー

**構成要素**

-   **エージェント（Agent）**
    -   人間の言語のニュアンスを理解する自然言語理解モジュール
    -   Dialogflowの１つのプロジェクトがエージェントに対応する。
    -   本記事では、「work-record1」というエージェントを作成した
-   **インテント（Intent）**
    -   1 回の会話ターンにおけるエンドユーザーの意図を分類する。
    -   以下のものが含まれる。
        -   **トレーニング フレーズ（Training phrases）**：エンドユーザー表現のサンプルフレーズ。エンドユーザー表現がいずれかと似ている場合、Dialogflow によってインテントがマッチングされる。
        -   **アクション（Action）**：インテントがマッチングしたときにトリガーするアクション。
        -   **パラメータ（Parameters）**：エンドユーザー表現からどんな値を抽出するかの定義。エンティティ タイプ（数値型、日付型、自作etc...）に沿って値が抽出されるので、ロジックの実行やレスポンスの生成に簡単に使用できる。
        -   **回答（Response）**：テキスト、音声、視覚的な回答を定義してエンドユーザーに返す。
    -   本記事では、以下の２つを使用した。
        -   初期状態で用意されている「Default Welcome Intent」
        -   新規作成した「作業を記録」Intent
-   **エンティティ（Entity）**
    -   エンドユーザー表現のデータの抽出方法を指定する。２種類のエンティティがある。
        -   事前定義のシステム エンティティ
            -   例：日付、時刻、色、メールアドレスなど
            -   本記事ではwork-timeエンティティを作成した。
            -   公式のシステム エンティティ リファレンス \
[https://cloud.google.com/dialogflow/docs/reference/system-entities](https://cloud.google.com/dialogflow/docs/reference/system-entities)
        -   独自定義できるカスタム エンティティ
            -   本記事ではwork-targetエンティティを作成した。
    -   **エントリ（Entry）**
        -   エンティティ タイプごとに多数のエンティティ エントリを定義できる。
        -   本記事では、「work-target」エンティティに、「制御２級」「情報２級」の２つのエントリを定義した。
        -   ![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186338/e02639f4-9684-f6ab-5077-8dec9ee08ea1.png)

-   **フルフィルメント（Fullfillment）**
    -   Fullfillment：通信販売においては、受注から配送までの一連のプロセス全体のこと（受注、梱包、在庫管理、etc...）
    -   Dialogflowにおいては、外部サービスとの連携の設定。以下２つのどちらかを選べる。
        -   Webhook：外部サーバへPOSTリクエスト
        -   Google Cloud Functions（Node.js）で処理
    -   本記事ではHTTPサーバ化したスプレッドシートにPOSTリクエストを送り、GASでJSONを解釈してシートに作業内容・作業時間を記録した。
-   **コンテクスト（Context）**
    -   （今回は使用しなかった。）

参考サイト

*   Dialogflow　公式Docs　[https://cloud.google.com/dialogflow/docs/](https://cloud.google.com/dialogflow/docs/)
*   Dialogflow　公式Docs　Dialogflowの基本　[https://cloud.google.com/dialogflow/docs/basics](https://cloud.google.com/dialogflow/docs/basics)
*   <span style="text-decoration:underline;">Qiita記事　[Dialogflow入門](https://qiita.com/kenz_firespeed/items/0979ceb05e4e3299f313#fulfilintent%E3%82%92%E4%BD%BF%E3%81%86)</span>


### Googleスプレッドシート

Google版エクセル。データ本体がGoogleのサーバにあるので、各種WEBサービスとの連携やデータ公開に優れている。


### Google Apps Script（GAS）

G Suiteアプリ開発プラットフォーム。スプレッドシートのマクロを作成したり、WEBアプリを作成したり、カレンダーなど他のGoogleサービスとやり取りしたりできる。

　本記事ではスプレッドシートにGET/POST処理を記述したスクリプトを追加することでHTTPサーバ化した。

参考サイト



*   Googleスプレッドシート（GASでHTTPサーバ化）
    *   [Google Spreadsheet を簡易 Webサーバーとして動かして、手軽にWebHookを受け取る方法](https://qiita.com/kunichiko/items/7f64c7c80b44b15371a3)
    *   [3分で API を作って世の中にデプロイするライブコーディング〜今日から君もスピードスターエンジニア](https://qiita.com/numanomanu/items/7bb6542961a2c567f05c)
*   GAS　公式Docs　[https://developers.google.com/apps-script/overview](https://developers.google.com/apps-script/overview)
*   公式ガイド　GET/POSTで使えるリクエストオブジェクトのパラメータなど \
[https://developers.google.com/apps-script/guides/web](https://developers.google.com/apps-script/guides/web)


### Google Sites

　WYSIWYGでWEBサイトを作れるサービス。2016年にリニューアルされた。プロジェクトや部署内の情報共有など、小規模組織の情報共有のような使い方が想定されているみたい。

　GoogleカレンダーやTodoistなどWEBアプリを埋め込むことができて、セルフマネジメント用のダッシュボード作成に便利そうだったので採用した。

参考サイト



*   Googleサイトヘルプ　Googleサイトの使い方　[https://support.google.com/sites/answer/6372878?hl=ja](https://support.google.com/sites/answer/6372878?hl=ja)


# 課題

２回に分けて入力（「OK Google, 作業記録」「制御２級 １時間」）ではなく、１回で入力（「OK Google, 作業記録で作業を記録、制御２級 １時間」）する方法があるようですが、うまくいかなかったので、分かる方がいらっしゃれば教えていただければ幸いです。