自宅Slackサーバーの作り方〜Bolt-js(Bolt for Javascript)で試す


2022/01/30
蛸壺の技術ブログ|自宅Slackサーバーの作り方〜Bolt-js(Bolt for Javascript)で試す

以前のブログ回でSlack APIをCurlコマンドで叩いて、Slack botに画像ファイルを送信させる方法を紹介していました。

このやり方では単なるSlackボットを設定しただけですので、ターミナル端末から直接Curlコマンドを入力しなければこのボットは何もしてくれるはずもありません。

Slackボットではなかなか難しい相互通信や自律的なレスポンス処理などの高度な操作を必要とする場合、
『Slack Bolt』によってSlackアプリを自作する必要が出てきます。

Slack BoltはSlack社が直接提供するSlackアプリを開発するためのWebアプリケーションフレームワークです。

主にJavascriptを用いてアプリ開発する
bolt-jsと、pythonベースのbolt-pythonがあります。

そこで今回はSlackボットより更に出来ることの自由度が高い
Slackサーバーをローカル環境に構築して、チャットで喋りかけるとそれに応じたレスポンスを返してくれるようなプログラムをbolt-jsで作成する手順を公式のBolt入門ガイドを中心に噛み砕いて解説していきます。


Slackアプリを設定する

何はともあれまずは何の機能も有しないサラのSlackアプリをSlack Appのダッシュボードから手動で新規作成する必要があります。

Create Appをクリックします。

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

最近はマニュフェストファイルでSlackアプリを生成できるようですが、今回は通常通り手動でポチポチと設定してモードでSlackアプリを作成します。

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

で、アプリ名を適当に決めます。

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

これは気に入らなければ後で修正できるので、ここでは適当に
First Slack Appとします。

またこのアプリを使う先のワークスペースも指定しておきます。

次にBotを使うための
『トークン』の設定を行います。

なおSlack AppのダッシュボードのUIは頻繁に変わっているので、現在のものとは少しボタンの位置や名称が変わっているかも知れませんのでご留意ください。

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

Slackアプリにおいて、トークンの設定は非常に重要になります。

通常Slackアプリは、
OAuthを使用して、SlackのAPIへのアクセスを管理しています。

Slackアプリがインストールされるとトークンを受け取り、そのトークンを使ってAPIメソッドを呼び出すという処理の流れになりますので、正しくトークンを設定出来ていないと、期待したように処理されないことになります。

復習しておくと、Slackアプリで使用できるトークンは3種類あり、
①ユーザートークン(xoxp)②ボットトークン(xoxb)③アプリレベルトークン(xapp)に分かれます、

            
            ①ユーザートークン:
    認証したユーザーに成り代わってAPIメソッドを呼び出す。
    1つのワークスペース対して複数のユーザートークンが存在してもよい

②ボットトークン:
    ボットユーザーに関連づけられ、1つのワークスペースで一度だけ発行される。
    ほとんどのSlackアプリに適用させる基本のトークン

③アプリレベルトークン:
    アカウントで利用している全ての組織を横断して利用できるアプリを代理できる。
    例として大多数のWebSocketコネクションを確立するためのアプリに利用できる
        
ひとまずはスタンダードなSlackアプリ(ボットが色々とやってくれるアプリ)を作成を目指します。

ここでは新規作成したSlackアプリにボットトークンを付与するところから始めましょう。

手っ取り早く、左のペインから
[Oauth & Permissoins] > [Scopes] > [Bot Token Scopes]に飛びます。

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

そこで、
[Add an OAuth Scope]をクリックします。

トークンの種類にはAPIの実行権限を細かく制御できるように、様々なトークンが用意してあります。

ここでは基礎的なスコープで、
chat:writeを一つだけ付与します。

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

このスコープは文字通り、このトークンを付与されたボットからチャットに文字を書き込み送信できるようにするスコープです。

トークンスコープを追加したら、この設定を反映させるためにターゲットのワークスペースに
Install Appを行います。

左のペインからだと、
[Settings] > [Install App]から[Install to Workspace]でこのSlackアプリをワークスペースへ適用させることができます。

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

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

Slackアプリのワークスペースへのインストールを許可すると以下のようにボットトークンが即時発行されます。

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

このトークンによってSlack APIが実行できるようになりますので、このトークンを何処かに控えておいて、流出させないようにしておきましょう。

なお、ボットトークンは
xoxb-...で始まるのが規約ですので、違う場合には設定を良く見直してください。


Slackアプリの中身をTypecriptで実装してみる

ここからは先程Slack Appのダッシュボードから設定したSlackアプリの処理の中身をTypescriptでゴリゴリ実装してきます。

