[Slack]Bolt 入門ガイドのアプリを作成する（Windows）

Bolt 入門ガイドを見ながら、アプリ作成してみたので、覚え書き。
今回は、[Javascript版](https://slack.dev/bolt-js/ja-jp/tutorial/getting-started)で実施しました（他に、[Python版](https://slack.dev/bolt-python/ja-jp/tutorial/getting-started)と[Java版](https://slack.dev/java-slack-sdk/guides/ja/getting-started-with-bolt)があります。）

## 環境
* OS: Windows 10 Home
* Slack（デスクトップアプリ）: 4.18.0 64-bit
* node.js: 14.17.4
* npm: 6.14.14
* ngrok: 2.3.40

## 事前準備

Node.js, npmとngrokのセットアップがまだの場合は、先に実施しておきます。

### 1. Node.js, npmのインストール

Boltアプリの起動に使用します。

#### (1) ダウンロード、インストール

Node.js, npmのインストールがまだの人は、以下よりダウンロード、インストールしておきましょう。
https://nodejs.org/ja/

特に理由がなければ、画面左のLTS（推奨版）がよいかと。
インストーラをダウンロードしたら、ダブルクリックしてインストールを進めます。

デフォルトの設定でインストールして、OK!
以下の通り、npmも一緒にインストールされます（キャプチャは、ウィザード4枚目）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/619e38bd-091f-528e-35f4-02d479e9d6f9.png)


#### (2) バージョンの確認

バージョンの確認をしがてら、PATHが通っていることを確認しましょう（インストーラは、デフォルトでPATHの設定もしてくれます）。

①コマンドプロンプトを起動して、以下のコマンドを実行し、node.jsのバージョンを確認します。

```
> node --version
```

②続いて、npmのバージョンも確認しておきましょう。

```
> npm --version
```


より詳細なインストール手順を知りたい方は、
[Node.js / npmをインストールする（for Windows） | Qiita](https://qiita.com/taiponrock/items/9001ae194571feb63a5e)
をご参考ください。

### 2. ngrokの準備

ローカルで起動したBoltアプリをパブリックアクセスさせるために使用します。

#### (1) アカウントの作成

① 以下にアクセスして、画面右上の「Sign up」をクリック。
https://ngrok.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/8a5bd187-a80a-3b27-d0d7-86efa2a07e3c.png)

② ngrok個別でのサインアップはもちろん（①）、GitHubやGoogleでも可能です（②）。
お好みの方法で実施しましょう。自分はGitHubでサインアップしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/fe11cf71-7423-e9e9-de9a-a5bcccba81fd.png)

#### (2) 必要ファイルのダウンロード＆解凍

ログインできたら、ローカル環境で動かすために必要なファイルをダウンロードします。

① 左サイドバーで、「Setup & Installation」をクリックし、ページが表示されたら「Download for Windows」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/e995d000-8451-6caa-3555-721b717f89ef.png)

②zipファイルがダウンロードされるので、任意の場所で解凍しましょう。
中身は、以下の通り。ngrok.exeのみが入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/c969e2ef-ef68-25b3-9dc4-42cb275f84a2.png)

③ngrok.exeの入ったフォルダまでのパスを通しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/1b1aa339-add7-58d5-6609-eefe229c4558.png)

④コマンドプロンプトを起動して、任意の場所で以下のコマンドを実行し、バージョンの確認がてら、PATHが通っていることを確認します。

```
> ngrok version
```

#### (3) AuthTokenの設定

① ダッシュボードの左サイドバーにて、「Your Authtoken」をクリックし（①）、AuthToken欄右横の「Copy」ボタンをクリックします（②）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/ee965736-e3ee-5f13-ba76-fd4de0ae8c71.png)

②コマンドプロンプトを起動＆以下のコマンドを実行して、authtokenを設定します。

```
> ngrok.exe authtoken <コピーしたAuthToken>
```

