Slackには普通の環境と、それを拡張したエンタープライズグリッドという環境があります。
通常はエンタープライズグリッドを考慮した開発を行わないと思うので、いざやってみると挙動がおかしいぞ?ということが発生して、その違和感にモヤモヤしながら開発をすることになったりします。エンタープライズグリッドは少し特殊な環境だと言えます。
何が起こるのか
アプリのホーム画面に機能性を与えるような実装をしている場合に困難が生まれます。
例えば、開発中のChatGPT対応アプリだと、以下のような画面の実装があります。
ピンクの枠で囲った部分は、当該ワークスペースで、機能をOn/Offするようなトグルボタンになっていて、そのワークスペースの設定を格納するためのテーブルにその値を格納しています。
例えばそのテーブル名をWorkspaceSettingsとしておきましょう。
この中には team_id というワークスペースIDを格納するカラムが存在し、それらをキーとしてレコードを取得するようになっています。
通常のワークスペースではそのやり方で構わないのですが、エンタープライズグリッドだとこのやり方を実現するには少し工夫が要ります。
エンタープライズグリッドの仕様の謎
エンタープライズグリッドでは、一つのエンタープライズIDの元に、いくつものワークスペースを配置することができます。
これは、表現として正しくは無いと思うのですが、内部的には恐らくエンタープライズグリッドという1つの契約が通常のワークスペース一つの契約と同等になっていて、ワークスペースIDによってその一つの箱を切り分けているだけなのではないかなと。
そのため、例えばワークスペースAでSlackコネクトで外部の人とつなぐと、他のワークスペースのDM欄からもアクセスすることができます。ワークスペースという意味でいうと異なるものという形には恐らくなっていないのではないかと考えています。
エンタープライズグリッドで起こる現象について
これはアプリのホーム画面やDMでの実装のみに関して違和感を覚えるだろうなという話になっています。通常のチャンネル上のメッセージイベント等では発生しません。上述の通り、ホーム画面はエンタープライズグリッド内のどのワークスペースからでもアクセスできるというものであり、決して別れたものという認識にはならないようです。
正しい team_id が返ってこない
例えば、先程示した画像のボタンを押したとします。
action_idをclick_buttonとしていた場合、そのアクションは以下のような形でキャッチします
@app.action("click_button")
def click_button_hundler(ack, body, logger, client, view, context):
print(body["team"]["id"])
print(context["team_id"])
このbody["team"]["id"]/context["team_id"]は正しいidかどうかはわかりません。
複数のワークスペースで試すと、一つのteam_idしか返ってこないでしょう。
エンタープライズグリッドでテストする場合は、複数のワークスペースを作った上でテストをしてみると良いと思います。
正しいteam_idが返ってくるのは app_home_opened の時のみ
ものすごく重要な点です。
正しいワークスペースIDが返ってくる唯一の瞬間が、アプリのホーム画面を開いた瞬間です。
このときの body['team_id'] には、きちんとそのワークスペースのIDが含まれています。
ホーム画面からの処理ではこのIDを引っ張り回しましょう。
先程のボタンのトグル処理の場合は、ボタンのvalueにteam_idを仕込んで引っ張り回しています。モーダルで続いていくような処理の場合はprivate_metadataのなかに格納してしまえばOK。
まとめ
エンタープライズグリッドのアプリのホーム画面・DM画面は特殊なので気をつけましょう。
テスト環境だとエンタープライズグリッドの複数ワークスペース作ってまで検証しない場合が多いと思うのですが、かなりハマりどころの大きな点だと思います。
上記の不具合は、以下のアプリのユーザーからの報告で気付きました。
ChatGPTをSlackで活用できるアプリになっています。無料で使えますので是非使ってみてください。