このブログでも
「WebSocket」 のネタをたまに載せていたりしますが、Slackアプリでも 「ソケットモード」 と呼ばれる方式で、前回説明したような外部のTCPトンネリングサーバーを経由することなしに NAT越え できる仕組みが用意されています。


合同会社タコスキングダム|蛸壺の技術ブログ
自宅Slackサーバーの作り方〜Bolt-js(Bolt for Javascript)で試す

簡単なチャットプログラムをbolt-jsで作成する手順をを中心に噛み砕いて解説していきます。




デフォルトではソケットモード機能はオフになっていますので、今回は前回のブログの内容の補講的な内容として、ソケットモードからSlackサーバーを構築する手順にも触れてみようと思います。


合同会社タコスキングダム|蛸壺の技術ブログJavascript(js)&Typescript(ts)プログラミング入門〜これから学ぶ人のためのおすすめ書籍&教材の手引き

ソケットモード用のSlackボットの準備



この記事の執筆時で、ソケットモード機能が2021年1月から正式にリリースされてちょうど1年たった頃合いですので、まだまだ認知度の低い機能かと思います。
Slackアプリの通常モードを用いる場合、自宅のローカル機で構築しオンプレで運用をさせることを考慮したSlackサーバーを構築する際には、
「NAT越え」 がかなりハードルの高い課題になるのは前回の記事でもお話しました。
通常モードでは、外部のTCPトンネリングサービスを利用するのがもっとも早い方法なのですが、ソケットモード登場以前ではSlackとは別のサービスに登録する必要があって、それが手間と場合によっては費用のかかるのが問題になっていました。
とはいえ、ここ数年でWebSocketやWebRTCなどのTCP/UDPベースの通信プロトコルの整備や対応するブラウザ・通信速度の飛躍的な向上も相まって、NAT越えの手段の選択肢も大幅に増えてきています。
こうした風潮にSlackも例外ではなく対応する必要もあり、外部サービスに依存しないSlackの提供するサービスドメイン内で完結させるため、
「ソケットモード」 が満を持して使えるようになったのが(この記事の執筆時点から)約1年前です。
以下の図はSlackサーバーを自宅や職場のローカル機で起動させることを考えたときの構成を模式的に示したものです。

合同会社タコスキングダム|蛸壺の技術ブログ


前回説明した通常モードでは、ngrokに代表されるような外部のTCPトンネリングサービスからSlackサーバー機を監視してもらい、オンラインのSlackはエンドポイントとしてngrok側のアドレスを踏むことで通信が確立するような構成になっています。 これはSlackサーバーに限らず、自宅にSSHサーバーなどを立てるときにも使える汎用な方法です。
対してソケットモードでは、Slackのローカルとリモートを先にWebSocketコネクションを確立させておくことで、サードパーティのサービスを利用すること無しにSlackクライアントとの通信が容易に可能となります。
Slackアプリを使っている開発者からすると、ngrokのようなサービスを既にガッツリ使われていたり、SaaS上で常時動作させていたりするので、今更無理にソケットモードへ移行するような必要もないでしょう。
他方、これからSlack Boltフレームワークを勉強してみたい開発者の方たちにとっては、NAT越えという忌まわしき呪縛から解放され、かなりお手軽にSlackアプリ開発ができるようになった恩恵がかなりあるものと思います。
企業や組織で働いている方でも、従来のSlackアプリをちょっとしたチーム業務で使いたいツールを使うのにも、会社の情報管理部門にお伺いを立てて、IPを割り当てもらったり、ポートを開けてもらったり、稟議書を提出してみたり...と非常に面倒な手続きもあったかも知れません。
ソケットモードならば、ようはブラウザとSlackの一機能を使っている訳ですので、こういう社内申請は無用です。

Slackボットを作成する



前置きはさておき、まずはSlackボットを一つ作成します。
とはいえ、こちらの手順は
前回説明した通常モードのボット作成手順 と、ソケットモードで全く同じです。
ただし、通常モードではSlackアプリの認証キー(Credentials)として、
「ボットトークンとサイン認証キー(Signing Secret)」 の2つを使うのに対して、ソケットモードでは、 「ボットトークンとアプリレベルトークン」 の2つを使うことが異なってます。
つまり、通常モード・ソケットモードともボットトークンは共通して利用しますが、ソケットモードで使う場合において、サイン認証キーは必要ありません。

そこでこのSlackボットが作成できたなら、次の項目で
「アプリレベルトークン」 を設定してみます。


合同会社タコスキングダム|蛸壺の技術ブログJavascript(js)&Typescript(ts)プログラミング入門〜これから学ぶ人のためのおすすめ書籍&教材の手引き

アプリレベルトークンを取得する




それでは
Slackアプリのダッシュボード からアプリレベルトークンを設定していきます。
ちなみにソケットモードで利用するSlackボットはソケットモード専用のアプリになり、そのアカウントで横断的に利用できるようになります。 一つのボットで通常モードとソケットモードの兼用は出来ませんのでご注意ください。
左側のペインから
[Socket Mode] に入り、 [Enable Socket Mode] のトグルスイッチをONにすることで、ソケットモード用のアプリに移行することになります。