ngrokの概要について知りたい場合は、
[ngrokが便利すぎる | Qiita](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)
詳細な使い方を知りたい場合は、
[ngrokを使ってローカル環境上で実行するWebアプリケーションにインターネットからアクセスする | Qiita](https://qiita.com/rubytomato@github/items/3ffb51d60fec24863a5b)
辺りがとても参考になります。

-----


これで、事前準備は完了です。

## Boltアプリを作成する

いよいよBoltアプリの作成に入っていきます。
ここからは、ほぼほぼ[Bolt入門ガイド | Slack | Bolt for Javascript](https://slack.dev/bolt-js/ja-jp/tutorial/getting-started)の通りの内容になります。
以下、手順に重きを置いてますので、解説は上記ページをご覧ください。

### 1. アプリを作成する

#### (1) アプリの作成

① ブラウザにて[Slack API: Applications | Slack](https://api.slack.com/apps)にアクセスし、「Create New App」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/1ef427b9-885d-3b77-310d-6486c631b1a5.png)

② アプリの作成タイプを選択します。今回は、「From scratch」にしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/f7b2a5cb-bb52-c2f2-6648-1cb3f120e4e8.png)

③ 任意のアプリ名（①）と、アプリを追加するワークスペース（②）を選択し、「Create App」をクリック（③）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/bc565564-3430-8ae5-bffd-5f5d12df4067.png)

### 2. トークンとアプリのインストール

### (1) トークンの設定

① ブラウザのアプリ設定ページにて、左サイドバーの「OAuth & Permissions」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/8b18487b-8b4e-93fa-79bf-1c81b3120951.png)

※この時点では、まだアプリのインストールはできません。
ページ上方の「OAuth Tokens for Your Workspace」の「Install to Workspace」ボタンは無効になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/3ac7a01e-81fe-b201-8723-55a0bbe5000e.png)


② 「Scopes」までスクロールし、「Bot Token Scopes」下の「Add an OAuth Scope」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/3df9cc9d-4e06-51de-87f8-f54e0272bd3c.png)

③ プルダウンが出現するので、「chat:write」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/8dbbbf33-9d7c-c3ee-ab89-c9fe9afd12c8.png)

以下、選択後の状態↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/9cc5187e-bfef-343e-ae0a-f5c365dd80c5.png)

#### (2) アプリのインストール

① ページを上方にスクロールし、「OAuth Tokens for Your Workspace」まで戻りましょう。
「Install to Workspace」が有効になっているので、クリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/c6447949-fbb6-43af-1d4a-06368412ab42.png)

② アクセス権限のリクエスト画面が開くので、「許可する」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/d7c27971-dd74-4800-7d65-189fadc51d59.png)


③ 画面が戻ると、「OAuth Tokens for Your Workspace」に「Bot User OAuth Token」が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/68746b96-2d94-a24a-6ee3-a674ea626df6.png)

④ この時点でSlackを開くと、Appの下に、作成したアプリが追加されているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/c85ce5a6-5294-95e5-5952-e6f11db712c3.png)

### 3. ローカルプロジェクトの設定

続いて、ローカル環境でBoltプロジェクトを作成します。

#### (1) ローカルプロジェクトの作成

① ローカルPCの任意の場所で、以下のコマンドを実行し、Boltプロジェクトを作成しましょう。
ディレクトリ名は、お好みの名前で大丈夫です。

```
> mkdir first-bolt-app
> cd first-bolt-app
> npm init
```

② その後、いくつか入力を促されますが、とりあえずは全てEnterでよいです。
最後に、作成されるpackage.jsonの内容が表示され、 Is this OK?と出るので、問題なければ「yes」と入力＆Enterしましょう。

```
{
  "name": "first-bolt-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes)
```

③ 対象のフォルダを確認すると、package.jsonができているはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/d9cba560-cfd6-4e9a-f48c-b17b18caa1cf.png)


#### (2) ボット (xoxb) トークンの設定

① ブラウザのアプリ設定ページにて、「2. トークンとアプリのインストール」の(6) で表示された「Bot User OAuth Token」を「Copy」します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/5e67a4d0-f59f-68f9-b276-622e0ac2b81e.png)

② ローカルPCにて、環境変数を設定します。
システムの詳細設定 - 環境変数のシステム環境変数の変数名に、「SLACK_BOT_TOKEN」を追加し（①）、①でコピーした値を「変数値」とし（②）、「OK」します（③）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/09a99bba-9ff6-f718-7e7e-8e128e286fe5.png)


#### (3) Signing Secretの設定

① ブラウザのアプリ設定ページにて、左サイドバーの「Basic Information」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/4ce98512-ef52-ea53-0968-84da6968d7d8.png)


②「App Credentials」までスクロールし、「Signing Secret」の「Show」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/36617a82-2aad-a43f-6d36-20ac6d9e91e9.png)

