GAミント至上主義

Web Monomaniacal Developer.

Google Hangouts ChatでAPIからスレッドを指定して書き込む

以前のこの記事の続き。チャットから返信できるようになったけど、ユーザーの書き込みが毎回新スレッドになるため、同一ユーザーの書き込みは同じスレッドにしたかった。

uyamazak.hatenablog.com

要約としては、書き込み成功のレスポンスにthread.nameが入っているので、それを保存し、2回目以降はそれをリクエストに追加すればおk。

メッセージ全体流れ

大きく分けて1.Firestore→Chat、2.Chat→Firestoreの流れとなる。

前者はWebhook、後者はbotを使うため大きく異なり自分でもよく分からなくなるので整理する。

1. ユーザーがチャットに書き込む(Firestore→Chat)

ユーザーがメッセージをFirestoreに書き込み、Cloud Functionsでそれを受け取りChatのWebhookにポストする

ユーザー側の画面はこんな感じで、メッセージフォームと自分と管理者を合わせたメッセージ履歴(Firestoreのデータ)がある
f:id:uyamazak:20181001115202p:plain
※画面は開発中のものです

2.管理者からユーザーへの返信(Chat→Firestore)

Chatに招待したCloud Functionsのbotに@指定でユーザーIDとメッセージを送る。
botでFirebase-adminを用い、ユーザーIDを使ってメッセージを書き込む。

Chatでのやりとり画面はこんな感じになる。
f:id:uyamazak:20181001115230p:plain
指定されたIDがなかった場合エラーを返す機能も付けた。

2回目以降にスレッドを指定して書き込む

1のWebhookのスクリプトで書き込みが成功すると、Messageオブジェクトが返ってきて、その中にthread.nameがあるのでそれをFirestoreに保存しておく。
こんな感じで取れる。awaitを使いたかったのでrequest-promise-nativeを使用した

const rp = require('request-promise-native');
const resultBody = await rp.post(options)
threadName = resultBody.thread.name

これをFirestoreの該当ユーザーのドキュメントに書き込んでおく。
今回は/usedata/{uId}/chatmetaみたいなドキュメントパスを使用した。

2回目以降はChatに書き込む前にこのドキュメントの有無を見て、あったら

if(threadName){
  data['thread'] =  {name:threadName}
}

のような感じでPOSTするdataに追加する。

全体のソースを貼りたかったけど汚すぎたので止めた。デザインができるまでには整理したい。
Chat側で指定したスレッドやそもそもルーム自体を消してしまった場合は処理できてない。

スレッド指定の書き込み方法はドキュメントが見つからなかったけど、Messageオブジェクト通りにやれば他のオプションもいろいろできそう。

REST Resource: spaces.messages  |  Hangouts Chat API  |  Google Developers