Bolt 入門ガイド
このガイドでは、Bolt を使用して Slack アプリを起動し実行する方法について説明します。その過程で、新しい Slack アプリを作成し、ローカル環境を設定し、Slack ワークスペースからのメッセージをリッスンして応答するアプリを開発します。
このガイドが終わったら、あなたはこの⚡️Getting Started appを実行したり、修正したり、自分で作ったりすることができます。
アプリを作成する
最初にやるべきこと: Bolt で開発を始める前に、 Slack アプリを作成します。
いつもの仕事のさまたげにならないように、別に開発用のワークスペースを使用することをおすすめします — 新しいワークスペースを無料で作成できます。
アプリ名を入力し (後で変更可能)、インストール先のワークスペースを選択したら、Create App
ボタンをクリックすると、アプリの Basic Information ページが表示されます。
このページには、後で必要になる重要な認証情報 (App Credentials ヘッダーの下の Signing Secret
など) に加えて、アプリケーションの概要が表示されます。
ひと通り確認し、アプリのアイコンと説明を追加してから、アプリの設定 🔩 を始めましょう。
トークンとアプリのインストール
Slack アプリは、OAuth を使用して、Slack の API へのアクセスを管理します。アプリがインストールされるとトークンが発行されます。そのトークンを使って、アプリは API メソッドを呼び出すことができます。
Slack アプリで使用できるトークンには、ユーザートークン(xoxp
)とボットトークン(xoxb
)、アプリレベルトークン(xapp
)の 3 種類があります。
- ユーザートークン を使用すると、アプリをインストールまたは認証したユーザーに成り代わって API メソッドを呼び出すことができます。1 つのワークスペースに複数のユーザートークンが存在する可能性があります。
- ボットトークン はボットユーザーに関連づけられ、1 つのワークスペースでは最初に誰かがそのアプリをインストールした際に一度だけ発行されます。どのユーザーがインストールを実行しても、アプリが使用するボットトークンは同じになります。 ほとんど のアプリで使用されるのは、ボットトークンです。
- アプリレベルトークン は、全ての組織(とその配下のワークスペースでの個々のユーザーによるインストール)を横断して、あなたのアプリを代理するものです。アプリレベルトークンは、アプリの WebSocket コネクションを確立するためによく使われます。
このガイドではボットトークンとアプリレベルトークンを使用します。
-
左側のサイドバーの OAuth & Permissions にアクセスして、Bot Token Scopes までスクロールします。そして、Add an OAuth Scope をクリックします。
-
ここでは、
chat:write
というスコープだけを追加してみましょう。これは、アプリにボットユーザがメンバーとして参加しているチャンネルへのメッセージの投稿を許可するスコープです。 -
ページ上部までスクロールして戻り、Install App to Workspace をクリックします。すると、開発用のワークスペースに このアプリをインストールするための Slack の OAuth 確認画面へと誘導されます。
-
インストールを承認すると、OAuth & Permissions ページが表示され、Bot User OAuth Access Token を確認することができるはずです。
トークンは、パスワードのように大切に扱い、安全に保管してください。アプリではそのトークンを使用して、Slack ワークスペースからの情報を投稿および取得します。
ローカルプロジェクトの設定
初期設定が完了したので、次は新しい Bolt プロジェクトを 設定します。ここで、アプリのロジックを処理するコードを記述します。
プロジェクトをまだ作成していない場合は、新しいプロジェクトを作成しましょう。次のように、空のディレクトリを作成して、新しいプロジェクトを初期化します。
mkdir first-bolt-app
cd first-bolt-app
npm init
新しいプロジェクトを説明するための一連の質問が表示されます (特に問題がなければ、各プロンプトで Enter を押すと、デフォルトを受け入れることができます)。完了すると、ディレクトリ内に新しい package.json
ファイルが作成されます。
Bolt パッケージを新しいプロジェクトにインストールする前に、アプリの設定時に生成されたボットトークンと signing secret (サイン認証) を保存しましょう。これらは環境変数として保存する必要があります。バージョン管理では保存しないでください。
- Basic Information ページから Signing Secret をコピーして、新しい環境変数に保存します。次の例は Linux と macOS で動作します。ただし、Windows でも同様のコマンドが利用可能です。
export SLACK_SIGNING_SECRET=<your-signing-secret>
- OAuth & Permissions ページからボット (xoxb) トークンをコピーし、それを別の環境変数に格納します。
export SLACK_BOT_TOKEN=xoxb-<your-bot-token>
🔒 全てのトークンは安全に保管してください。少なくともパブリックなバージョン管理にチェックインするようなことは避けるべきでしょう。また、上にあった例のように環境変数を介してアクセスするようにしてください。詳細な情報は アプリのセキュリティのベストプラクティスのドキュメントを参照してください。
それでは、アプリを作成しましょう。次のコマンドを使用して、@slack/bolt
パッケージをインストールし、 package.json
中で依存ファイルとして保存します。
npm install @slack/bolt
このディレクトリ内に app.js
という名前の新しいファイルを作成し、以下のコードを追加します。
const { App } = require('@slack/bolt');
// ボットトークンと Signing Secret を使ってアプリを初期化します
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET
});
(async () => {
// アプリを起動します
await app.start(process.env.PORT || 3000);
console.log('⚡️ Bolt app is running!');
})();
まず実行してみましょう。 app.js
ファイルを保存してから、以下のコマンドラインで動かします。
node app.js
アプリから、起動し実行中であることが通知されます🎉
イベントの設定
アプリはワークスペース内の他のメンバーと同じように振る舞い、メッセージを投稿したり、絵文字リアクションを追加したり、イベントをリッスンして返答したりできます。
Slack ワークスペースで発生するイベント(メッセージが投稿されたときや、メッセージに対するリアクションがつけられたときなど)をリッスンするには、Events API を使って特定の種類のイベントをサブスクライブします。
- Socket Mode
- HTTP
このチュートリアルでは、ソケットモードを使用します。 Socket モードは、チームのために何かを作り始めたばかりの人にお勧めのオプションです。
ソケットモードを使うことで、アプリが公開された HTTP エンドポイントを公開せずに Events API やインタラクティブコンポーネントを利用できるようになります。このことは、開発時やファイヤーウォールの裏からのリクエストを受ける際に便利です。HTTP での方式はホスティング環境(AWS or Herokuなど)にデプロイするアプリや Slack App Directory で配布されるアプリに適しています。 HTTP での情報についてはこちらのドキュメントを参照してください。
それではソケットモードを有効にします。
-
アプリの設定ページに向かいます(アプリ管理ページからアプリをクリックします)。左側のメニューにある「Socket Mode」に移動し、有効に切り替えます。
-
Basic Information にアクセスし、「App-Level Tokens」セクションの下にスクロールし、Generate Token and Scopes をクリックしてアプリトークンを生成します。このトークンに
connections:write
スコープを追加し、生成されたxapp
トークンを保存します。
アプリのイベントを有効にしましょう。
-
アプリのイベントを有効にするには、まずアプリ設定ページに戻ります (アプリ管理ページでアプリをクリックします)。左側のサイドバーにある Event Subscription をクリックします。Enable Events のスイッチをオンにします。
-
Request URLを追加します。Slackはイベントに対応するHTTP POSTリクエストをこのRequest URLエンドポイントに送信します。Boltは
/slack/events
のパスを使用して、すべての受信リクエスト(ショートカット、イベント、インタラクティビティのペイロードなど)をリッスンします。アプリの設定でRequest URLを設定する際には、https://<your-domain>/slack/events
のように/slack/events
を追加します。💡
ローカル開発では、ngrokのようなプロキシサービスを使って公開 URL を作成し、リクエストを開発環境にトンネリングすることができます。このトンネリングの方法については、ngrok のガイドを参照してください。
最後に、聞きたいイベントをSlackに伝えましょう。Event Subscriptionsの下にある、Enable Eventsというラベルの付いたスイッチを切り替えます。
イベントが発生すると、Slack は、そのイベントをトリガーしたユーザーやイベントが発生したチャンネルなど、イベントに関する情報をアプリに送信します。アプリが詳細を処理し、それに応じて応答することができます。
Request URL ボックスの Enable Events スイッチの下のフィールドにこの URL を貼り付けます。Bolt アプリが引き続き実行されている場合は、URL が検証されチェックマークが表示されます。
そして最後に、私たちがどのイベントをリッスンしたいかを Slack に伝えましょう。
イベントが発生すると、そのイベントをトリガーしたユーザーやイベントが発生したチャンネルなど、イベントに関する情報が Slack からアプリに送信されます。アプリではこれらの情報を処理して、適切な応答を返します。
Subscribe to Bot Events まで下にスクロールします。4つのメッセージに関するイベントがあります。
message.channels
アプリが参加しているパブリックチャンネルのメッセージをリッスンmessage.groups
アプリが参 加しているプライベートチャンネルのメッセージをリッスンmessage.im
あなたのアプリとユーザーのダイレクトメッセージをリッスンmessage.mpim
あなたのアプリが追加されているグループ DM をリッスン
もしボットに参加しているすべての場所で全てのメッセージイベントをリッスンさせたいなら、これら4つ全てのイベントを選んでください。選択したら、緑の Save Changes ボタンをクリックします。
- Socket Mode
- HTTP
プロジェクトに戻り、先ほど保存した xapp
トークンを環境変数に保存してください。
export SLACK_APP_TOKEN=xapp-<your-app-token>
Bolt の初期化部分のコードを変更し、アプリを再起動してください。
// ソケットモードでトークンおよび signing secret で初期化します。
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
socketMode: true, // 追加
appToken: process.env.SLACK_APP_TOKEN // 追加
});
ここでの設定は特にありません。このまま続けてください!
メッセージのリスニングと応答
これで、アプリでいくつかのロジックを設定する準備が整いました。まずは message()
メソッドを使用して、メッセージのリスナーをアタッチしましょう。
次の例では、あなたのアプリが追加されているチャンネルや DM で hello
という単語を含むすべてのメッセージをリッスンし、 Hey there @user!
と応答します。
- Socket Mode
- HTTP
const { App } = require('@slack/bolt');
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
socketMode: true,
appToken: process.env.SLACK_APP_TOKEN,
// ソケットモードではポートをリッスンしませんが、アプリを OAuth フローに対応させる場合、
// 何らかのポートをリッスンする必要があります
port: process.env.PORT || 3000
});
// "hello" を含むメッセージをリッスンします
app.message('hello', async ({ message, say }) => {
// イベントがトリガーされたチャンネルに say() でメッセージを送信します
await say(`Hey there <@${message.user}>!`);
});
(async () => {
// アプリを起動します
await app.start();
console.log('⚡️ Bolt app is running!');
})();
const { App } = require('@slack/bolt');
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET
});
// "hello" を含むメッセージをリッスンします
app.message('hello', async ({ message, say }) => {
// イベントがトリガーされたチャンネルに say() でメッセージを送信します
await say(`Hey there <@${message.user}>!`);
});
(async () => {
// アプリを起動します
await app.start(process.env.PORT || 3000);
console.log('⚡️ Bolt app is running!');
})();
アプリを再起動したら、ボットユーザーをチャンネル、 DM に追加し、 hello
を含むメッセージを送信してみてください。アプリが応答したら成功です。
これは基本的な例ですが、ここから自分の好きなようにアプリをカスタマイズしていくことができます。さらにインタラクティブな動作を試すために、プレーンテキストではなくボタンを送信してみましょう。
アクションの送信と応答
ボタン、選択メニュー、日付 ピッカー、モーダルなどの機能を使用するには、インタラクティブ機能を有効にする必要があります。イベントと同様に、Slack の URL を指定してアクション ( 「ボタン・クリック」など) を送信する必要があります。
- Socket Mode
- HTTP
ソケットモードを有効にしているとき、デフォルトで基本的なインタラクティブ機能が有効になっていため、ここでは特に何もする必要はいありません。
アプリ設定ページに戻り、左側の Interactivity & Shortcuts をクリックします。Request URL ボックスがもう 1 つあることがわかります。
デフォルトでは、Bolt はイベントに使用しているのと同じエンドポイントをインタラクティブコンポー ネントに使用するように設定されているため、上記と同じリクエスト URL (この例では https://8e8ec2d7.ngrok.io/slack/events
) を使用します。右下隅にある Save Changes ボタンを押してください。これでアプリのインタラクティブなコンポーネントを利用する設定が有効になりました!
インタラクティブ機能が有効化されていると、ショートカット、モーダル、インタラクティブコンポーネント (例:ボタン、選択メニュー、日付ピッカーなど) とのインタラクションがイベントとしてあなたのアプリに送信されます。
それでは、アプリのコードに戻り、インタラクティブな処理を追加しましょう。この実装は以下の二つのステップで構成されます。
- 最初に、アプリからボタンを含むメッセージを送信します。
- 次に、ユーザーがボタンをクリックしたときの動作をアプリでリッスンし、応答します。
以下は、前のセクションで記述したアプリコードを、文字列だけでなく、ボタン付きのメッセージを送信するように変更したものです。
- Socket Mode
- HTTP
const { App } = require('@slack/bolt');
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
socketMode: true,
appToken: process.env.SLACK_APP_TOKEN,
// ソケットモードではポートをリッスンしませんが、アプリを OAuth フローに対応させる場合、
// 何らかのポートをリッスンする必要があります
port: process.env.PORT || 3000
});
// "hello" を含むメッセージをリッスンします
app.message('hello', async ({ message, say }) => {
// イベントがトリガーされたチャンネルに say() でメッセージを送信します
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 () => {
// アプリを起動します
await app.start();
console.log('⚡️ Bolt app is running!');
})();
const { App } = require('@slack/bolt');
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET
});
// "hello" を含むメッセージをリッスンします
app.message('hello', async ({ message, say }) => {
// イベントがトリガーされたチャンネルに say() でメッセージを送信します
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 () => {
// アプリを起動します
await app.start(process.env.PORT || 3000);
console.log('⚡️ Bolt app is running!');
})();
say()
に格納されている値が、 blocks
の配列を含むオブジェクトになりました。このブロックは Slack メッセージを構成するコンポーネントであり、テキストや画像、日付ピッカーなど、さまざまなタイプがあります。この例では、アプリは、ボタンを accessory
として含むセクションブロックを使用して応答します。blocks
を使っている場合、 text
は通知やアクセシビリティのためのフォールバックとして使用されます。
このボタン accessory
オブジェクトには、action_id
が割り当てられています。これはボタンの一意の識別子として機能するため、アプリはどのアクションに応答するかを指定できます。
Block Kit ビルダーを使うとインタラクティブメッセージを簡単にプロトタイプすることができます。ビルダーを使用すると、ユーザー (またはそのチームメンバー) はメッセージをモックアップして、対応する JSON を生成し、それをアプリに直接貼り付けることができます。
これで、アプリを再起動し、アプリが登録されているチャンネルで hello
と入力すると、ボタン付きのメッセージが表示されます。ただしこのボタンをクリックしても、まだ何も起こりません。
ボタンがクリックされるとフォローアップメッセージを送信するハンドラーを追加してみましょう。
- Socket Mode
- HTTP
const { App } = require('@slack/bolt');
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
socketMode: true,
appToken: process.env.SLACK_APP_TOKEN,
// ソケットモードではポートをリッスンし ませんが、アプリを OAuth フローに対応させる場合、
// 何らかのポートをリッスンする必要があります
port: process.env.PORT || 3000
});
// "hello" を含むメッセージをリッスンします
app.message('hello', async ({ message, say }) => {
// イベントがトリガーされたチャンネルに say() でメッセージを送信します
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}>!`
});
});
app.action('button_click', async ({ body, ack, say }) => {
// アクションのリクエストを確認
await ack();
await say(`<@${body.user.id}> clicked the button`);
});
(async () => {
// アプリを起動します
await app.start();
console.log('⚡️ Bolt app is running!');
})();
const { App } = require('@slack/bolt');
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET
});
// "hello" を含むメッセージをリッスンします
app.message('hello', async ({ message, say }) => {
// イベントがトリガーされたチャンネルに say() でメッセージを送信します
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}>!`
});
});
app.action('button_click', async ({ body, ack, say }) => {
// アクションのリクエストを確認
await ack();
await say(`<@${body.user.id}> clicked the button`);
});
(async () => {
// アプリを起動します
await app.start(process.env.PORT || 3000);
console.log('⚡️ Bolt app is running!');
})();
このように、app.action()
を使うことで button_click
という action_id
のボタンアクションのリスナーを追加できるのです。アプリを再起動してボタンをクリックしてみましょう。すると、you clicked the button という新しいメッセージがアプリに表示されるはずです。
次のステップ
これで最初の Bolt アプリが構築できました! 🎉
基本的なアプリの作成ができましたので、次回は是非もっといろいろな、 Bolt の機能を使ってアプリを作ってみましょう。下記のリンクを辿っていろいろアイデアを模索してみてください!
-
基本的な概念 をお読みください。Bolt アプリからアクセスできるさまざまなメソッドと機能について学ぶことができます。
-
ボットが
events()
メソッドでリッスンできるさまざまなイベントを確認しましょう。イベントはすべてAPI サイトにリストされています。 -
Bolt を使用すると、アプリにアタッチされているクライアントで Web API メソッドを呼 び出すことができます。API サイトに 200 を超えるメソッドを用意してあります。