bolt-js本体の実装はTypescriptになっていますので、Slackアプリの開発も最初からTypescriptの実装で当初から始めたほうが後々楽にプロジェクトを拡張できるでしょう。

以下の記事で、Javascript/Typescriptの勉強方法をまとめていますので、Typescriptをガッツリ学びたい方は参考にしてみてください。

TypescriptでSlackアプリプロジェクトを作成する

公式ではJavascriptでSlackアプリのプロジェクトを紹介されていますが、このブログではTypescriptで始めます。

一からTypescriptプロジェクトを説明していくのが少し手間がかかるので、今回は
Typescriptプロジェクトの簡単なサンプルを用意して、GitHub上に公開しています。

実際にSlackアプリをビルドしてみたい方は、これをサッと
git cloneするなどしてお試しください。

            
            $ git clone https://github.com/tacoskingdom/example_first_slack_app.git
        
クローンしてからyarn installすることでTypesciptのプロジェクトが利用可能です。

基本的には
main.tsにSlackボットのイベントアクションを記述していく感じでSlackアプリ開発を進めることになります。

詳しいAPIの始め方は
公式のDocumentationを参考にしてみてください。

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

const app = new App({
    signingSecret: process.env.SLACK_SIGNING_SECRET,
    token: process.env.SLACK_BOT_TOKEN,
});

//☆この位置にイベント処理をコーディング

(async () => {
    await app.start(process.env.PORT || 3000);
    console.log('⚡️ Slack Bolt now is serving!');
})();
        
なお簡単なサンプルコードだと、イベントの部分に以下のコードを使っています。

            
            app.message('hello', async ({ message, say }) => {
    await say(`<@${(message as any).user}> はん、まいどおおきに!`);
});
        
これでSlackアプリを仕込んだチャンネルにhelloとつぶやくと、「〇〇はん、まいどおおきに!」と応えてくれるようなボットに仕上がります。

Credentials(サイン認証キーとボットトークン)を変数に設定

Slackアプリに外部からアクセスするには、先ほどの上記のパートで設定した「ボットトークン」と 「サイン認証キー(Signing Secret)」の2つの秘密キーが必要になります。

これらはシェル変数もしくは環境変数としてプロセスから読み取れるように保存する必要があります。

ボットトークンのほうは先ほど説明していた通りですが、サイン認証キーは
[Basic Information] > [App Credentials]と辿り、[Signing Secret]の項目があるので、これをそのままどこかにコピーしておきます。

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

ここでは適当なLinuxOS環境で、Node.jsがインストール済みであることを前提であるとします。

WindowsでもSlackアプリをビルドしたい場合には、「windows node.js インストール」等でウェブ検索していただくと良いでしょう。

それではシェル変数もしくは環境変数に2つの認証キーを以下のように格納します。

            
            $ export SLACK_SIGNING_SECRET="サイン認証キー"
$ export SLACK_BOT_TOKEN="ボットトークン(xoxbから始まるもの)"
        
これでシェルコマンドから参照することができれば準備完了です。

            
            $ echo $SLACK_SIGNING_SECRET
<サイン認証キー...>
$ echo $SLACK_BOT_TOKEN
<ボットトークン...>
        

Slackアプリの起動テスト

では、サンプルプロジェクトのほうをビルドして、ローカルサーバーとして起動してみます。

            
            $ yarn build && yarn start
$ node dist/index.js
⚡️ Bolt app is running!
        
自宅のサーバーでSlackアプリを常時立ち上げた状態にすることで、任意のSlackアプリを仕込んだチャンネルに様々なイベントを提供していくことができます。

なお、Slackアプリを利用した様々な応用例は、これから本ブログでもちょこちょこ扱っていければ良いなぁと思っております。


Slackサーバーの動作確認を行う

Slackアプリの実体は結局のところSlackのリモートサーバーを経由したWebサーバーです。

Slackアプリというと以下にもクライアントっぽい言葉の響きがあるので、ここからは
『Slackサーバー』というように呼ぶようにします。

当然ながらSlackサーバーを動かすには、node.jsがちゃんと動作するローカルサーバー機を用意したり、オンプレが嫌ならAWSやGCPなどのSaaSのクラウドサービスの利用が必要になります。

今回の例でいうと、適当なLinuxパソコンにローカルでSlackサーバーを起動して、Slack越しにチャットの内容が受け答えできるかを評価してみます。

リモートでSlackのサブスクリプションを有効にする

上記のパートでは、Typescriptでの実装パートでSlackアプリをローカルやSaaSサイドのホストでSlackサーバーを起動させるまでを説明しました。

ただサーバーを起動させただけでは、オンラインのSlackリモートサービスへの接続がまだ確立されていません。

