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


合同会社タコスキングダム|蛸壺の技術ブログ
【Slack x 業務効率化】Slack APIを利用してCurlから画像をアップロードしてみた

ローカルから画像ファイルをアップロードするためのSlackのAPIを試してみます。




このやり方では単なるSlackボットを設定しただけですので、ターミナル端末から直接Curlコマンドを入力しなければこのボットは何もしてくれるはずもありません。
Slackボットではなかなか難しい相互通信や自律的なレスポンス処理などの高度な操作を必要とする場合、
『Slack Bolt』 によって Slackアプリ を自作する必要が出てきます。

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


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

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-... で始まるのが規約ですので、違う場合には設定を良く見直してください。


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

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




ここからは先程Slack Appのダッシュボードから設定したSlackアプリの処理の中身をTypescriptでゴリゴリ実装してきます。
bolt-js本体の実装はTypescriptになっていますので、Slackアプリの開発も最初からTypescriptの実装で当初から始めたほうが後々楽にプロジェクトを拡張できるでしょう。
以下の記事で、Javascript/Typescriptの勉強方法をまとめていますので、Typescriptをガッツリ学びたい方は参考にしてみてください。

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

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


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

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 とつぶやいたときに、ちゃんと返答してくれるようになっていれば成功です。

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

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

まとめ



以上、今回はSlack Bolt-jsを利用した、自宅Slackサーバーを作るための基本的な手順を解説していきました。
とにかく手動で設定すると割と面倒ですが、最初に使い方を慣れて感覚を掴んでいただけると幸いです。
まだこの記事の執筆時点ではベータ機能ですが、
マニュフェストファイル からSlackアプリを一括設定するやり方も出来るようになっています。
今後もSlackアプリの可能性が広がりそうですので、面白いSlackアプリを自作してガンガン業務に活用されてみてはいかがかと思います。

参考サイト

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