Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ _site
Gemfile.lock
.env
.jekyll-metadata
.vscode/
.bundle/
vendor/
4 changes: 2 additions & 2 deletions docs/_advanced/custom_routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ const receiver = new ExpressReceiver({ signingSecret: process.env.SLACK_SIGNING_

// Create the Bolt App, using the receiver
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
receiver
token: process.env.SLACK_BOT_TOKEN,
receiver
});

// Slack interactions are methods on app
Expand Down
23 changes: 11 additions & 12 deletions docs/_advanced/ja_authorization.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
---
title: 承認
title: 認可(Authorization)
lang: ja-jp
slug: authorization
order: 2
---

<div class="section-content">
承認は、特定の着信イベントの処理中にどの Slack 認証情報 (ボットトークンなど) を使用可能にするかを決定するプロセスです。
認可(Authorization)は、Slack からのイベントを処理するにあたって、どの Slack クレデンシャル (ボットトークンなど) を使用可能にするかを決定するプロセスです。

1 つのワークスペースにインストールされたカスタムアプリでは、`App` 初期化時に `token` オプションを使用できます。ただし、複数のワークスペースにインストールされる場合や、複数のユーザートークンにアクセスする必要がある場合など、アプリが複数のトークンを処理しなければならない場合には、代わりに `authorize` オプションを使用する必要があります。
1 つだけのワークスペースにインストールされたカスタムアプリであれば `App` 初期化時に単に `token` オプションを使用するだけで OK です。一方で、複数のワークスペースにインストールされる、複数のユーザートークンを使用するといったケースのように、アプリが複数のトークンを処理しなければならない場合があります。このようなケースでは `token` の代わりに `authorize` オプションを使用する必要があります。

`authorize` オプションは、イベントソースを入力値として受け取る関数に設定でき、許可された認証情報を含むオブジェクトに Promise を返す必要があります。ソースには、 `teamId` (常に利用可能)、 `userId`、`conversationId`、`enterpriseId` のようなプロパティを使用して、イベントの送信者や送信元に関する情報が含まれています
`authorize` オプションには、イベントソースを入力値として受け取り、許可された認可されたクレデンシャルを含むオブジェクトを Promise の値として返す関数を指定します。このイベントソースの情報には、 `teamId` (常に存在します)、 `userId`、`conversationId`、`enterpriseId` のような、イベントが誰によって発生させられたか、どこで発生したかに関する情報が含まれます

