Hangouts Chatbotをdialogflowを利用してもっとbotらしくする

# はじめに

簡単に人の名前から、今その人が会議中なのか、単に離席しているのか知りたいな。
よし、ボット作ろう！と思ったのがきっかけです。

こんな背景があります。

- いつもはslackのbotを作っていますが、GSuiteでのセキュリティ周りで色々難しいので今回はHangouts Chatbotで作成
- サーバーは自分で用意しない。管理とか嫌だよ。
- 何かもっと会話っぽいもの作りたいな。名寄せとかもできるようにしたい。

特定のメッセージ形式(コマンド的な) で応答を返すのではなく、会話っぽい感じでエンジニアの人じゃない人が「お、botっぽい」と思えるものを作る・・・よし！ Dialogflow試してみよう！と思い作ってみました。

# 結論

Dialogflow使う事で下記が簡単に実現できます！すごい・・・！

- 名寄せ楽！！！！！
- エンティティの抜き出しがすごい楽！！！！！

プロダクトとしては管理とか色々大変だから使いたくないけど、社内で使う分には結構良いかも！という印象です。
ほんのちょっとだけ、会話っぽいことするbotを作りたいなと思っている方に、お勧めです。
slackですと、そのまま連携できますし、楽しいと思います！

## 名寄せが楽
エンティティで、synonymを作ります。
例えば下記例ですと、「自分」、「僕」、「私」が全て「自分」という文字列として受け取る事ができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/268550/ee3fce56-2aee-44cd-f7e7-4ec544aa4952.png)

## エンティティの抜き出しがすごい楽。
ある程度の文章パターンを登録して期待結果を登録するだけで、いろんな文章パターンを対応できます。トレーニングってすごい。これが機械学習の力なのか・・・！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/268550/f2ff48e1-8dad-fddb-4aa0-482948acf0f0.png)

[Cloud Natural Language API](https://cloud.google.com/natural-language/)使うか迷ったのですが、多分圧倒的にこっちが楽。
下記のように、結果parametersからそれぞれ `PERSON` 、 `TIME` として解析された結果を受け取るだけですもん。

```javascript
  //dialogflow detectIntent呼出し
  //https://dialogflow.com/docs/reference/api-v2/rest/v2/projects.agent.sessions/detectIntent 
  var response = UrlFetchApp.fetch(Utilities.formatString(dfUrlFormat, this.id), options);
  var results = JSON.parse(response.getContentText());

  //色んな処理

  results.queryResult.parameters.PERSON  ←ここにPERSON エンティティが入る。
  results.queryResult.parameters.TIME    ←ここにTIME エンティティが入る。
```


# 出来たもの

Google Apps Scriptのソースは、下記リポジトリに保管しています。
https://github.com/h-r-k-matsumoto/hangout-calendar-bot

- claspを使っているので拡張子はjsに自動的に変換されています。
- GAS側の動きは、上記リポジトリのREADME.mdを参照して頂ければと思います。

## 今会議中かどうか知る
適当に1人以上の名前を指定して状況を知る事ができます。
そう、会議中なのかどうなのかが知りたいのです。電話取次とかで「あの人どこいってるん？」というサクッと知りたい。カレンダーとか見るのもだるい場合 (チーム全員いない場合とか )があるので、これを作りたかった・・・！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/268550/6e18f5ae-c397-3d0d-212e-c46bea39ac75.png)

## 明日の予定を確認する。
まぁ…とりあえず作ってみた感じですね。Hangouts Chatの応答パターンとしてもうちょっとシンプルにしてみました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/268550/5bbd0456-31da-2a70-71d2-556bad591b84.png)


## チームの予定を確認する
チーム名で確認することもできます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/268550/bb9def58-994d-7ed4-1480-434100faf59f.png)

# 仕組み
ざっくりこんな感じです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/268550/4cd33687-c823-d81b-5620-4a8a2ff98328.png)

後は、
[https://github.com/h-r-k-matsumoto/hangout-calendar-bot/blob/master/README.md#仕組み](https://github.com/h-r-k-matsumoto/hangout-calendar-bot/blob/master/README.md#%E4%BB%95%E7%B5%84%E3%81%BF)
を見てください。

# ハマるポイント

## Dialogflow→GoogleAppsScriptじゃないの？
多分Dialogflowを学ぶと、Dialogflow→Google Apps Scriptという構成を思い浮かべると思います。
2018年現時点では、slackとは連携するのですが、hangouts chatとは連携機能はありません。

そのため、 Google Apps ScriptからDialogflowを呼び出すようにしています。

## どうやってOAuthで認可させるの？
https://dialogflow.com/docs/reference/v2-auth-setup
上記には、Google Apps Scriptとの連携書いてないんですよね。
とりあえず上記の通りサービスアカウントを作成します。
そして、 [Apps-Script-GSApp-Library](https://github.com/Spencer-Easton/Apps-Script-GSApp-Library)を利用して、認可させてます。

## グループ、人の検索は、Admin SDK使わないの？
人の検索はできたのですが、グループの検索は、permission無かったんです。
G Suite管理者の人に掛け合うほどのもんでもないし、まぁいいかと独自のデータ持ってます。

## `@meet bot` で良くない？
`@meet bot` 使った方がきっといいです。でも自分たちは使えませんでした。
※恐らく管理者に外部のbotが止められてる。

まぁ作ってみたかったので、G Suite管理者の人に掛け合うほどのもんでもないし…という感じです。

# これからまだやりたいこと
会話ですよね。
sessionを使ってもうちょっと上手い事会話したり、いろんな機能…作りたいけど需要が無いので、いまいちやる気がおきませんが、ちょっと上手い事使えそうな仕組み考えて改良していきたいなと思ってます。

# 参考

- Dialogflow: https://dialogflow.com/
- clasp: https://github.com/google/clasp
- まずはDialogflowを触ってみる：https://qiita.com/sanoh/items/efd99ebbdee294a7beb3
- Google Apps ScriptでService Accountを利用して認証する:https://qiita.com/soundTricker/items/63da2f5cf98088542821