LoginSignup
8
5

REST APIを用いてGASからGoogle Chatに「返信」を行う@インラインスレッド対応

Last updated at Posted at 2023-05-25

はじめに

本稿では、Google ChatのWebhookを用いて、Google Apps Script(GAS)のBOTからインラインスレッドに自動返信する際の注意点をまとめます。

背景

Google Chatでは、2022/12/11にインラインスレッド機能がリリースされ、続く2023/03/13に旧来のトピック機能が廃止されました。
トピック機能が廃止されるまでは、スペース作成時に「会話をトピック別に整理する」のチェックをオンとすることでトピック表示できましたが現在は、新しく作成されるスペースはすべてインラインスレッド形式になります。

トピックの表示例
image.png

インラインスレッドの表示例
image.png

2023/05現在、過去作成済みのトピック表示スペースはそのまま使えます。

Google workspace Updates note
https://workspaceupdates-ja.googleblog.com/2023/03/2023-3-13-google-chat.html

GASを用いたBOTからの投稿

Google Chatに対してBOT投稿をするための方法は、www上に多数公開されています。
また、トピック表示に対して返信を行う方法も多数公開されており、比較的容易に実現が可能です。

本稿では、投稿時のレスポンスも含めて簡単に記載します。

参考:Google Chat APIガイド
https://developers.google.com/chat/api/reference/rest?hl=ja

GASで、投稿をするサンプルは以下になります。
事前にチャットスペース側で「アプリと統合」
image.png

から、「Webhookを管理」に移動し
image.png

webhookを追加します。
image.png

追加後webhookのURLをコピーし、GASコードのurlへ適用します。

Google Chatの利用シーンとして、プロジェクト毎、係の仕事毎などでスペースが設立されることが多いかと思います。その際に、各スペースでデイリーの報告などをメッセージで乱立させるとログが流れすぎる問題があります。
本稿のGASは、デイリー報告用のスレッドに対するしおり機能をイメージして日付を投稿するサンプルとしています。

GASコードサンプル

function bot_message() {
  var url = "https://chat.googleapis.com/v1/spaces/XXXXXXXXXXX/messages?key=XXXXXXXXXXXXXXX";
  
  var dt = new Date();
  var today = dt.getFullYear() + "" + (dt.getMonth()+1) + "" + dt.getDate() + "";
  
  var json_msg = {
    "text" : "```" + today + "```\n",
  }
  
  var json = JSON.stringify(json_msg);
  var options = {
    "method" : "POST",
    "contentType" : "application/json; charset=utf-8",
    "payload" : json
  }
  
  var response = UrlFetchApp.fetch(url, options);
  Logger.log(response);
}

トピックに投稿する

トピック表示のスペースに対して投稿を行った場合、新規投稿が行われます。
image.png

塗りつぶしていますが、投稿のレスポンスを確認すると、生成されたスレッドの識別子(name)が把握できます。
image.png

このスレッド識別子を指定して投稿することで、当該トピックに対して返信の形で投稿することができます。

function bot_message() {
  var url = "https://chat.googleapis.com/v1/spaces/XXXXXXXXXXX/messages?key=XXXXXXXXXXXXXXX";
+  var thread = "spaces/XXXXXXXXXXX/threads/XXXXXXXXXXXXXX";
  
  var dt = new Date();
  var today = dt.getFullYear() + "" + (dt.getMonth()+1) + "" + dt.getDate() + "";
  
  var json_msg = {
    "text" : "```" + today + "```\n",
+    "thread": {
+      "name": thread,
+    },
  }
  
  var json = JSON.stringify(json_msg);
  var options = {
    "method" : "POST",
    "contentType" : "application/json; charset=utf-8",
    "payload" : json
  }
  
  var response = UrlFetchApp.fetch(url, options);
  Logger.log(response);
}

image.png

インラインスレッドに投稿する

では、インラインスレッドのスペースに対しても同じことを実施してみます。

image.png

実行ログはこちら。
image.png

※説明のため、末尾3文字分のIDだけマスク外にしています。

同様に、スレッド識別子を指定して再度実行します。
image.png

投稿には成功しましたが、返信ではなく新規スレッドになってしまいました。
ログを確認すると異なるスレッド識別子が返却されており新規投稿となっています。
image.png

Google ChatのREST APIの説明を読むと、スレッドに返信するには次のオプションを設定する必要があるようです。

MessageReplyOption

image.png

トピック表示スペースに対してはこのオプションの指定はせずとも同一スレッドへの返信となりましたが、インラインスレッドのトピックに対してはこのオプションを正しく指定する必要がありそうです。

メッセージと共に送信する方法を試しましたが何れもエラーとなり、最終的にGETの引数として指定することで動作してくれました。

function bot_message() {
  var url = "https://chat.googleapis.com/v1/spaces/XXXXXXXXXXX/messages?key=XXXXXXXXXXXXXXX";
+  var res_swith = "&messageReplyOption=REPLY_MESSAGE_OR_FAIL";
  var thread = "spaces/XXXXXXXXXXX/threads/XXXXXXXXXXX_b8";
  
  var dt = new Date();
  var today = dt.getFullYear() + "" + (dt.getMonth()+1) + "" + dt.getDate() + "";
  
  var json_msg = {
    "text" : "```" + today + "```\n",
  }
  
  var json = JSON.stringify(json_msg);
  var options = {
    "method" : "POST",
    "contentType" : "application/json; charset=utf-8",
    "payload" : json
  }
  
-  var response = UrlFetchApp.fetch(url, options);
+  var response = UrlFetchApp.fetch(url + res_swith, options);
  Logger.log(response);
}

image.png

まとめ

発言をHookしてBOTにレスポンスさせる場合など、返信を活用したいシーンは多く、インラインスレッドとなってから二カ月ほど経ちましたが、検索をしてもなかなかサンプルコードに出会わなかったため、Qiita投稿として記録しておきます。

最終GASコードサンプル

function bot_message() {
  var url = "https://chat.googleapis.com/v1/spaces/XXXXXXXXXXX/messages?key=XXXXXXXXXXXXXXX";
  var res_swith = "&messageReplyOption=REPLY_MESSAGE_OR_FAIL";
  var thread = "spaces/XXXXXXXXXXX/threads/XXXXXXXXXXXXXX";
  
  var dt = new Date();
  var today = dt.getFullYear() + "" + (dt.getMonth()+1) + "" + dt.getDate() + "";
  
  var json_msg = {
    "text" : "```" + today + "```\n",
  }
  
  var json = JSON.stringify(json_msg);
  var options = {
    "method" : "POST",
    "contentType" : "application/json; charset=utf-8",
    "payload" : json
  }
  
  var response = UrlFetchApp.fetch(url + res_swith, options);
  Logger.log(response);
}
8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5