この後、「Signing Secret」が選択された状態で表示されるので、これをコピーします。

③ ローカルPCにて、環境変数を設定します。
システムの詳細設定 - 環境変数のシステム環境変数の変数名に、「SLACK_SIGNING_SECRET」を追加し（①）、②でコピーした値を「変数値」とし（②）、「OK」します（③）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/25a7cde6-3dac-7b34-e10a-22bd53eb6161.png)

#### (4) アプリの作成

ローカル環境にて、アプリを作成します。

① コマンドプロンプトを開き、「(1) ローカルプロジェクトの作成」で作成したpackage.jsonのあるフォルダにて、以下のコマンドを実行し、@slack/boltパッケージをインストールします。

```
> npm install @slack/bolt
```

※コマンドプロンプトを起動したまま、(2), (3)で環境変数の設定を行った場合は、再起動してください。

② 同フォルダ内に、「app.js」を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/c00c4c6f-810c-94bd-7571-af21ca991edb.png)

③ 「app.js」に以下の内容を記載し、保存します。

```javascript:app.js
const { App } = require('@slack/bolt');

// Initializes your app with your bot token and signing secret
const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET
});

(async () => {
  // Start your app
  await app.start(process.env.PORT || 3000);

  console.log('⚡️ Bolt app is running!');
})();
```

④ 実行してみます。コマンドプロンプトにて、以下のコマンドを実行。
「⚡️ Bolt app is running!」（コンソールログの内容）が表示されればOKです。

```
> node app.js
⚡️ Bolt app is running!
```

### 4. イベントの設定

#### (1) ngrokの実行

① 別途コマンドプロンプトを起動し、ngrok.exeを実行して、ローカル環境へパブリックアクセスできるようにします。
「3. ローカルプロジェクトの設定」の(4)-③の内容から、環境変数PORTが設定されていない場合は、3000となるので、以下の通り実行。

```
> ngrok.exe http 3000
```

※環境変数PORTの設定内容に応じて、適宜変更してください。

② すると、以下のような内容が出力されるので、2番目のForwarding隣のhttpsからioまでをコピーします。

```
ngrok by @inconshreveable

Session Status                online
Account                       your-name (Plan: Free)
Version                       2.3.40
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://1056e3d274db.ngrok.io -> http://localhost:3000
Forwarding                    https://1056e3d274db.ngrok.io -> http://localhost:3000

Connections                   ttl     opn     rt1     rt5     p50     p90                                                                             
                              0       0       0.00    0.00    0.00    0.00
```

※無料版の場合、「http(s)://1056e3d274db.ngrok.io」の「1056e3d274db」の部分は実行毎に変更されます。

#### (2) イベントの設定

アプリのイベントを有効にしていきます。

① ブラウザのアプリ設定ページにて、左サイドバーの「Event Subscriptions」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/529a9526-5ad1-4cdf-9343-e3427b516882.png)

② 「Enable Events」のトグルをクリックして、Onに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/04cc77fc-3f39-5df3-d863-79799152457e.png)

③ 「Request URL」に、4-(1)-②でコマンドプロンプトに表示されたURLの末尾に「/slack/events」をつけたものを入力します。
「Verified ✓」と出ればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/f2f546f8-555d-ec58-0715-c280449345f2.png)

※今回、URLが「https://1056e3d274db.ngrok.io」だったので、「https://1056e3d274db.ngrok.io/slack/events」と入力しました。

④ ページを「Subscribe to Bot Events」までスクロール→「Add Bot User Event」をクリックして、メッセージに関するイベントの設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/d14dc637-0b15-80ad-1c53-2eb251345e00.png)

⑤ 以下、4つを設定（選択）しましょう。

|項目 |内容 |
|---|---|
|message.channels  |アプリが追加されているパブリックチャンネルのメッセージをリッスンする  |
|message.groups  |アプリが追加されているプライベートチャンネルのメッセージをリッスンする  |
|message.im  |アプリとユーザーのダイレクトメッセージをリッスンする  |
|message.mpim  |アプリが追加されているグループ DM をリッスンする  |

※上記4つ全てを設定することで、全てのメッセージイベントをリッスンさせることができるそうです。


⑥ 完了したら、「Save Changes」をクリックして保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/5f266bff-173d-2e36-2868-54d459d896f8.png)

⑦ アプリの再インストールを求める旨のメッセージが出るので、「reinstall your app」のリンクをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/513f1cbe-ec1f-59fe-ad5e-e2a5a4dbd6bd.png)