許可された認証情報には、`botToken`、`userToken`、`botId` (アプリがボット自体からのメッセージを無視するために必要)、 `botUserId` などの固有のプロパティもいくつか含まれています。その他、 [`context`](#context) オブジェクトを使用すれば他のプロパティの指定もできるようになります
許可されたクレデンシャルには、`botToken`、`userToken`、`botId` (アプリがボット自体からのメッセージを無視するために必要です)、 `botUserId` が含まれます。[`context`](#context) オブジェクトに、これ以外の他のプロパティを自由に設定することもできます

`botToken` プロパティと `userToken` プロパティは、一方または両方を必ず指定する必要があります。`say()` のようなヘルパーを動作させるには、どちらか一方は指定しなければなりません。両方指定した場合は、`botToken` が優先されます。
`botToken` `userToken` は、どちらか、またはその両方を必ず設定してください。`say()` のようなユーティリティを動作させるには、どちらか一方が存在している必要があります。両方指定した場合、`say()` では `botToken` が優先されます。
</div>

```javascript
const app = new App({ authorize: authorizeFn, signingSecret: process.env.SLACK_SIGNING_SECRET });

// 注: これはデモの目的のみの例です
// 実際は重要なデータはセキュリティの高いデータベースに保存してください
// このアプリは bot トークンのみのしようと仮定、ここで使われるオブジェクトは、複数ワークスペースにアプリをインストールする際の認証情報を保管するモデルとします
// 実際は重要なデータはセキュリティの高いデータベースに保存してください。このアプリは bot トークンのみを使用すると仮定しています。ここで使われるオブジェクトは、複数ワークスペースにアプリをインストールした場合のクレデンシャルを保管するモデルです。

const installations = [
{
Expand All @@ -41,11 +40,11 @@ const installations = [
];

const authorizeFn = async ({ teamId, enterpriseId }) => {
// データベースから team 情報を取得
// データベースから team(ワークスペース)を取得
for (const team of installations) {
// installations 配列から teamId と enterpriseId が一致するかチェック
// installations 配列から teamId と enterpriseId(Enterprise Grid の OrG の ID)が一致するかチェック
if ((team.teamId === teamId) && (team.enterpriseId === enterpriseId)) {
// 一致したワークスペースの認証情報を使用
// 一致したワークスペースのクレデンシャルを使用
return {
// 代わりに userToken をセットしても OK
botToken: team.botToken,
Expand All @@ -55,6 +54,6 @@ const authorizeFn = async ({ teamId, enterpriseId }) => {
}
}

throw new Error('No matching authorizations'); // 認証エラー
throw new Error('No matching authorizations');
}
```
8 changes: 4 additions & 4 deletions docs/_advanced/ja_context.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ order: 6
---

<div class="section-content">
すべてのリスナーから、情報を追加してイベントを充実させるために使用できる `context` オブジェクトにアクセスすることができます。これはたとえば、サードパーティのシステムからユーザー情報を追加したり、チェーン内の次のミドルウェアの一時的な状態を追加したりする場合に使用します
`context` オブジェクトは、受信イベントに付加情報を提供するために使用されるもので、全てのリスナーがこれを使用できます。例えば、3rd party のシステムからユーザー情報を追加したり、ミドルウェアのチェインの中で次のミドルウェアが必要とする一時的な状態を追加したりといった用途に利用できます

`context` は単なるオブジェクトであるため、必要な情報をいくらでも追加、編集できます
`context` は、ただのオブジェクトなので、いくらでも属性を追加、編集することができます
</div>

```javascript
Expand Down Expand Up @@ -37,9 +37,9 @@ app.command('request', addTimezoneContext, async ({ command, ack, context }) =>

const requestText = `:large_blue_circle: *New request from <@${command.user_id}>*: ${command.text}`;

// 午前9時〜午後5時以外のリクエストの場合は明日
// 午前 9 時〜午後 5 時以外のリクエストの場合は明日
if (local_hour > 17 || local_hour < 9) {
// ローカル時間の明日午前9時までの差分を取得する関数があると仮定
// ローカル時間の明日午前 9 時までの差分を取得する関数があると仮定
const local_tomorrow = getLocalTomorrow(context.tz_offset);

try {
Expand Down
4 changes: 2 additions & 2 deletions docs/_advanced/ja_conversation_store.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Conversation stores
title: 会話ストア
lang: ja-jp
slug: conversation-store
order: 3
Expand All @@ -12,7 +12,7 @@ Bolt は、会話 (conversation) に関連する state を設定および取得

`conversationContext()` は、他のミドルウェアによる会話の更新を可能にする組み込みの[グローバルミドルウェア](#global-middleware)です。イベントを受け取ると、ミドルウェア関数は `context.updateConversation()` を使用して状態を設定でき、`context.conversation` を使用してその state を取得できます。

組み込みの conversation store は、シンプルに会話の state をメモリーに格納します。状況によってはこれで十分ですが、アプリのインスタンスが複数実行されている場合、状態はプロセス間で共有されないため、データベースを使用して会話の state を取得する conversation store を実装することをお勧めします
組み込みの conversation store は、シンプルに会話の state をメモリーに格納します。状況によってはこれで十分ですが、アプリのインスタンスが複数実行されている場合、状態はプロセス間で共有されないため、データベースを使用して会話の state を取得する conversation store を実装することをおすすめします
</div>

```javascript
Expand Down
42 changes: 42 additions & 0 deletions docs/_advanced/ja_custom_routes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: カスタム HTTP ルートの追加
lang: ja-jp
slug: custom-routes
order: 9
---

<div class="section-content">

Bolt の組み込みの `ExpressReceiver` を使っているなら、カスタムの HTTP ルートを追加するのはとても簡単です。`v2.1.0` から `ExpressReceiver` には `router` というプロパティが追加されています。これは、さらにルートを追加できるように `App` 内部で保持している Exprss の [Router](http://expressjs.com/en/4x/api.html#router) を public にしたものです。

</div>

```javascript
const { App, ExpressReceiver } = require('@slack/bolt');

// Bolt の Receiver を明に生成
const receiver = new ExpressReceiver({ signingSecret: process.env.SLACK_SIGNING_SECRET });

// App をこのレシーバーを指定して生成
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
receiver
});

// Slack とのやりとりは App のメソッドで定義
app.event('message', async ({ event, client }) => {
// Do some slack-specific stuff here
await client.chat.postMessage(...);
});

// それ以外の Web リクエストの処理は receiver.router のメソッドで定義
receiver.router.post('/secret-page', (req, res) => {
// ここでは Express のリクエストやレスポンスをそのまま扱う
res.send('yay!');
});

(async () => {
await app.start(8080);
console.log('app is running');
}());
```
6 changes: 3 additions & 3 deletions docs/_advanced/ja_logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ order: 7
---

<div class="section-content">
デフォルトでは、Bolt はアプリからコンソールに情報をログします。ログ取集が行われる回数をカスタマイズするには、コンストラクタで `logLevel` を渡します。使用可能なログレベルは、レベルの高い方から順に、`DEBUG`、 `INFO`、`WARN`、および `ERROR` です。
Bolt はデフォルトの設定では、標準出力のコンソールにログ上を出力します。どれくらいのどれくらいのログが出力されるかは、コンストラクターの引数の `logLevel` を指定して、カスタマイズできます。使用可能なログレベルは、頻度の高い方から順に、`DEBUG`、`INFO`、`WARN`、`ERROR` です。
</div>

```javascript
Expand All @@ -27,7 +27,7 @@ const app = new App({
</summary>

<div class="secondary-content" markdown="0">
ログの送信先をコンソール以外に設定するなど、logger をよりスマートに管理するには、カスタム logger を実装します。カスタム logger には、以下の特定のメソッド (`Logger` インターフェイスと呼ばれる) を実装する必要があります。
ログの送信先をコンソール以外に設定したり、よりロガーを細かくコントロールしたい場合は、カスタムロガーを実装します。カスタムロガーは、以下のメソッド (`Logger` インターフェイスに定義されているもの) を実装する必要があります。

| メソッド | パラメーター | 戻り値の型 |
|--------------|-------------------|-------------|
Expand All @@ -50,7 +50,7 @@ const logWritable = createWriteStream('/var/my_log_file');
const app = new App({
token,
signingSecret,
// リテラルオブジェクトとしてクラスを指定する感じで logger を生成。
// リテラルオブジェクトとして logger を設定(必要なメソッドを持つクラスを指定するイメージで)
logger: {
debug(...msgs): { logWritable.write('debug: ' + JSON.stringify(msgs)); },
info(...msgs): { logWritable.write('info: ' + JSON.stringify(msgs)); },
Expand Down
2 changes: 1 addition & 1 deletion docs/_advanced/ja_middleware_global.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ order: 4
---

<div class="section-content">
グローバルミドルウェアは、すべての着信イベントに対して、リスナーミドルウェアより前に実行されます。`app.use(fn({payload,...,next}))` を使用すると、グローバルミドルウェアをいくつでもアプリに追加できます。
グローバルミドルウェアは、すべての受信イベントに対して、リスナーミドルウェアより前に実行されます。`app.use(fn({payload,...,next}))` を使用すると、グローバルミドルウェアをいくつでもアプリに追加できます。

グローバルミドルウェアとリスナーミドルウェアは、いずれも、`await next()` を呼び出して実行チェーンの制御を次のミドルウェアに渡すか、`throw` を呼び出して以前に実行したミドルウェアチェーンにエラーを渡す必要があります。

Expand Down
8 changes: 4 additions & 4 deletions docs/_advanced/ja_middleware_listener.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ order: 5
---

<div class="section-content">
リスナーミドルウェアは、全てではありませんが多くのリスナー関数を対象としたロジックに使用され、組み込みメソッド内のリスナー関数より先に引数として追加されます。ここでは任意の数のリスナーミドルウェアを追加することができます。
リスナーミドルウェアは、多くのリスナー関数を対象(つまり、複数のリスナー関数を対象としますが、全てのリスナーに実行するわけではないものです)としたロジックの適用に使用でき、リスナーを追加する組み込みメソッドの引数リスト内で、リスナー関数より先に引数として追加されます。ここでは任意の数のリスナーミドルウェアを追加することができます。

組み込みリスナーミドルウェアはいくつか用意されており、例えば、メッセージのサブタイプをフィルタリングする `subtype()` や、ボットに直接 @ メンションしないメッセージを除外する `directMention()` のように使用することができます。

ただしもちろん、よりカスタマイズされた機能を追加するために、独自のミドルウェアを作成することもできます。独自のミドルウェアを記述する際には、関数で `await next()` を呼び出して制御を次のミドルウェアに渡すか、`throw` を呼び出して以前に実行されたミドルウェアチェーンにエラーを渡す必要があります
もちろん、よりカスタマイズされた機能を追加するために独自のミドルウェアを実装することもできます。カスタムミドルウェアとして動作する関数の実装は `await next()` を呼び出して制御を次のミドルウェアに渡すか、`throw` を呼び出して以前に実行されたミドルウェアチェーンにエラーを投げる必要があります

たとえば、リスナーが人間からのメッセージのみを扱うのであれば、ボットメッセージを除外するリスナーミドルウェアを作成できます
例として、リスナーが人(ボットではないユーザー)からのメッセージのみを扱うケースを考えてみましょう。このためには、全てのボットメッセージを除外するリスナーミドルウェアを実装します

*注: Bolt 2.x からミドルウェアが `async` 関数をサポートしました!この変更については [2.x マイグレーションガイド](https://slack.dev/bolt/ja-jp/tutorial/migration-v2)を参照してください。*
</div>
Expand All @@ -26,7 +26,7 @@ async function noBotMessages({ message, next }) {
}

// ボットではなく人間からのメッセージのみを受信するリスナー
app.message(noBotMessages, ({ message }) => console.log(
app.message(noBotMessages, async ({ message }) => console.log(
`(MSG) User: ${message.user}
Message: ${message.text}`
));
Expand Down
9 changes: 5 additions & 4 deletions docs/_advanced/ja_receiver.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@ order: 8
---

<div class="section-content">
レシーバーは、Slack から送信されたイベントを処理およびパースして発行するので、Bolt アプリがそのイベントにコンテキストを追加し、アプリのリスナーに渡すことができます。レシーバーは、レシーバーのインターフェイスに準拠している必要があります
レシーバーは、Slack からのイベントを受け付けてパースした後、それを Bolt アプリに伝える責務を担っています。Bolt アプリは、`context` 情報やリスナーへのイベントの引き渡しを行います。レシーバーの実装は `Receiver` インターフェイスに準拠している必要があります

| メソッド | パラメーター | 戻り値の型 |
|--------------|----------------------------------|-------------|
| `init()` | `app: App` | `unknown` |
| `start()` | None | `Promise` |
| `stop()` | None | `Promise` |

Bolt アプリでは `init()` が 2 回呼び出されます。このメソッドはレシーバーに `App` の参照を付与するため、これにより以下の呼び出しが可能になります。
`init()` メソッドは Bolt for JavaScript アプリが生成されたときに呼び出されます。このメソッドはレシーバーに `App` インスタンスへの参照を与えます。レシーバーはこれを保持して、イベント受信時に呼び出します。

* `await app.processEvent(event)` は Slack から送信されてくるイベントを受け取るたびに呼び出されます。ハンドリングされなかったエラーが発生した場合はそれを throw します。

Bolt アプリを初期化するときにカスタムレシーバーをコンストラクタに渡すことで、そのカスタムレシーバーを使用できます。ここで紹介するのは、基本的なカスタムレシーバーです
カスタムのレシーバーを使用する場合は、それを `App` のコンストラクターに渡します。ここで紹介しているコード例は、基本的なカスタムレシーバーの実装例です

レシーバーについて詳しくは、[組み込み `ExpressReceiver` のソースコード](https://github.com/slackapi/bolt/blob/master/src/ExpressReceiver.ts)をお読みください
レシーバーについてより深く知りたい場合は、[組み込み `ExpressReceiver` のソースコード](https://github.com/slackapi/bolt-js/blob/master/src/ExpressReceiver.ts)を参照してください
</div>

```javascript
Expand Down
2 changes: 1 addition & 1 deletion docs/_advanced/middleware_listener.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ async function noBotMessages({ message, next }) {
}

// The listener only receives messages from humans
app.message(noBotMessages, ({ message }) => console.log(
app.message(noBotMessages, async ({ message }) => console.log(
`(MSG) User: ${message.user}
Message: ${message.text}`
));
Expand Down
Loading