合同会社タコスキングダム|蛸壺の技術ブログ


これで、
Event Subscriptions がWebSocket対応になったことも確認できます。
ソケットモードへと移行した初回は、
アプリレベルトークン を生成するダイアログが立ち上がってきます。

合同会社タコスキングダム|蛸壺の技術ブログ


ここではアプリレベルトークンのタイトルを適当に
MySocketMode にしています。
アプリレベルトークンに付与するアクションスコープは基本的に
connections:write のみを付けていればWebSocket越しに通信できるようになります。
またアプリレベルトークンは
[Basic Information] のページの [App-Level Tokens] から追加・編集することが可能です。

合同会社タコスキングダム|蛸壺の技術ブログ


説明書きの通りで、アプリレベルトークンは最大10個まで登録できます。
つまり、組織ごとにアプリレベルトークンを一つで使い分けることで、同じSlackアプリを最大10の組織で利用管理できることになります。
ソケットモードでは11以上の組織をアプリレベルトークンで管理することが難しいので、そうなってくると通常モードで個別にドメイン管理する必要はあります。
何はともあれ、これでアプリレベルトークンが発行されました。
発行されたアプリレベルトークンを見ると、Tokenの項目に、
xapp-... から始まる文字列が表示されていますので、これをコピーし何処かに控えておきます。

合同会社タコスキングダム|蛸壺の技術ブログ


ついでに左のペインから
[Event Subscriptions] のページも確認しておくと、

合同会社タコスキングダム|蛸壺の技術ブログ


ソケットモードが有効になって、リクエストURLは必要ないよ、という文言が確認できます。


合同会社タコスキングダム|蛸壺の技術ブログJavascript(js)&Typescript(ts)プログラミング入門〜これから学ぶ人のためのおすすめ書籍&教材の手引き

Slackアプリの実装(Typecript対応)

前回の通常モードの実装手順 とほぼ変わりませんが、Credentialsの扱いが異なります。
TypesciptプロジェクトでのSlackアプリの始め方は前回のほうで詳しく解説しましたので、ここでは手順の異なる点だけを説明していきます。


Credentials(アプリレベルトークンとボットトークン)を変数に設定

前回の手順 も説明したように、これらの認証キーはソースコードにハードコードすべきではありません。
ここでも環境変数に埋め込んで、自分だけが使えるようにしておきます。

            $ export SLACK_BOT_TOKEN="ボットトークン(xoxbから始まるもの)"
$ export SLACK_APP_TOKEN="アプリレベルトークン(xappから始まるもの)"

        

これでシェルから参照することができれば準備完了です。

            $ echo $SLACK_APP_TOKEN
<アプリレベルトークン...>
$ echo $SLACK_BOT_TOKEN
<ボットトークン...>

        

Typescriptコードの修正



ソケットモードへ移行する場合、アプリのインスタンスのコンストラクタ引数だけが違うだけです。

前回説明したコード からは以下のように修正します。

            import { App } from '@slack/bolt';

const app = new App({
    token: process.env.SLACK_BOT_TOKEN,
    appToken: process.env.SLACK_APP_TOKEN,
    socketMode: true,
});

//...以下略

        

と、通常モードからソケットモードへの移行はとても簡単です。


合同会社タコスキングダム|蛸壺の技術ブログJavascript(js)&Typescript(ts)プログラミング入門〜これから学ぶ人のためのおすすめ書籍&教材の手引き

ソケットモードの動作確認



ということで、最後に通常モードからソケットモードに移行したソースコードで、Slackサーバーを起動してみます。


            $ yarn build && yarn start
node dist/index.js
⚡️ Bolt app is running!

        

で、見た目や挙動は通常モードの時と全く変わりません。

前回 と同様に、Slackボットを追加したプライベートチャンネルで hello をつぶやいて見ますと、

合同会社タコスキングダム|蛸壺の技術ブログ


のように、レスポンスURLの経由なしに、Slackサービスだけで完結したアプリに仕上がりました。


合同会社タコスキングダム|蛸壺の技術ブログJavascript(js)&Typescript(ts)プログラミング入門〜これから学ぶ人のためのおすすめ書籍&教材の手引き

まとめ



今回は、前回説明した
通常モードのSlackアプリ作成の基礎手順 よりもちょっと進んだ使いこなしにあたる「ソケットモード」に移行するためのポイントを紹介していきました。
ソケットモードが通常モードよりも優れているとか、そういう話ではありませんので、ご自分の置かれたシチュエーションに合った開発環境で使い分けて頂くと良いでしょう。
ソケットモードがもっと流行っていけば、開発者にとって、Slackアプリでの業務ツール製作がより身近になっていくのではないかと思います。

参考サイト

Intro to Socket ModeSlack ソケットモードの最も簡単な始め方