⑧ アクセス可能な情報が追加されていることを確認し（①）、「許可する」をクリック（②）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/9d2e4493-5757-0221-4263-d54f80c1f2fa.png)

### 5. メッセージのリスニングと応答

アプリがメッセージをリスニングし、応答するようにします。

#### (1) app.jsの内容変更と反映

①app.jsの中身を以下の内容で上書きます。
※実際には、「// Listens to incoming messages that contain "hello"」下の3行が追記されています。

```javascript:app.js
const { App } = require('@slack/bolt');

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

// Listens to incoming messages that contain "hello"
app.message('hello', async ({ message, say }) => {
  // say() sends a message to the channel where the event was triggered
  await say(`Hey there <@${message.user}>!`);
});

(async () => {
  // Start your app
  await app.start(process.env.PORT || 3000);

  console.log('⚡️ Bolt app is running!');
})();
```

②app.jsを実行しているコマンドプロンプトにて、「Ctrl + c」にて中断した後、以下のコマンドを実行して再度起動します。

```
> node app.js
```

#### (2) ボットユーザーのチャンネルへの追加と動作確認

①アプリを追加したいチャンネルにて、右上端の「このチャンネルのすべてのメンバーを表示する」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/1576e414-ba80-b6fb-967e-8cf9ae5783f2.png)


②「インテグレーション」（①） → 「アプリを追加する」（②）をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/5b919301-2e20-aa87-3cb3-28846f941462.png)


③追加したいアプリの右端の「追加」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/99867440-53c4-29fc-5774-ff024f35a302.png)

④チャンネルに戻ると、アプリが追加されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/16ab1803-4655-bfe6-b541-39276477b037.png)


⑤ 5-(1)-①で記載したメッセージ「hello」を入力してみましょう。
すると、以下の通り、アプリから応答があるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/cc60ae56-b079-aedb-e678-3e91031789b1.png)

### 6. アクションの送信と応答

ボタン、選択メニュー、日付ピッカー、モーダルといった機能を使用するために、インタラクティブ性を有効にします。

#### (1) インタラクティブ性の設定

① ブラウザのアプリ設定ページにて、左サイドバーの「Interactivity & Shortcuts」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/02784a5f-ddc2-9ac9-e868-16f486404529.png)

②「Interactivity」のトグルをクリックして、Onに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/6bcecef1-242e-b82e-a636-e56c39b1be00.png)

③ 「Request URL」に、4-(1)-②でコマンドプロンプトに表示されたURLの末尾に「/slack/events」をつけたものを入力し（4-(2)-③と同じ内容; ①）、「Save Changes」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/9f1d7268-9ad5-d253-f1b8-9e3ed13ce638.png)

#### (2) app.jsの内容変更と反映

①app.jsの中身を以下の内容で上書きます。
※実際には、「app.message」の「await say」に内容が付加されています。

```javascript:app.js
const { App } = require('@slack/bolt');

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

// Listens to incoming messages that contain "hello"
app.message('hello', async ({ message, say }) => {
  // say() sends a message to the channel where the event was triggered
  await say({
    blocks: [
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": `Hey there <@${message.user}>!`
        },
        "accessory": {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "Click Me"
          },
          "action_id": "button_click"
        }
      }
    ],
    text: `Hey there <@${message.user}>!`
  });
});

(async () => {
  // Start your app
  await app.start(process.env.PORT || 3000);

  console.log('⚡️ Bolt app is running!');
})();
```

②app.jsを実行しているコマンドプロンプトにて、「Ctrl + c」にて中断した後、以下のコマンドを実行して再度起動します。

```
> node app.js
```

③ slackのアプリを追加したチャンネルにて、「hello」と入力すると、アプリから応答があります。
5-(2)-⑤の内容と比較し、「Click Me」と記載のあるボタンが追加されているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/32c5ba1d-6eac-726e-e253-5c4bb7998365.png)

※この時点では、ボタンをクリックしても何も起こりません。
　ここからさらに開発を進めていくイメージです。

## 終わりに

bolt、少し癖がある気がしましたが、慣れれば開発の幅が広がりそう。
ngrokの使い方でハマりましたが、便利なサービスなので、別の用途でも使っていきたいです。



## 参考

* [The Bolt family of SDKs | Slack](https://api.slack.com/tools/bolt)