まずローカルのSlackサーバーとSlackサービスへの接続を確立させるために、Slack Appのダッシュボードからサブスクリプションを有効にしましょう。

自宅のサーバー機からサブスクリプションを有効にするには、オンラインで何処からでも自宅のサーバーへアクセス出来るように、
NAT越え出来るようにする必要があります。

しかし自前でNAT越え出来るようにするには、ネットワーク機器の設定を調整したり、適切にポートフォワーディング・TCPトンネリングをする必要があり非常に面倒で、かつネットワーク技術の知識が無いとセキュリティ上の問題が起こる可能性もあります。

もっとも簡単な方法の一つとして紹介されているのが、
ngrokなどの外部トンネリングサービスを使うことです。

ngrokの設定はこちらの方の解説記事を読んで頂くとして、今回はngrokをSlackアプリの起動しているLinuxサーバー機にインストールし、以下のように先程のコンソールとは別の画面で起動させておきます。

            
            $ ngrok http 3000
ngrok by @inconshreveable                                                        (Ctrl+C to quit)
                                                                                                 
Session Status                online                                                             
Session Expires               1 hour, 55 minutes                                                 
Version                       2.3.40                                                             
Region                        United States (us)                                                 
Web Interface                 http://127.0.0.1:4040                                              
Forwarding                    http://xxxx-xxx-xxx-xxx-xx.ngrok.io -> http://localhost:3000       
Forwarding                    http://xxxx-xxx-xxx-xxx-xx.ngrok.io -> http://localhost:3000      
                                                                                                 
Connections                   ttl     opn     rt1     rt5     p50     p90                        
                              1       0       0.00    0.00    5.02    5.02
        
これでngrokが監視してくれるサーバー機のグローバルIP等がフォワーディングされている状態になりますので、Slackダッシュボードから[Event Subscriptions] > [Enable Events]をOn > [Request URL]https://xxxx-xxx-xxx-xxx-xxx.ngrok.io/slack/eventsを反映させることでVerifiedに変わります。

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

これで自宅サーバー機とリモートのSlackサービスがNAT越えて、トンネリングが開始されるようになります。

ボットに権限スコープを仕込む

後はこのSlackアプリ(ボット)を、「チャンネル全体で」とか「プライベートチャンネル限定で」使うようにしたり、「ボットと自分だけ」とか「複数のグループ一括してボットから通知」したいだとか、要はやりたいことを目的に合わせたイベント権限スコープを付与する必要があります。

おおよそ代表的なスコープは以下の4つです。

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

この権限スコープは、Slackダッシュボードから
[Event Subscriptions] > [Subscribe to bot events]から設定できます。

イベントの細かい制御がこの権限スコープの付与によって実現できますが、始めの方はとにかくこの4つを付与しておくと基本的には困ることはないでしょう。

ワークスペースでボットを使ってみる!

ここまででようやくSlackアプリの実装と、NAT超えの設定が終わりました。

あとはSlackアプリが使えるように、ワークスペースのチャンネル等々にこの
First Slack Appを追加します。

まずはSlackワークスペースを開き、今回作成したSlackアプリを追加します。

おそらく先程までの行程でワークスペースにSlackアプリが自動でインストールされて
Appの項目に表示されていると思いますが、存在しなければ手動でアプリを追加してください。

Slackアプリを使いたいチャンネルを新規作成します。

左側のペインの
チャンネルの項目から、+ボタンなどでチャンネルを追加します。

今回はお試しということで、テスト用のプライベートチャンネルを
first-slack-appという名前で作ります。

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

次に
Appの項目のFirst Slack Appを選択し、ページ上部のSlackアプリのタイトルをクリックすると、[チャンネルにこのアプリを追加する]という項目が選択できます。

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

ここで先程作ったプライベートチャンネルを選択し、アプリを追加します。

ようやく全ての準備が整いました。

最終的にこのチャンネルで
helloとつぶやいたときに、ちゃんと返答してくれるようになっていれば成功です。

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


まとめ

以上、今回はSlack Bolt-jsを利用した、自宅Slackサーバーを作るための基本的な手順を解説していきました。

とにかく手動で設定すると割と面倒ですが、最初に使い方を慣れて感覚を掴んでいただけると幸いです。

まだこの記事の執筆時点ではベータ機能ですが、
マニュフェストファイルからSlackアプリを一括設定するやり方も出来るようになっています。

今後もSlackアプリの可能性が広がりそうですので、面白いSlackアプリを自作してガンガン業務に活用されてみてはいかがかと思います。

参考サイト

Bolt 入門ガイド

今更ChatOpsをしたくてSlack Boltに触れてみた【Agent Grow Advent Calendar 2019:12日目】