/slack/events`. 💡
-
-:::info
-
-For local development, you can use a proxy service like [ngrok](https://ngrok.com/) to create a public URL and tunnel requests to your development environment. Refer to [ngrok's getting started guide](https://ngrok.com/docs#getting-started-expose) on how to create this tunnel.
-
-:::
-
-
-Finally, it's time to tell Slack what events we'd like to listen for. Under **Event Subscriptions**, toggle the switch labeled **Enable Events**.
-
-When an event occurs, Slack will send your app information about the event, like the user that triggered it and the channel it occurred in. Your app will process the details and can respond accordingly.
-
-Scroll down to **Subscribe to Bot Events**. There are four events related to messages:
-- [`message.channels`](https://api.slack.com/events/message.channels) listens for messages in public channels that your app is added to
-- [`message.groups`](https://api.slack.com/events/message.groups) listens for messages in 🔒 private channels that your app is added to
-- [`message.im`](https://api.slack.com/events/message.im) listens for messages in your app's DMs with users
-- [`message.mpim`](https://api.slack.com/events/message.mpim) listens for messages in multi-person DMs that your app is added to
-
-If you want your bot to listen to messages from everywhere it is added to, choose all four message events. After you’ve selected the events you want your bot to listen to, click the green **Save Changes** button.
-
----
-### Listening and responding to a message {#listening-and-responding-to-a-message}
-Your app is now ready for some logic. Let's start by using the `message()` method to attach a listener for messages.
-
-The following example listens and responds to all messages in channels/DMs where your app has been added that contain the word "hello":
-
-```javascript
-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!');
-})();
-```
-
-If you restart your app, so long as your bot user has been added to the channel/DM, when you send any message that contains "hello", it will respond.
-
-This is a basic example, but it gives you a place to start customizing your app based on your own goals. Let's try something a little more interactive by sending a button rather than plain text.
-
----
-
-### Sending and responding to actions {#sending-and-responding-to-actions}
-
-To use features like buttons, select menus, datepickers, modals, and shortcuts, you’ll need to enable interactivity. Similar to events, you'll need to specify a Request URL for Slack to send the action (such as *user clicked a button*). Head over to **Interactivity & Shortcuts** in your app configuration.
-
-:::info
-
-By default, Bolt uses the same endpoint for interactive components that it uses for events, so use the same request URL as above (in the example, it was `https://8e8ec2d7.ngrok.io/slack/events`). Press the **Save Changes** button in the lower right hand corner, and that's it. Your app is set up to handle interactivity!
-
-:::
-
-When interactivity is enabled, interactions with shortcuts, modals, or interactive components (such as buttons, select menus, and datepickers) will be sent to your app as events.
-
-Now, let’s go back to your app’s code and add logic to handle those events:
-- First, we'll send a message that contains an interactive component (in this case a button).
-- Next, we'll listen for the action of a user clicking the button before responding
-
-Below, the code from the last section is modified to send a message containing a button rather than just a string:
-
-```javascript
-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!');
-})();
-```
-
-The value inside of `say()` is now an object that contains an array of `blocks`. Blocks are the building components of a Slack message and can range from text to images to datepickers. In this case, your app will respond with a section block that includes a button as an accessory. Since we're using `blocks`, the `text` is a fallback for notifications and accessibility.
-
-You'll notice in the button `accessory` object, there is an `action_id`. This will act as a unique identifier for the button so your app can specify what action it wants to respond to.
-
-:::tip
-
-The [Block Kit Builder](https://app.slack.com/block-kit-builder) is a simple way to prototype your interactive messages. The builder lets you (or anyone on your team) mockup messages and generates the corresponding JSON that you can paste directly in your app.
-
-:::
-
-Now, if you restart your app and say "hello" in a channel your app is in, you'll see a message with a button. But if you click the button, nothing happens (*yet!*).
-
-Let's add a handler to send a followup message when someone clicks the button:
-
-```javascript
-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}>!`
- });
-});
-
-app.action('button_click', async ({ body, ack, say }) => {
- // Acknowledge the action
- await ack();
- await say(`<@${body.user.id}> clicked the button`);
-});
-
-(async () => {
- // Start your app
- await app.start(process.env.PORT || 3000);
-
- console.log('⚡️ Bolt app is running!');
-})();
-```
-
-You can see that we used `app.action()` to listen for the `action_id` that we named `button_click`. If you restart your app and click the button, you'll see a new message from your app that says you clicked the button.
-
----
-
-### Next steps {#next-steps}
-You just built your first [Bolt for JavaScript app](https://github.com/slackapi/bolt-js-getting-started-app)! 🎉
-
-Now that you have a basic app up and running, you can start exploring how to make your Bolt app stand out. Here are some ideas about what to explore next:
-
-* Read through the Basic concepts to learn about the different methods and features your Bolt app has access to.
-
-* Explore the different events your bot can listen to with the [`events()` method](/concepts/event-listening). All of the events are listed [on the API site](https://api.slack.com/events).
-
-* Bolt allows you to [call Web API methods](/concepts/web-api) with the client attached to your app. There are [over 200 methods](https://api.slack.com/methods) on our API site.
-
-* Learn more about the different token types [on our API site](https://api.slack.com/docs/token-types). Your app may need different tokens depending on the actions you want it to perform. If you are using [Socket Mode](/getting-started) instead of HTTP, an additional (`xapp`) token with `connections:write` scopes is required.
diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js
index 81c195376..c5b680f27 100644
--- a/docs/docusaurus.config.js
+++ b/docs/docusaurus.config.js
@@ -1,17 +1,12 @@
-// @ts-check
-// `@type` JSDoc annotations allow editor autocompletion and type checking
-// (when paired with `@ts-check`).
-// There are various equivalent ways to declare your Docusaurus config.
-// See: https://docusaurus.io/docs/api/docusaurus-config
-
import { themes as prismThemes } from 'prism-react-renderer';
+const footer = require('./footerConfig');
+const navbar = require('./navbarConfig');
/** @type {import('@docusaurus/types').Config} */
const config = {
- title: 'Slack Developer Tools',
+ title: 'Bolt for JavaScript',
tagline: 'Official frameworks, libraries, and SDKs for Slack developers',
favicon: 'img/favicon.ico',
-
url: 'https://tools.slack.dev',
baseUrl: '/bolt-js/',
organizationName: 'slackapi',
@@ -42,9 +37,6 @@ const config = {
theme: {
customCss: './src/css/custom.css',
},
- gtag: {
- trackingID: 'G-9H1YZW28BG',
- },
}),
],
],
@@ -57,7 +49,21 @@ const config = {
redirects: [
{
to: '/getting-started',
- from: ['/tutorial/getting-started'],
+ from: ['/tutorial/getting-started', '/tutorial/getting-started-http'],
+ },
+ {
+ to: '/legacy/steps-from-apps',
+ from: [
+ '/concepts/steps',
+ '/concepts/creating-steps',
+ '/concepts/adding-editing-steps',
+ '/concepts/saving-steps',
+ '/concepts/executing-steps',
+ ],
+ },
+ {
+ to: '/concepts/actions',
+ from: ['/concepts/action-listening', '/concepts/action-responding'],
},
{
to: '/',
@@ -79,102 +85,8 @@ const config = {
autoCollapseCategories: true,
},
},
- navbar: {
- title: 'Slack Developer Tools',
- logo: {
- alt: 'Slack logo',
- src: 'img/slack-logo.svg',
- href: 'https://tools.slack.dev',
- target: '_self',
- },
- items: [
- {
- type: 'dropdown',
- label: 'Bolt',
- position: 'left',
- items: [
- {
- label: 'Java',
- to: 'https://tools.slack.dev/java-slack-sdk/guides/bolt-basics',
- target: '_self',
- },
- {
- label: 'JavaScript',
- to: 'https://tools.slack.dev/bolt-js',
- target: '_self',
- },
- {
- label: 'Python',
- to: 'https://tools.slack.dev/bolt-python',
- target: '_self',
- },
- ],
- },
- {
- type: 'dropdown',
- label: 'SDKs',
- position: 'left',
- items: [
- {
- label: 'Java Slack SDK',
- to: 'https://tools.slack.dev/java-slack-sdk/',
- target: '_self',
- },
- {
- label: 'Node Slack SDK',
- to: 'https://tools.slack.dev/node-slack-sdk/',
- target: '_self',
- },
- {
- label: 'Python Slack SDK',
- to: 'https://tools.slack.dev/python-slack-sdk/',
- target: '_self',
- },
- {
- label: 'Deno Slack SDK',
- to: 'https://api.slack.com/automation/quickstart',
- target: '_self',
- },
- ],
- },
- {
- type: 'dropdown',
- label: 'Community',
- position: 'left',
- items: [
- {
- label: 'Community tools',
- to: 'https://tools.slack.dev/community-tools',
- target: '_self',
- },
- {
- label: 'Slack Community',
- to: 'https://slackcommunity.com/',
- target: '_self',
- },
- ],
- },
- {
- to: 'https://api.slack.com/docs',
- label: 'API Docs',
- target: '_self',
- },
- {
- type: 'localeDropdown',
- position: 'right',
- },
- {
- 'aria-label': 'GitHub Repository',
- className: 'navbar-github-link',
- href: 'https://github.com/slackapi/bolt-js',
- position: 'right',
- target: '_self',
- },
- ],
- },
- footer: {
- copyright: ' Made with ♡ by Slack and pals like you
',
- },
+ navbar,
+ footer,
prism: {
// switch to alucard when available in prism?
theme: prismThemes.github,
diff --git a/docs/footerConfig.js b/docs/footerConfig.js
new file mode 100644
index 000000000..e3e10c571
--- /dev/null
+++ b/docs/footerConfig.js
@@ -0,0 +1,19 @@
+const footer = {
+ links: [
+ {
+ items: [
+ {
+ html: `
+
+ ©2024 Slack Technologies, LLC, a Salesforce company. All rights reserved. Various trademarks held by their respective owners.
+ `,
+ },
+ ],
+ },
+ ],
+};
+
+module.exports = footer;
diff --git a/docs/i18n/ja-jp/README.md b/docs/i18n/ja-jp/README.md
index 5acce6f8d..c5f04de1a 100644
--- a/docs/i18n/ja-jp/README.md
+++ b/docs/i18n/ja-jp/README.md
@@ -2,7 +2,7 @@
This README describes how the Japanese documentation is created. Please read the [/docs README](./docs/README) for information on _all_ the documentation.
-[Docusaurus](https://docusaurus.io) supports using different languages. Each language is a different version of the same site. The English site is the default. The English page will be viewable if the page is not translated into Japanese.
+[Docusaurus](https://docusaurus.io) supports using different languages. Each language is a different version of the same site. The English site is the default. The English page will be viewable if the page is not translated into Japanese. You do not need to place the English page on the Japanese side of the site though! It is automatically pulled during the build process.
There will be English pages on the Japanese site of the pages are not translated yet. Japanese readers will not miss any content, but they may be confused seeing English and Japanese mixed together. Please give us your thoughts on this setup.
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current.json b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current.json
index c5794d3d0..aa7410656 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current.json
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current.json
@@ -3,26 +3,10 @@
"message": "Next",
"description": "The label for version current"
},
- "sidebar.sidebarJSBolt.category.Basic concepts": {
- "message": "基本的な概念",
- "description": "The label for category Basic concepts in sidebar sidebarJSBolt"
- },
- "sidebar.sidebarJSBolt.category.Advanced concepts": {
- "message": "応用コンセプト",
- "description": "The label for category Advanced concepts in sidebar sidebarJSBolt"
- },
"sidebar.sidebarJSBolt.category.Deployments": {
"message": "Deployments",
"description": "The label for category Deployments in sidebar sidebarJSBolt"
},
- "sidebar.sidebarJSBolt.category.Custom functions (Beta)": {
- "message": "Custom functions (Beta)",
- "description": "The label for category Custom functions (Beta) in sidebar sidebarJSBolt"
- },
- "sidebar.sidebarJSBolt.category.Workflow steps (Deprecated)": {
- "message": "ワークフローステップ 非推奨",
- "description": "The label for category Workflow steps (Deprecated) in sidebar sidebarJSBolt"
- },
"sidebar.sidebarJSBolt.category.Tutorials": {
"message": "チュートリアル",
"description": "The label for category Tutorials in sidebar sidebarJSBolt"
@@ -34,5 +18,45 @@
"sidebar.sidebarJSBolt.link.Contributors Guide": {
"message": "貢献",
"description": "The label for link Contributors Guide in sidebar sidebarJSBolt, linking to https://github.com/SlackAPI/bolt-js/blob/main/.github/contributing.md"
+ },
+ "sidebar.sidebarJSBolt.category.Slack API calls": {
+ "message": "Slack API コール",
+ "description": "The label for category Slack API calls in sidebar sidebarJSBolt"
+ },
+ "sidebar.sidebarJSBolt.category.Events": {
+ "message": "イベント API",
+ "description": "The label for category Events in sidebar sidebarJSBolt"
+ },
+ "sidebar.sidebarJSBolt.category.App UI & Interactivity": {
+ "message": "インタラクティビティ & ショートカット",
+ "description": "The label for category Interactivity & Shortcuts in sidebar sidebarJSBolt"
+ },
+ "sidebar.sidebarJSBolt.category.App Configuration": {
+ "message": "App の設定",
+ "description": "The label for category App Configuration in sidebar sidebarJSBolt"
+ },
+ "sidebar.sidebarJSBolt.category.Middleware & Context": {
+ "message": "ミドルウェア & コンテキスト",
+ "description": "The label for category Middleware & Context in sidebar sidebarJSBolt"
+ },
+ "sidebar.sidebarJSBolt.category.Authorization & Security": {
+ "message": "認可 & セキュリティ",
+ "description": "The label for category Authorization & Security in sidebar sidebarJSBolt"
+ },
+ "sidebar.sidebarJSBolt.category.Migration Guides": {
+ "message": "マイグレーションガイド",
+ "description": "The label for category Migration Guides in sidebar sidebarJSBolt"
+ },
+ "sidebar.sidebarJSBolt.category.Legacy": {
+ "message": "レガシー(非推奨)",
+ "description": "The label for category Legacy in sidebar sidebarJSBolt"
+ },
+ "sidebar.sidebarJSBolt.link.Release notes": {
+ "message": "リリースノート",
+ "description": "The label for link Release notes in sidebar sidebarJSBolt, linking to https://github.com/slackapi/bolt-js/releases"
+ },
+ "sidebar.sidebarJSBolt.doc.Bolt for JavaScript": {
+ "message": "Bolt for JavaScript",
+ "description": "The label for the doc item Bolt for JavaScript in sidebar sidebarJSBolt, linking to the doc index"
}
}
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/action-respond.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/action-respond.md
deleted file mode 100644
index 75d1e3a6d..000000000
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/action-respond.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: アクションへの応答
-lang: ja-jp
-slug: /concepts/action-respond
----
-
-アクションへの応答には、主に 2 つのやり方があります。1 つ目の (最も一般的な) やり方は `say` 関数の利用です。 `say` 関数は、Slack 内のリクエストが発生した会話(チャンネルや DM)へメッセージを返します。
-
-アクションに応答する 2 つ目の方法は `respond()` です。これはアクションに紐付けられている `response_url` を用いたメッセージの送信をシンプルに行うためのユーティリティです。
-
-```javascript
-// action_id が "approve_button" のインタラクティブコンポーネントがトリガーされる毎にミドルウェアが呼び出される
-app.action('approve_button', async ({ ack, say }) => {
- // アクションリクエストの確認
- await ack();
- await say('Request approved 👍');
-});
-```
-
-
-
-`respond()` の使用
-
-
-`respond()` は `response_url` を呼び出すためのユーティリティであるため、それを直接使うときと同様に動作します。新しいメッセージのペイロードと、オプショナルな引数である `response_type` (値は `in_channel` または `ephemeral` )、 `replace_original` 、 `delete_original` を含む JSON オブジェクトを渡すことができます。
-
-```javascript
-// "user_select" の action_id がトリガーされたアクションをリッスン
-app.action('user_select', async ({ action, ack, respond }) => {
- await ack();
- if (action.type === 'users_select') {
- await respond(`You selected <@${action.selected_user}>`);
- }
-});
-```
-
-
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/custom-steps.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/custom-steps.md
deleted file mode 100644
index aa4f344cc..000000000
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/custom-steps.md
+++ /dev/null
@@ -1,167 +0,0 @@
----
-title: Listening and responding to custom steps
-lang: ja-jp
-slug: /concepts/custom-steps
----
-
-Your app can use the `function()` method to listen to incoming [custom step requests](https://api.slack.com/automation/functions/custom-bolt). Custom steps are used in Workflow Builder to build workflows. The method requires a step `callback_id` of type string. This `callback_id` must also be defined in your [Function](https://api.slack.com/concepts/manifests#functions) definition. Custom steps must be finalized using the `complete()` or `fail()` listener arguments to notify Slack that your app has processed the request.
-
-* `complete()` requires one argument: an `outputs` object. It ends your custom step **successfully** and provides an object containing the outputs of your custom step as per its definition.
-* `fail()` requires **one** argument: `error` of type string. It ends your custom step **unsuccessfully** and provides a message containing information regarding why your custom step failed.
-
-You can reference your custom step's inputs using the `inputs` listener argument.
-
-```js
-// This sample custom step formats an input and outputs it
-app.function('sample_custom_step', async ({ inputs, complete, fail, logger }) => {
- try {
- const { message } = inputs;
-
- await complete({
- outputs: {
- message: `:wave: You submitted the following message: \n\n>${message}`
- }
- });
- } catch (error) {
- logger.error(error);
- await fail({ error: `Failed to handle a function request: ${error}` });
- }
-});
-```
-
-
-
-Example app manifest definition
-
-
-```json
-...
-"functions": {
- "sample_custom_step": {
- "title": "Sample custom step",
- "description": "Run a sample custom step",
- "input_parameters": {
- "message": {
- "type": "string",
- "title": "Message",
- "description": "A message to be formatted by a custom step",
- "is_required": true,
- }
- },
- "output_parameters": {
- "message": {
- "type": "string",
- "title": "Messge",
- "description": "A formatted message",
- "is_required": true,
- }
- }
- }
-}
-```
-
-
-
----
-
-### Listening to custom step interactivity events
-
-Your app's custom steps may create interactivity points for users, for example: Post a message with a button
-
-If such interaction points originate from a custom step execution, the events sent to your app representing the end-user interaction with these points are considered to be _function-scoped interactivity events_. These interactivity events can be handled by your app using the same concepts we covered earlier, such as [Listening to actions](/concepts/action-listening).
-
-_function-scoped interactivity events_ will contain data related to the custom step (`function_executed` event) they were spawned from, such as custom step `inputs` and access to `complete()` and `fail()` listener arguments.
-
-Your app can skip calling `complete()` or `fail()` in the `function()` handler method if the custom step creates an interaction point that requires user interaction before the step can end. However, in the relevant interactivity handler method, your app must invoke `complete()` or `fail()` to notify Slack that the custom step has been processed.
-
-You’ll notice in all interactivity handler examples, `ack()` is used. It is required to call the `ack()` function within an interactivity listener to acknowledge that the request was received from Slack. This is discussed in the [acknowledging requests section](/concepts/acknowledge).
-
-```js
-/** This sample custom step posts a message with a button */
-app.function('custom_step_button', async ({ client, inputs, fail, logger }) => {
- try {
- const { user_id } = inputs;
-
- await client.chat.postMessage({
- channel: user_id,
- text: 'Click the button to signal the function has completed',
- blocks: [
- {
- type: 'section',
- text: {
- type: 'mrkdwn',
- text: 'Click the button to signal the function has completed',
- },
- accessory: {
- type: 'button',
- text: {
- type: 'plain_text',
- text: 'Complete function',
- },
- action_id: 'sample_button',
- },
- },
- ],
- });
- } catch (error) {
- logger.error(error);
- await fail({ error: `Failed to handle a function request: ${error}` });
- }
-});
-
-/** Your listener will be called every time a block element with the action_id "sample_button" is triggered */
-app.action('sample_button', async ({ ack, body, client, complete, fail, logger }) => {
- try {
- await ack();
-
- const { channel, message, user } = body;
- // Functions should be marked as successfully completed using `complete` or
- // as having failed using `fail`, else they'll remain in an 'In progress' state.
- await complete({ outputs: { user_id: user.id } });
-
- await client.chat.update({
- channel: channel.id,
- ts: message.ts,
- text: 'Function completed successfully!',
- });
- } catch (error) {
- logger.error(error);
- await fail({ error: `Failed to handle a function request: ${error}` });
- }
-});
-```
-
-
-
-Example app manifest definition
-
-
-```json
-...
-"functions": {
- "custom_step_button": {
- "title": "Custom step with a button",
- "description": "Custom step that waits for a button click",
- "input_parameters": {
- "user_id": {
- "type": "slack#/types/user_id",
- "title": "User",
- "description": "The recipient of a message with a button",
- "is_required": true,
- }
- },
- "output_parameters": {
- "user_id": {
- "type": "slack#/types/user_id",
- "title": "User",
- "description": "The user that completed the function",
- "is_required": true
- }
- }
- }
-}
-```
-
-
-
-Learn more about responding to interactivity, see the [Slack API documentation](https://api.slack.com/automation/functions/custom-bolt#interactivity).
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/acknowledge.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/acknowledge.md
similarity index 100%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/acknowledge.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/acknowledge.md
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/action-listening.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/actions.md
similarity index 53%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/action-listening.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/actions.md
index bfe5edbe1..756f88b42 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/action-listening.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/actions.md
@@ -1,16 +1,22 @@
---
-title: アクションのリスニング
+title: アクション
lang: ja-jp
-slug: /concepts/action-listening
+slug: /concepts/actions
---
Bolt アプリは `action` メソッドを用いて、ボタンのクリック、メニューの選択、メッセージショートカットなどのユーザーのアクションをリッスンすることができます。
+## アクションのリスニング
+
アクションは文字列型の `action_id` または RegExp オブジェクトでフィルタリングできます。 `action_id` は、Slack プラットフォーム上のインタラクティブコンポーネントの一意の識別子として機能します。
すべての `action()` の例で `ack()` が使用されていることに注目してください。Slack からリクエストを受信したことを確認するために、アクションリスナー内で `ack()` 関数を呼び出す必要があります。これについては、「[リクエストの確認](/concepts/acknowledge)」 セクションで説明しています。
-*注: Bolt 2.x からメッセージショートカット(以前はメッセージアクションと呼ばれていました)は `action()` ではなく `shortcut()` メソッドを使用するようになりました。この変更については [2.x マイグレーションガイド](/tutorial/migration-v2)を参照してください。*
+:::info
+
+Bolt 2.x からメッセージショートカット(以前はメッセージアクションと呼ばれていました)は `action()` ではなく `shortcut()` メソッドを使用するようになりました。この変更については [2.x マイグレーションガイド](/tutorial/migration-v2)を参照してください。
+
+:::
`block_actions` ペイロードの詳細については、[こちら](https://api.slack.com/reference/interaction-payloads) をご覧ください。リスナー内からビューの完全なペイロードにアクセスするには、コールバック関数内で `body` 引数を参照します。
@@ -22,10 +28,7 @@ app.action('approve_button', async ({ ack }) => {
});
```
-
-
-制約付きオブジェクトを使用したアクションのリスニング
-
+### 制約付きオブジェクトを使用したアクションのリスニング
制約付きのオブジェクトを使って、 `callback_id` 、 `block_id` 、および `action_id` (またはそれらの組み合わせ) をリッスンすることができます。オブジェクト内の制約には、文字列型または RegExp オブジェクトを使用できます。
@@ -52,4 +55,31 @@ app.action({ action_id: 'select_user', block_id: 'assign_ticket' },
});
```
-
\ No newline at end of file
+## アクションへの応答
+
+アクションへの応答には、主に 2 つのやり方があります。1 つ目の (最も一般的な) やり方は `say` 関数の利用です。 `say` 関数は、Slack 内のリクエストが発生した会話(チャンネルや DM)へメッセージを返します。
+
+アクションに応答する 2 つ目の方法は `respond()` です。これはアクションに紐付けられている `response_url` を用いたメッセージの送信をシンプルに行うためのユーティリティです。
+
+```javascript
+// action_id が "approve_button" のインタラクティブコンポーネントがトリガーされる毎にミドルウェアが呼び出される
+app.action('approve_button', async ({ ack, say }) => {
+ // アクションリクエストの確認
+ await ack();
+ await say('Request approved 👍');
+});
+```
+
+### `respond()` の使用
+
+`respond()` は `response_url` を呼び出すためのユーティリティであるため、それを直接使うときと同様に動作します。新しいメッセージのペイロードと、オプショナルな引数である `response_type` (値は `in_channel` または `ephemeral` )、 `replace_original` 、 `delete_original` を含む JSON オブジェクトを渡すことができます。
+
+```javascript
+// "user_select" の action_id がトリガーされたアクションをリッスン
+app.action('user_select', async ({ action, ack, respond }) => {
+ await ack();
+ if (action.type === 'users_select') {
+ await respond(`You selected <@${action.selected_user}>`);
+ }
+});
+```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/authenticating-oauth.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/authenticating-oauth.md
similarity index 99%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/authenticating-oauth.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/authenticating-oauth.md
index f17fa03e7..25f06b8cb 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/authenticating-oauth.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/authenticating-oauth.md
@@ -170,10 +170,7 @@ const app = new App({
});
```
-
-
-OAuth デフォルト設定をカスタマイズ
-
+## OAuth デフォルト設定をカスタマイズ
`installerOptions` を使って OAuth モジュールのデフォルト設定を上書きすることができます。このカスタマイズされた設定は `App` の初期化時に渡します。以下の情報を変更可能です:
@@ -237,5 +234,4 @@ const app = new App({
},
}
});
-```
-
+```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/authorization.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/authorization.md
similarity index 100%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/authorization.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/authorization.md
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/commands.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/commands.md
similarity index 94%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/commands.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/commands.md
index 5616bf65e..c71b1d153 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/commands.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/commands.md
@@ -10,7 +10,7 @@ slug: /concepts/commands
アプリがスラッシュコマンドのリクエストを受け取ったことを `ack()` の実行によって Slack に通知する必要があります。
-スラッシュコマンドへの応答には 2 つのやり方があります。1 つ目の方法は、文字列または JSON ペイロードを受け取る `say()` で、2 つ目は `response_url` を簡単に利用するためのユーティリティである `respond()` です。これらについては、「[アクションへの応答](/concepts/action-respond)」セクションで詳しく説明しています。
+スラッシュコマンドへの応答には 2 つのやり方があります。1 つ目の方法は、文字列または JSON ペイロードを受け取る `say()` で、2 つ目は `response_url` を簡単に利用するためのユーティリティである `respond()` です。これらについては、「[アクションへの応答](/concepts/actions)」セクションで詳しく説明しています。
Slack アプリの管理画面でスラッシュコマンドを設定するとき、そのスラッシュコマンドの Request URL に(`https://{ドメイン}` に続いて) `/slack/events` を指定するようにしてください。
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/context.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/context.md
similarity index 100%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/context.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/context.md
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/creating-modals.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/creating-modals.md
similarity index 100%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/creating-modals.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/creating-modals.md
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/custom-routes.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/custom-routes.md
similarity index 97%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/custom-routes.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/custom-routes.md
index fbb559711..d42fb0420 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/custom-routes.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/custom-routes.md
@@ -48,10 +48,7 @@ const app = new App({
})();
```
-
-
-カスタム ExpressReceiver ルート
-
+## カスタム ExpressReceiver ルート
Bolt の組み込みの `ExpressReceiver` を使っているなら、カスタムの HTTP ルートを追加するのはとても簡単です。`v2.1.0` から `ExpressReceiver` には `router` というプロパティが追加されています。これは、さらにルートを追加できるように `App` 内部で保持している Express の [Router](http://expressjs.com/en/4x/api.html#router) を public にしたものです。
@@ -88,5 +85,4 @@ receiver.router.post('/secret-page', (req, res) => {
await app.start();
console.log('⚡️ Bolt app started');
})();
-```
-
\ No newline at end of file
+```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/deferring-initialization.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/deferring-initialization.md
similarity index 100%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/deferring-initialization.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/deferring-initialization.md
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/error-handling.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/error-handling.md
similarity index 97%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/error-handling.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/error-handling.md
index 090c6795d..5d5159c4e 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/error-handling.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/error-handling.md
@@ -54,10 +54,7 @@ app.error(async (error) => {
});
```
-
-
-エラーハンドラーでのさらなるデータの参照
-
+## エラーハンドラーでのさらなるデータの参照
グローバルエラーハンドラーの中で、リクエストからのデータをログ出力したい場合もあるでしょう。あるいは単に Bolt に設定した `logger` を利用したい場合もあるでしょう。
@@ -83,6 +80,4 @@ app.error(async ({ error, logger, context, body }) => {
// デバッグのために teamId を使ってなんらかの処理
}
});
-```
-
-
+```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/event-listening.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/event-listening.md
similarity index 51%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/event-listening.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/event-listening.md
index 7dbadd081..8f3c3a0bd 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/event-listening.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/event-listening.md
@@ -25,29 +25,4 @@ app.event('team_join', async ({ event, client, logger }) => {
logger.error(error);
}
});
-```
-
-
-
-メッセージのサブタイプのフィルタリング
-
-
-`message()` リスナーは `event('message')` と等価の機能を提供します。
-
-イベントのサブタイプをフィルタリングしたい場合、組み込みの `subtype()` ミドルウェアを使用できます。 `message_changed` や `message_replied` のような一般的なメッセージサブタイプの情報は、[メッセージイベントのドキュメント](https://api.slack.com/events/message#message_subtypes)を参照してください。
-
-```javascript
-// パッケージから subtype をインポート
-const { App, subtype } = require('@slack/bolt');
-
-// user からのメッセージの編集と一致
-app.message(subtype('message_changed'), ({ event, logger }) => {
- // この if 文は TypeScript でコードを書く際に必要
- if (event.subtype === 'message_changed'
- && !event.message.subtype
- && !event.previous_message.subtype) {
- logger.info(`The user ${event.message.user} changed their message from ${event.previous_message.text} to ${event.message.text}`);
- }
-});
-```
-
\ No newline at end of file
+```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/global-middleware.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/global-middleware.md
similarity index 91%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/global-middleware.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/global-middleware.md
index 1e3189e7b..465964423 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/global-middleware.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/global-middleware.md
@@ -10,7 +10,11 @@ slug: /concepts/global-middleware
たとえば、アプリが、対応する内部認証サービス (SSO プロバイダ、LDAP など) で識別されたユーザーにのみ応答する必要があるとします。この場合、グローバルミドルウェアを使用して認証サービス内のユーザーレコードを検索し、ユーザーが見つからない場合はエラーとなるように定義するのがよいでしょう。
-*注: Bolt 2.x からグローバルミドルウェアが `async` 関数をサポートしました!この変更については [2.x マイグレーションガイド](/tutorial/migration-v2)を参照してください。*
+:::info
+
+Bolt 2.x からグローバルミドルウェアが `async` 関数をサポートしました!この変更については [2.x マイグレーションガイド](/tutorial/migration-v2)を参照してください。
+
+:::
```javascript
// Acme ID情報管理プロバイダ上のユーザからの着信リクエストと紐つけた認証ミドルウェア
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/listener-middleware.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/listener-middleware.md
similarity index 91%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/listener-middleware.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/listener-middleware.md
index 96d556b6b..74b90a494 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/listener-middleware.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/listener-middleware.md
@@ -12,7 +12,11 @@ slug: /concepts/listener-middleware
例として、リスナーが人(ボットではないユーザー)からのメッセージのみを扱うケースを考えてみましょう。このためには、全てのボットメッセージを除外するリスナーミドルウェアを実装します。
-*注: Bolt 2.x からミドルウェアが `async` 関数をサポートしました!この変更については [2.x マイグレーションガイド](/tutorial/migration-v2)を参照してください。*
+:::info
+
+Bolt 2.x からミドルウェアが `async` 関数をサポートしました!この変更については [2.x マイグレーションガイド](/tutorial/migration-v2)を参照してください。
+
+:::
```javascript
// 'bot_message' サブタイプを持つメッセージをフィルタリングするリスナーミドルウェア
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/logging.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/logging.md
similarity index 96%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/logging.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/logging.md
index c1307d5da..137c53cdd 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/logging.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/logging.md
@@ -18,10 +18,7 @@ const app = new App({
});
```
-
-
-コンソール以外へのログ出力の送信
-
+## コンソール以外へのログ出力の送信
ログの送信先をコンソール以外に設定したり、よりロガーを細かくコントロールしたい場合は、カスタムロガーを実装します。カスタムロガーは、以下のメソッド (`Logger` インターフェイスに定義されているもの) を実装する必要があります。
@@ -56,6 +53,4 @@ const app = new App({
setName: (name) => { },
},
});
-```
-
-
\ No newline at end of file
+```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/message-listening.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/message-listening.md
similarity index 54%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/message-listening.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/message-listening.md
index 254d3aea1..907b5b52c 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/message-listening.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/message-listening.md
@@ -4,7 +4,7 @@ lang: ja-jp
slug: /concepts/message-listening
---
-[アプリが受信可能な](https://api.slack.com/messaging/retrieving#permissions)メッセージをリッスンするには、`message` 型でないイベントを除外する `message()` メソッドを使用します。
+[アプリが受信可能な](https://api.slack.com/messaging/retrieving#permissions)メッセージをリッスンするには、`message` 型でないイベントを除外する `message()` メソッドを使用します。`message()` リスナーは `event('message')` と等価の機能を提供します。
`message()` は、`string` 型か `RegExp` 型の、指定パターンに一致しないメッセージを除外する `pattern` パラメーター(指定は必須ではありません)を受け付けます。
@@ -21,10 +21,7 @@ app.message(':wave:', async ({ message, say }) => {
});
```
-
-
-正規表現(RegExp) パターンの使用
-
+## 正規表現(RegExp) パターンの使用
文字列の代わりに 正規表現(RegExp) パターンを使用すると、より細やかなマッチングが可能です。
@@ -39,4 +36,20 @@ app.message(/^(hi|hello|hey).*/, async ({ context, say }) => {
});
```
-
\ No newline at end of file
+## メッセージのサブタイプのフィルタリング
+
+イベントのサブタイプをフィルタリングしたい場合、組み込みの `subtype()` ミドルウェアを使用できます。 `message_changed` や `message_replied` のような一般的なメッセージサブタイプの情報は、[メッセージイベントのドキュメント](https://api.slack.com/events/message#message_subtypes)を参照してください。
+
+```javascript
+// パッケージから subtype をインポート
+const { App, subtype } = require('@slack/bolt');
+
+// user からのメッセージの編集と一致
+app.message(subtype('message_changed'), ({ event, logger }) => {
+ // この if 文は TypeScript でコードを書く際に必要
+ if (event.subtype === 'message_changed'
+ && !event.message.subtype
+ && !event.previous_message.subtype) {
+ logger.info(`The user ${event.message.user} changed their message from ${event.previous_message.text} to ${event.message.text}`);
+ }
+});
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/message-sending.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/message-sending.md
similarity index 96%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/message-sending.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/message-sending.md
index 5ccef4f28..a4b17b889 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/message-sending.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/message-sending.md
@@ -15,10 +15,7 @@ app.message('knock knock', async ({ message, say }) => {
});
```
-
-
-ブロックを用いたメッセージの送信
-
+## ブロックを用いたメッセージの送信
`say()` は、より複雑なメッセージペイロードを受け付けるので、メッセージに機能やリッチな構造を与えることが容易です。
@@ -48,5 +45,4 @@ app.event('reaction_added', async ({ event, say }) => {
});
}
});
-```
-
\ No newline at end of file
+```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/publishing-views.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/publishing-views.md
similarity index 100%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/publishing-views.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/publishing-views.md
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/receiver.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/receiver.md
similarity index 100%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/receiver.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/receiver.md
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/options.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/select-menu-options.md
similarity index 92%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/options.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/select-menu-options.md
index 430e9b4f5..2a81d89ec 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/options.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/select-menu-options.md
@@ -4,7 +4,7 @@ lang: ja-jp
slug: /concepts/options
---
-`options()` メソッドは、Slack からのオプション(セレクトメニュー内の動的な選択肢)をリクエストするペイロードをリッスンします。 [`action()` と同様](/concepts/action-listening)に、文字列型の `action_id` または制約付きオブジェクトが必要です。
+`options()` メソッドは、Slack からのオプション(セレクトメニュー内の動的な選択肢)をリクエストするペイロードをリッスンします。 [`action()` と同様](/concepts/actions)に、文字列型の `action_id` または制約付きオブジェクトが必要です。
`external_select` メニューには `action_id` を使用することをおすすめしますが、ダイアログはまだ Block Kit をサポートしていないため、制約オブジェクトを用いて `callback_id` でフィルタリングする必要があります。
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/shortcuts.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/shortcuts.md
similarity index 66%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/shortcuts.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/shortcuts.md
index c440feb28..61a1bb6b7 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/shortcuts.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/shortcuts.md
@@ -68,64 +68,57 @@ app.shortcut('open_modal', async ({ shortcut, ack, context, logger }) => {
});
```
-
-
- 制約付きオブジェクトを使用したショートカットのリスニング
-
+## 制約付きオブジェクトを使用したショートカットのリスニング
- 制約付きオブジェクトを使って `callback_id` や `type` によるリスニングができます。オブジェクト内の制約は文字列型または RegExp オブジェクトを使用できます。
+制約付きオブジェクトを使って `callback_id` や `type` によるリスニングができます。オブジェクト内の制約は文字列型または RegExp オブジェクトを使用できます。
-
-
- ```javascript
- // callback_id が 'open_modal' と一致し type が 'message_action' と一致する場合のみミドルウェアが呼び出される
- app.shortcut({ callback_id: 'open_modal', type: 'message_action' }, async ({ shortcut, ack, context, client, logger }) => {
- try {
- // ショートカットリクエストの確認
- await ack();
+```javascript
+// callback_id が 'open_modal' と一致し type が 'message_action' と一致する場合のみミドルウェアが呼び出される
+app.shortcut({ callback_id: 'open_modal', type: 'message_action' }, async ({ shortcut, ack, context, client, logger }) => {
+ try {
+ // ショートカットリクエストの確認
+ await ack();
- // 組み込みの WebClient を使って views.open API メソッドを呼び出す
- const result = await app.client.views.open({
- // `context` オブジェクトに保持されたトークンを使用
- token: context.botToken,
- trigger_id: shortcut.trigger_id,
- view: {
- type: "modal",
- title: {
- type: "plain_text",
- text: "My App"
- },
- close: {
- type: "plain_text",
- text: "Close"
+ // 組み込みの WebClient を使って views.open API メソッドを呼び出す
+ const result = await app.client.views.open({
+ // `context` オブジェクトに保持されたトークンを使用
+ token: context.botToken,
+ trigger_id: shortcut.trigger_id,
+ view: {
+ type: "modal",
+ title: {
+ type: "plain_text",
+ text: "My App"
+ },
+ close: {
+ type: "plain_text",
+ text: "Close"
+ },
+ blocks: [
+ {
+ type: "section",
+ text: {
+ type: "mrkdwn",
+ text: "About the simplest modal you could conceive of :smile:\n\nMaybe or ."
+ }
},
- blocks: [
- {
- type: "section",
- text: {
+ {
+ type: "context",
+ elements: [
+ {
type: "mrkdwn",
- text: "About the simplest modal you could conceive of :smile:\n\nMaybe or ."
+ text: "Psssst this modal was designed using "
}
- },
- {
- type: "context",
- elements: [
- {
- type: "mrkdwn",
- text: "Psssst this modal was designed using "
- }
- ]
- }
- ]
- }
- });
-
- logger.info(result);
- }
- catch (error) {
- logger.error(error);
- }
- });
- ```
+ ]
+ }
+ ]
+ }
+ });
-
\ No newline at end of file
+ logger.info(result);
+ }
+ catch (error) {
+ logger.error(error);
+ }
+});
+```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/socket-mode.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/socket-mode.md
similarity index 95%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/socket-mode.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/socket-mode.md
index 275cdea5c..b765a8e5b 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/socket-mode.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/socket-mode.md
@@ -23,10 +23,7 @@ const app = new App({
})();
```
-
-
-ソケットモードレシーバーのカスタム初期化
-
+## ソケットモードレシーバーのカスタム初期化
以下のように `@slack/bolt` から `SocketModeReceiver` を import して、カスタムされたインスタンスとして定義することができます。
@@ -53,6 +50,4 @@ const app = new App({
await app.start();
console.log('⚡️ Bolt app started');
})();
-```
-
-
+```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/token-rotation.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/token-rotation.md
similarity index 100%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/token-rotation.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/token-rotation.md
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/updating-pushing-views.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/updating-pushing-views.md
similarity index 90%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/updating-pushing-views.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/updating-pushing-views.md
index 17c5a8c63..0f7d99804 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/updating-pushing-views.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/updating-pushing-views.md
@@ -6,13 +6,13 @@ slug: /concepts/updating-pushing-views
モーダルでは、複数のモーダルをスタックのように積み重ねて表示できます。[`views.open`](https://api.slack.com/methods/views.open) という API を呼び出すと、まず親の(最初の)モーダルが表示されます。この最初の呼び出しの後、[`views.update`](https://api.slack.com/methods/views.update) を実行することでそのビューを書き換えることもできますし、最初に述べたように [`views.push`](https://api.slack.com/methods/views.push) で新しいモーダルを積み重ねて表示することもできます。
-**`views.update`**
+## `views.update`
モーダルの更新には、組み込みの API クライアントを使って `views.update` を呼び出します。この API 呼び出しには、そのモーダルを開いたときに生成された `view_id` と、更新後の内容を表現する `blocks` の配列を含む新しい `view` を渡します。ユーザーが既存のモーダル内の要素とインタラクションを行なった(例:ボタンを押す、メニューから選択する)ことをトリガーにビューを更新する場合、そのリクエストの `body` に `view_id` が含まれます。
-**`views.push`**
+## `views.push`
-モーダルのスタックに新しいモーダルを積み重ねるためには、組み込みの API クライアントを用いて `views.push` を呼び出します。この API 呼び出しには、有効な `trigger_id` と、新しく生成する [ビュー部分のペイロード](https://api.slack.com/reference/block-kit/views)を渡します。`views.push` の引数は モーダルを開始するときと同様です。最初のモーダルを開いた後、その上にさらに二つまで追加のモーダルをスタックに積み重ねることができます。
+モーダルのスタックに新しいモーダルを積み重ねるためには、組み込みの API クライアントを用いて `views.push` を呼び出します。この API 呼び出しには、有効な `trigger_id` と、新しく生成する [ビュー部分のペイロード](https://api.slack.com/reference/block-kit/views)を渡します。`views.push` の引数は [モーダルを開始するとき](/concepts/creating-modals)と同様です。最初のモーダルを開いた後、その上にさらに二つまで追加のモーダルをスタックに積み重ねることができます。
より詳細な情報は [API ドキュメント](/concepts/view-submissions)を参照してください。
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/view-submissions.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/view-submissions.md
similarity index 97%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/view-submissions.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/view-submissions.md
index f22c6cf89..641de55d5 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/view-submissions.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/view-submissions.md
@@ -14,7 +14,7 @@ slug: /concepts/view-submissions
---
-##### モーダル送信でのビューの更新
+## モーダル送信でのビューの更新
`view_submission` リクエストに対してモーダルを更新するには、リクエストの確認の中で `update` という `response_action` と新しく作成した `view` を指定します。
@@ -33,7 +33,7 @@ app.view('modal-callback-id', async ({ ack, body }) => {
---
-##### モーダルを閉じるときのハンドリング
+## モーダルを閉じるときのハンドリング
💡 `view_closed` リクエストをリッスンするとき、`callback_id` と `type: 'view_closed'` を含むオブジェクトの指定が必要です。以下の例を参照してください。
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/web-api.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/web-api.md
similarity index 88%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/web-api.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/web-api.md
index a5578871f..6eccc9c0b 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/web-api.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/web-api.md
@@ -4,7 +4,7 @@ lang: ja-jp
slug: /concepts/web-api
---
-[Web API メソッド](https://api.slack.com/methods)を呼び出すには、リスナー関数の引数に `client` として提供されている [`WebClient`](https://tools.slack.dev/node-slack-sdk/web-api) を使用します。このインスタンスが使用するトークンは、Bolt アプリの初期化時に指定されたもの もしくは Slack からのリクエストに対して [`authorize` 関数](/concepts/authorization)から返されたものが設定されます。組み込みの [OAuth サポート](/concepts/authenticating-oauth)は、この後者のケースをデフォルトでハンドリングします。
+[Web API メソッド](https://api.slack.com/methods)を呼び出すには、リスナー関数の引数に `client` として提供されている [`WebClient`](https://tools.slack.dev/node-slack-sdk/web-api) を使用します。このインスタンスが使用するトークンは、Bolt アプリの初期化時に指定されたもの **もしくは** Slack からのリクエストに対して [`authorize` 関数](/concepts/authorization)から返されたものが設定されます。組み込みの [OAuth サポート](/concepts/authenticating-oauth)は、この後者のケースをデフォルトでハンドリングします。
Bolt アプリケーションは、トップレベルに `app.client` も持っています。このインスタンスには、トークンをメソッド呼び出しのパラメーターとして都度指定します。Slack からのリクエストが authorize されないユースケースや、リスナー関数の外で Web API を呼び出したい場合は、このトップレベルの `app.client` を使用します。
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/deployments/aws-lambda.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/deployments/aws-lambda.md
index 743589da5..5a266eb60 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/deployments/aws-lambda.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/deployments/aws-lambda.md
@@ -3,16 +3,13 @@ title: AWS Lambda へのデプロイ
lang: ja-jp
---
-# AWS Lambda へのデプロイ
-
このガイドでは、Bolt for JavaScript、[Serverless Framework](https://serverless.com/)、[AWS Lambda](https://aws.amazon.com/lambda/) を使った Slack アプリの準備とデプロイの方法について説明します。
-
この手順を全て終わらせたら、あなたはきっと⚡️ [Deploying to AWS Lambda](https://github.com/slackapi/bolt-js/tree/main/examples/deploy-aws-lambda) のサンプルアプリを動作させたり、それに変更を加えたり、自分のアプリを作ったりすることができるようになるでしょう。
---
-### AWS Lambda のセットアップ {#set-up-aws-lambda}
+## AWS Lambda のセットアップ {#set-up-aws-lambda}
[AWS Lambda](https://aws.amazon.com/lambda/) はサーバーレスの Function-as-a-Service(FaaS)プラットフォームです。AWS Lambda を利用すると、サーバーを管理することなく、コードを実行することができます。このセクションでは、ローカルマシンから AWS Lambda にアクセスするための設定を行います。
@@ -22,7 +19,7 @@ lang: ja-jp
:::
-**1. AWS アカウントを作成する**
+### 1. AWS アカウントを作成する
AWS アカウントをまだ持っていない場合は、[アカウントを作成](https://aws.amazon.com/)する必要があります。画面に表示される案内に沿って作成しましょう。
@@ -32,7 +29,7 @@ AWS アカウントをまだ持っていない場合は、[アカウントを作
:::
-**2. AWS のアクセスキーを作成する**
+### 2. AWS のアクセスキーを作成する
Lambda へのデプロイでは、プログラムから AWS アカウントにアクセスする手段が必要になります。AWS の世界では、このために**アクセスキー ID** と**シークレットアクセスキー**が必要です。
@@ -44,13 +41,13 @@ Lambda へのデプロイでは、プログラムから AWS アカウントに
:::
-**3. AWS CLI をインストールする**
+### 3. AWS CLI をインストールする
AWS では [macOS、Windows、Linux](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) にインストールして利用できるコマンドラインインターフェイス(CLI)のツールが用意されています。
macOS では、[最新の .pkg インストーラーをダウンロード](https://awscli.amazonaws.com/AWSCLIV2.pkg)して AWS CLI をインストールできます。
-**4. AWS プロファイルを構成する**
+### 4. AWS プロファイルを構成する
AWS CLI を使ってプロファイルを構成します。プロファイルはローカルマシンに置かれ、アクセスキーのペアを保管します。この CLI やその他のツールは、このプロファイルを使って AWS にアクセスします。
@@ -74,12 +71,10 @@ aws configure
---
-### Serverless Framework をセットアップする {#set-up-serverless-framework}
+## Serverless Framework をセットアップする {#set-up-serverless-framework}
[Serverless Framework](https://serverless.com/) では、AWS Lambda 向けのアプリの設定、デバッグ、デプロイを簡単に行うためのツールが用意されています。
-**1. Serverless Framework CLI をインストールする**
-
Serverless でも macOS、Windows、Linux にインストールして利用できるコマンドラインインターフェイス(CLI)のツールが用意されています。インストールするには Serverless の[入門ガイド(英語)](https://www.serverless.com/framework/docs/getting-started/) をお読みください。
インストールが完了したら Serverless CLI をテストするため、利用可能なコマンドを表示してみましょう。
@@ -92,7 +87,7 @@ Serverless のツールのセットアップが完了しました。次に、AWS
---
-### Bolt Slack アプリを入手する {#get-a-bolt-slack-app}
+## Bolt Slack アプリを入手する {#get-a-bolt-slack-app}
まだ Bolt アプリを自分で作成したことがない場合は、[入門ガイド](/getting-started)を参照してください。テンプレートのアプリをクローンするには、以下のコマンドを実行します。
@@ -110,9 +105,9 @@ Bolt アプリを用意できました。次に AWS Lambda と Serverless Framew
---
-### アプリをセットアップする {#prepare-the-app}
+## アプリをセットアップする {#prepare-the-app}
-**1. アプリを AWS Lambda に対応させる**
+### 1. アプリを AWS Lambda に対応させる
デフォルトでは、入門ガイドの Bolt サンプルアプリはソケットモードを使用しています。WebSocket イベントの代わりに HTTP リクエストをリッスンするため、 `app.js` の設定を変更しましょう。
@@ -174,7 +169,7 @@ module.exports.handler = async (event, context, callback) => {
完成したアプリのソースコードは、⚡️[deploy-aws-lambda](https://github.com/slackapi/bolt-js/tree/main/examples/deploy-aws-lambda/app.js) のサンプルのようになります。
-**2. serverless.yml を追加する**
+### 2. serverless.yml を追加する
Serverless Framework のプロジェクトでは、アプリの設定とデプロイに `serverless.yml` ファイルを使用します。
@@ -206,7 +201,7 @@ plugins:
:::
-**3. serverless-offline モジュールをインストールする**
+### 3. serverless-offline モジュールをインストールする
ローカルでの開発を容易にするため、`serverless-offline` モジュールを使ってデプロイ対象の関数をエミュレートできるようにしましょう。
@@ -220,11 +215,11 @@ npm install --save-dev serverless-offline
---
-### アプリをローカルで実行する {#run-the-app-locally}
+## アプリをローカルで実行する {#run-the-app-locally}
アプリを AWS Lambda 関数に応答させるための準備が完了したので、次にローカルでアプリを実行できるように環境を設定します。
-**1. ローカルのサーバーを起動する**
+### 1. ローカルのサーバーを起動する
まず、アプリの起動と AWS Lambda 関数のイベントをリッスンするため、`serverless offline` コマンドを実行します。
@@ -250,7 +245,7 @@ ngrok http 3000
:::
-**2. リクエスト URL を変更する**
+### 2. リクエスト URL を変更する
次に、[Slack アプリの設定](https://api.slack.com/apps)を開き、**リクエスト URL** を ngrok のウェブアドレスに変更します。
@@ -268,7 +263,7 @@ ngrok http 3000
![「Event Subscriptions」ページ](/img/event-subscriptions-page.png "「Event Subscriptions」ページ")
-**3. Slack アプリをテストする**
+### 3. Slack アプリをテストする
Slack アプリをテストします。今作った Bolt アプリを Slack のチャンネルに招待し、半角の小文字で「hello」と入力してみましょう。[入門ガイド](/getting-started)のとおり、アプリから応答があるはずです。
@@ -285,13 +280,13 @@ Slack アプリをテストします。今作った Bolt アプリを Slack の
---
-### アプリをデプロイする {#deploy-the-app}
+## アプリをデプロイする {#deploy-the-app}
今までローカルでアプリを実行し、 Slack ワークスペースでテストをしてきました。さて、動作するアプリができたので、デプロイしてみましょう!
AWS Lambda 向けのアプリのプロビジョニング、パッケージング、デプロイには、Serverless Framework のツールが利用できます。アプリのデプロイが完了したら、アプリのリクエスト URL を更新して、「hello」と入力した時にアプリが応答できるようにします。✨
-**1. AWS Lambda にアプリをデプロイする**
+### 1. AWS Lambda にアプリをデプロイする
次のコマンドを使って AWS Lambda にアプリをデプロイします。
@@ -312,7 +307,7 @@ serverless deploy
:::
-**2. Slack アプリの設定を更新する**
+### 2. Slack アプリの設定を更新する
Slack からのイベントやアクションの送信先となる**リクエスト URL** に、発行された AWS Lambda の**エンドポイント**を指定します。[Slack アプリの構成](https://api.slack.com/apps)を開き、先ほどコピーしたエンドポイントを**リクエスト URL** に貼りつけます。
@@ -324,7 +319,7 @@ Slack からのイベントやアクションの送信先となる**リクエス
![「Event Subscriptions」ページ](/img/event-subscriptions-page.png "「Event Subscriptions」ページ")
-**3. Slack アプリをテストする**
+### 3. Slack アプリをテストする
アプリのデプロイと、Slack の設定の更新が完了しました。動作を試してみましょう。
@@ -333,7 +328,7 @@ Slack からのイベントやアクションの送信先となる**リクエス
> 👩💻 hello
> 🤖 Hey there @Jane!
-**4. 更新をデプロイする**
+### 4. 更新をデプロイする
Slack アプリの開発を継続していくなら、更新したアプリをデプロイする必要が出てくるでしょう。それをやってみるために、「goodbye」というメッセージに応答するようにアプリを変更してみましょう。
@@ -355,11 +350,15 @@ serverless deploy
デプロイが完了したら、アプリを参加させた Slack チャンネルを開いて、半角の小文字で「goodbye」と入力してみましょう。Slack アプリに「See you later」と表示されるはずです。
-> ⛳️ 一つの関数に小さな変更を加える場合、その関数だけをデプロイするためにより高速な `serverless deploy function -f my-function` を実行することができます。より詳細なヘルプを見るには `serverless help deploy function` を実行してください。
+:::tip
+
+一つの関数に小さな変更を加える場合、その関数だけをデプロイするためにより高速な `serverless deploy function -f my-function` を実行することができます。より詳細なヘルプを見るには `serverless help deploy function` を実行してください。
+
+:::
---
-### 次のステップ {#next-steps}
+## 次のステップ {#next-steps}
⚡️[AWS Lambda を使った最初の Bolt for JavaScript アプリ](https://github.com/slackapi/bolt-js/tree/main/examples/deploy-aws-lambda)をデプロイできました。🚀
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/deployments/heroku.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/deployments/heroku.md
index 8eacde210..715e0ecd4 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/deployments/heroku.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/deployments/heroku.md
@@ -3,16 +3,13 @@ title: Heroku へのデプロイ
lang: ja-jp
---
-# Heroku へのデプロイ
-
このガイドでは、Bolt for JavaScriptと[Heroku プラットフォーム](https://heroku.com/)を使ってSlack アプリを用意して、デプロイするまでの手順を説明します。全体の流れとしては、Bolt Slack アプリをダウンロードし、Heroku 用の準備を済ませ、デプロイする流れになります。
-
この手順を全て終わらせたら、あなたはきっと️⚡️[getting-started-with-heroku](https://github.com/slackapi/bolt-js/tree/main/examples/deploy-heroku)のサンプルアプリを動作させたり、それに変更を加えたり、自分のアプリを作ったりすることができるようになるでしょう。
---
-### Bolt Slack アプリを入手する {#get-a-bolt-slack-app}
+## Bolt Slack アプリを入手する {#get-a-bolt-slack-app}
Bolt アプリを作るのが初めてという場合は、まず[Bolt 入門ガイド](/getting-started)に沿って進めてみましょう。または、以下のテンプレートアプリをクローンしてもよいでしょう。
@@ -30,11 +27,11 @@ cd bolt-js-getting-started-app/
---
-### アプリをHeroku で動かすための準備する {#prepare-the-app-for-heroku}
+## アプリをHeroku で動かすための準備する {#prepare-the-app-for-heroku}
Heroku は、作ったアプリをホストできる柔軟性の高いプラットフォームで、少し設定が必要です。このセクションでは、Bolt アプリに変更を加え、Heroku に対応させます。
-**1. Git リポジトリを使用する**
+### 1. Git リポジトリを使用する
Heroku にアプリをデプロイするには、まずGit リポジトリが必要です。まだGit を使ったことがない場合は、[Git をインストール](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)し、[Git リポジトリを作成](https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository)します
@@ -44,7 +41,7 @@ Heroku にアプリをデプロイするには、まずGit リポジトリが必
:::
-**2. Procfile を追加する**
+### 2. Procfile を追加する
Heroku アプリでは、必ず`Procfile`という専用のファイルが必要です。このファイルを使ってHeroku にアプリの起動方法を伝えます。Bolt Slack アプリは、公開されたWeb アドレスを持つWeb サーバーとして起動します。
@@ -77,11 +74,11 @@ git commit -m "Add Procfile"
---
-### Heroku ツールをセットアップする {#set-up-the-heroku-tools}
+## Heroku ツールをセットアップする {#set-up-the-heroku-tools}
ローカルマシンでHeroku ツールのセットアップを行います。このツールは、Heroku プラットフォームを使用するアプリの管理、デプロイ、デバッグを行う場合に便利です。
-**1. Heroku CLI をインストールする**
+### 1. Heroku CLI をインストールする
Heroku ツールは、コマンドラインインターフェイス(CLI)の形で提供されています。さっそく[macOS、Windows、Linux 用のHeroku CLI](https://devcenter.heroku.com/articles/getting-started-with-nodejs#set-up)をインストールしましょう。macOS では次のコマンドを実行します。
@@ -101,7 +98,7 @@ heroku help
:::
-**2. Heroku CLI にログインする**
+### 2. Heroku CLI にログインする
Heroku CLI では、ローカルマシンからHeroku アカウントに接続します。[無料のHeroku アカウントを新規登録](https://heroku.com)して、次のコマンドでHeroku CLI にログインします。
@@ -114,7 +111,7 @@ heroku login
:::
-**3. Heroku CLI へのログインが成功したか確認する**
+### 3. Heroku CLI へのログインが成功したか確認する
ログインできたかどうか確認しましょう。次のコマンドを実行すると、Heroku CLI に現在接続されているアカウント名が表示されます。
@@ -126,7 +123,7 @@ heroku auth:whoami
---
-### Heroku アプリを作成する {#create-an-app-on-heroku}
+## Heroku アプリを作成する {#create-an-app-on-heroku}
先ほどインストールしたツールを使って、[Heroku アプリを作成](https://devcenter.heroku.com/articles/creating-apps)します。アプリを作成するときは、ユニークな名前を自分で指定するか、ランダムな名前を生成することができます。
@@ -136,7 +133,7 @@ heroku auth:whoami
:::
-**1. Heroku アプリを作成する**
+### 1. Heroku アプリを作成する
ユニークな名前を指定してHeroku アプリを作成します。
@@ -158,7 +155,7 @@ Heroku アプリが作成されると、いくつかの情報が表示されま
- Web アドレス: `https://sharp-rain-871.herokuapp.com/`
- 空のリモートGit リポジトリ: `https://git.heroku.com/sharp-rain-871.git`
-**2. Heroku のリモートGit リポジトリを確認する**
+### 2. Heroku のリモートGit リポジトリを確認する
Heroku CLI は、自動的に`heroku`という名前のリモートGit リポジトリをローカルに追加します。リモートGit リポジトリを一覧して、`heroku`が存在することを確認しましょう。
@@ -168,7 +165,7 @@ git remote -v
# heroku https://git.heroku.com/sharp-rain-871.git (push)
```
-**3. アプリをデプロイする**
+### 3. アプリをデプロイする
Slack アプリの認証情報をHeroku アプリに設定します。
@@ -187,11 +184,11 @@ heroku config:set SLACK_BOT_TOKEN=xoxb-
---
-### アプリをデプロイする {#deploy-the-app}
+## アプリをデプロイする {#deploy-the-app}
アプリをデプロイするため、ローカルのコードをHeroku にプッシュします。その後Slack アプリの設定を更新し、Heroku アプリに"hello" と声をかけてみましょう。 ✨
-**1. Heroku にアプリをデプロイする**
+### 1. Heroku にアプリをデプロイする
Heroku へのアプリのデプロイには、通常`git push`コマンドを使用します。これにより、ローカルリポジトリのコードがリモートの`heroku`リポジトリにプッシュされます。
@@ -214,7 +211,7 @@ Heroku deploys code that's pushed to the [master or main branches](https://devce
heroku ps:scale web=1
```
-**2. Slack アプリの設定を更新する**
+### 2. Slack アプリの設定を更新する
次に、Heroku のWeb アドレスをリクエストURL に指定し、Slack からのイベントやアクションがこのURL に送信されるようにします。
@@ -250,7 +247,7 @@ heroku info
:::
-**3. Slack アプリをテストする**
+### 3. Slack アプリをテストする
アプリのデプロイが完了し、Slack の設定変更も行いました。アプリを試してみましょう。
@@ -258,7 +255,7 @@ heroku info
---
-### 変更をデプロイする {#deploy-an-update}
+## 変更をデプロイする {#deploy-an-update}
Slack アプリを構築するなかで、変更を加えてデプロイする必要があります。一般的な流れでは、変更を加え、コミットし、Heroku にプッシュするという順番です。
@@ -288,7 +285,7 @@ git push heroku main
---
-### 次のステップ {#next-steps}
+## 次のステップ {#next-steps}
これではじめて️⚡Bolt for JavaScript アプリをHerokuへデプロイすることに成功しました。🚀
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.mdx
similarity index 68%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.mdx
index 2bfc095af..86c59dc29 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.mdx
@@ -5,19 +5,13 @@ slug: getting-started
lang: ja-jp
---
-# Bolt 入門ガイド
-
このガイドでは、Bolt を使用して Slack アプリを起動し実行する方法について説明します。その過程で、新しい Slack アプリを作成し、ローカル環境を設定し、Slack ワークスペースからのメッセージをリッスンして応答するアプリを開発します。
-:::tip
-
-このガイドでは[ソケットモード](https://api.slack.com/apis/connections/socket) を利用します。ソケットモードは、Slack アプリ開発をとりあえず始めてみるときやあなたのチームだけのためのアプリをつくるときにおすすめのやり方です。もしすでに HTTP をアプリのコミュニケーションプロトコルとしてするとわかっているなら、HTTP の方式に対応した同様のドキュメントである [Bolt 入門ガイド(HTTP)](/tutorial/getting-started-http) を参照してください。
-
-:::
+このガイドが終わったら、あなたはこの⚡️[Getting Started app](https://github.com/slackapi/bolt-js-getting-started-app)を実行したり、修正したり、自分で作ったりすることができます。
---
-### アプリを作成する {#create-an-app}
+## アプリを作成する {#create-an-app}
最初にやるべきこと: Bolt で開発を始める前に、 [Slack アプリを作成](https://api.slack.com/apps/new)します。
:::tip
@@ -36,7 +30,7 @@ lang: ja-jp
---
-### トークンとアプリのインストール {#tokens-and-installing-apps}
+## トークンとアプリのインストール {#tokens-and-installing-apps}
Slack アプリは、[OAuth を使用して、Slack の API へのアクセスを管理](https://api.slack.com/docs/oauth)します。アプリがインストールされるとトークンが発行されます。そのトークンを使って、アプリは API メソッドを呼び出すことができます。
Slack アプリで使用できるトークンには、ユーザートークン(`xoxp`)とボットトークン(`xoxb`)、アプリレベルトークン(`xapp`)の 3 種類があります。
@@ -64,7 +58,7 @@ Slack アプリで使用できるトークンには、ユーザートークン
---
-### ローカルプロジェクトの設定 {#setting-up-your-project}
+## ローカルプロジェクトの設定 {#setting-up-your-project}
初期設定が完了したので、次は新しい Bolt プロジェクトを設定します。ここで、アプリのロジックを処理するコードを記述します。
プロジェクトをまだ作成していない場合は、新しいプロジェクトを作成しましょう。次のように、空のディレクトリを作成して、新しいプロジェクトを初期化します。
@@ -79,17 +73,23 @@ npm init
Bolt パッケージを新しいプロジェクトにインストールする前に、アプリの設定時に生成されたボットトークンと signing secret (サイン認証) を保存しましょう。これらは環境変数として保存する必要があります。**バージョン管理では保存しない**でください。
-1. **Basic Information ページから Signing Secret をコピー**して、新しい環境変数に保存します。次の例は Linux と macOS で動作します。ただし、[Windows でも同様のコマンドが利用可能](https://superuser.com/questions/212150/how-to-set-env-variable-in-windows-cmd-line/212153#212153)です。
+1. **Basic Information ページから Signing Secret をコピー**して、新しい環境変数に保存します。次の例は Linux と macOS で動作します。ただし、[Windows でも同様のコマンドが利用可能](https://superuser.com/questions/212150/how-to-set-env-variable-in-windows-cmd-line/212153#212153)です。
+
```shell
export SLACK_SIGNING_SECRET=
```
-2. **OAuth & Permissions ページからボット (xoxb) トークンをコピー**し、それを別の環境変数に格納します。
+2. **OAuth & Permissions ページからボット (xoxb) トークンをコピー**し、それを別の環境変数に格納します。
+
```shell
export SLACK_BOT_TOKEN=xoxb-
```
-> 🔒 全てのトークンは安全に保管してください。少なくともパブリックなバージョン管理にチェックインするようなことは避けるべきでしょう。また、上にあった例のように環境変数を介してアクセスするようにしてください。詳細な情報は [アプリのセキュリティのベストプラクティス](https://api.slack.com/authentication/best-practices)のドキュメントを参照してください。
+:::info
+
+🔒 全てのトークンは安全に保管してください。少なくともパブリックなバージョン管理にチェックインするようなことは避けるべきでしょう。また、上にあった例のように環境変数を介してアクセスするようにしてください。詳細な情報は [アプリのセキュリティのベストプラクティス](https://api.slack.com/authentication/best-practices)のドキュメントを参照してください。
+
+:::
それでは、アプリを作成しましょう。次のコマンドを使用して、`@slack/bolt` パッケージをインストールし、 `package.json` 中で依存ファイルとして保存します。
@@ -126,15 +126,23 @@ node app.js
---
-### イベントの設定 {#setting-up-events}
+## イベントの設定 {#setting-up-events}
アプリはワークスペース内の他のメンバーと同じように振る舞い、メッセージを投稿したり、絵文字リアクションを追加したり、イベントをリッスンして返答したりできます。
-Slack ワークスペースで発生するイベント(メッセージが投稿されたときや、メッセージに対するリアクションがつけられたときなど)をリッスンするには、[Events API を使って特定の種類のイベントをサブスクライブします](https://api.slack.com/events-api)。このチュートリアルでは、[ソケットモード](https://api.slack.com/apis/connections/socket)を使用します。 Socket モードは、チームのために何かを作り始めたばかりの人にお勧めのオプションです。
+Slack ワークスペースで発生するイベント(メッセージが投稿されたときや、メッセージに対するリアクションがつけられたときなど)をリッスンするには、[Events API を使って特定の種類のイベントをサブスクライブします](https://api.slack.com/events-api)。
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+
+このチュートリアルでは、[ソケットモード](https://api.slack.com/apis/connections/socket)を使用します。 Socket モードは、チームのために何かを作り始めたばかりの人にお勧めのオプションです。
:::tip
-ソケットモードを使うことで、アプリが公開された HTTP エンドポイントを公開せずに Events API やインタラクティブコンポーネントを利用できるようになります。このことは、開発時やファイヤーウォールの裏からのリクエストを受ける際に便利です。HTTP での方式はホスティング環境([AWS](/deployments/aws-lambda) or [Heroku](/deployments/heroku)など)にデプロイするアプリや Slack App Directory で配布されるアプリに適しています。 HTTP での情報については[こちらのドキュメント](/tutorial/getting-started-http#setting-up-events-with-http)を参照してください。
+ソケットモードを使うことで、アプリが公開された HTTP エンドポイントを公開せずに Events API やインタラクティブコンポーネントを利用できるようになります。このことは、開発時やファイヤーウォールの裏からのリクエストを受ける際に便利です。HTTP での方式はホスティング環境([AWS](/deployments/aws-lambda) or [Heroku](/deployments/heroku)など)にデプロイするアプリや Slack App Directory で配布されるアプリに適しています。 HTTP での情報については[こちらのドキュメント](#setting-up-events)を参照してください。
:::
@@ -144,6 +152,30 @@ Slack ワークスペースで発生するイベント(メッセージが投
2. **Basic Information** にアクセスし、「App Token」セクションの下にスクロールし、**Generate Token and Scopes** をクリックしてアプリトークンを生成します。このトークンに `connections:write` スコープを追加し、生成された `xapp` トークンを保存します。
+
+
+
+アプリのイベントを有効にしましょう。
+
+1. アプリのイベントを有効にするには、まずアプリ設定ページに戻ります ([アプリ管理ページ](https://api.slack.com/apps)でアプリをクリックします)。左側のサイドバーにある **Event Subscription** をクリックします。**Enable Events** のスイッチをオンにします。
+
+2. Request URLを追加します。Slackはイベントに対応するHTTP POSTリクエストをこの[Request URL](https://api.slack.com/apis/connections/events-api#the-events-api__subscribing-to-event-types__events-api-request-urls)エンドポイントに送信します。Boltは`/slack/events`のパスを使用して、すべての受信リクエスト(ショートカット、イベント、インタラクティビティのペイロードなど)をリッスンします。アプリの設定でRequest URLを設定する際には、`https:///slack/events`のように`/slack/events`を追加します。💡
+
+:::tip
+
+ローカル開発では、[ngrok](https://ngrok.com/)のようなプロキシサービスを使って公開 URL を作成し、リクエストを開発環境にトンネリングすることができます。このトンネリングの方法については、[ngrok のガイド](https://ngrok.com/docs#getting-started-expose)を参照してください。
+
+:::
+
+最後に、聞きたいイベントをSlackに伝えましょう。**Event Subscriptions**の下にある、**Enable Events**というラベルの付いたスイッチを切り替えます。
+
+イベントが発生すると、Slack は、そのイベントをトリガーしたユーザーやイベントが発生したチャンネルなど、イベントに関する情報をアプリに送信します。アプリが詳細を処理し、それに応じて応答することができます。
+
+**Request URL** ボックスの **Enable Events** スイッチの下のフィールドにこの URL を貼り付けます。Bolt アプリが引き続き実行されている場合は、URL が検証されチェックマークが表示されます。
+
+
+
+
そして最後に、私たちがどのイベントをリッスンしたいかを Slack に伝えましょう。
イベントが発生すると、そのイベントをトリガーしたユーザーやイベントが発生したチャンネルなど、イベントに関する情報が Slack からアプリに送信されます。アプリではこれらの情報を処理して、適切な応答を返します。
@@ -158,11 +190,14 @@ Slack ワークスペースで発生するイベント(メッセージが投
---
-### メッセージのリスニングと応答 {#listening-and-responding-to-a-message}
+## メッセージのリスニングと応答 {#listening-and-responding-to-a-message}
これで、アプリでいくつかのロジックを設定する準備が整いました。まずは `message()` メソッドを使用して、メッセージのリスナーをアタッチしましょう。
次の例では、あなたのアプリが追加されているチャンネルや DM で `hello` という単語を含むすべてのメッセージをリッスンし、 `Hey there @user!` と応答します。
+
+
+
```javascript
const { App } = require('@slack/bolt');
@@ -190,22 +225,65 @@ app.message('hello', async ({ message, say }) => {
})();
```
+
+
+
+```javascript
+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` を含むメッセージを送信してみてください。アプリが応答したら成功です。
これは基本的な例ですが、ここから自分の好きなようにアプリをカスタマイズしていくことができます。さらにインタラクティブな動作を試すために、プレーンテキストではなくボタンを送信してみましょう。
---
-### アクションの送信と応答 {#sending-and-responding-to-actions}
+## アクションの送信と応答 {#sending-and-responding-to-actions}
ボタン、選択メニュー、日付ピッカー、モーダルなどの機能を使用するには、インタラクティブ機能を有効にする必要があります。イベントと同様に、Slack の URL を指定してアクション ( 「ボタン・クリック」など) を送信する必要があります。
+
+
+
+ソケットモードを有効にしているとき、デフォルトで基本的なインタラクティブ機能が有効になっていため、ここでは特に何もする必要はいありません。
+
+
+
+
+アプリ設定ページに戻り、左側の **Interactivity & Shortcuts** をクリックします。**Request URL** ボックスがもう 1 つあることがわかります。
+
:::tip
-ソケットモードを有効にしているとき、デフォルトで基本的なインタラクティブ機能が有効になっていため、ここでは特に何もする必要はいありません。もし HTTP を使っている場合、Slack からのイベント送信先である Request URL を設定する必要があります。
+デフォルトでは、Bolt はイベントに使用しているのと同じエンドポイントをインタラクティブコンポーネントに使用するように設定されているため、上記と同じリクエスト URL (この例では `https://8e8ec2d7.ngrok.io/slack/events`) を使用します。右下隅にある **Save Changes** ボタンを押してください。これでアプリのインタラクティブなコンポーネントを利用する設定が有効になりました!
:::
+![Configuring a Request URL](/img/request-url-config.png "Configuring a Request URL")
+
+
+
+
インタラクティブ機能が有効化されていると、ショートカット、モーダル、インタラクティブコンポーネント (例:ボタン、選択メニュー、日付ピッカーなど) とのインタラクションがイベントとしてあなたのアプリに送信されます。
それでは、アプリのコードに戻り、インタラクティブな処理を追加しましょう。この実装は以下の二つのステップで構成されます。
@@ -214,6 +292,9 @@ app.message('hello', async ({ message, say }) => {
以下は、前のセクションで記述したアプリコードを、文字列だけでなく、ボタン付きのメッセージを送信するように変更したものです。
+
+
+
```javascript
const { App } = require('@slack/bolt');
@@ -260,6 +341,53 @@ app.message('hello', async ({ message, say }) => {
})();
```
+
+
+
+```javascript
+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` が割り当てられています。これはボタンの一意の識別子として機能するため、アプリはどのアクションに応答するかを指定できます。
@@ -274,6 +402,9 @@ app.message('hello', async ({ message, say }) => {
ボタンがクリックされるとフォローアップメッセージを送信するハンドラーを追加してみましょう。
+
+
+
```javascript
const { App } = require('@slack/bolt');
@@ -326,12 +457,66 @@ app.action('button_click', async ({ body, ack, say }) => {
})();
```
+
+
+
+
+```javascript
+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 という新しいメッセージがアプリに表示されるはずです。
---
-### 次のステップ {#next-steps}
-これで最初の Bolt アプリをソケットモードを使って構築できました! 🎉
+## 次のステップ {#next-steps}
+これで最初の Bolt アプリが構築できました! 🎉
基本的なアプリの作成ができましたので、次回は是非もっといろいろな、 Bolt の機能を使ってアプリを作ってみましょう。下記のリンクを辿っていろいろアイデアを模索してみてください!
@@ -339,6 +524,4 @@ app.action('button_click', async ({ body, ack, say }) => {
* ボットが[`events()` メソッド](/concepts/event-listening)でリッスンできるさまざまなイベントを確認しましょう。イベントはすべて[API サイト](https://api.slack.com/events)にリストされています。
-* Bolt を使用すると、アプリにアタッチされているクライアントで [Web API メソッドを呼び出す](/concepts/web-api)ことができます。API サイトに [200 を超えるメソッド](https://api.slack.com/methods)を用意してあります。
-
-* [API サイト](https://api.slack.com/docs/token-types)では、様々なトークンタイプの詳細を確認することができます。アプリには、実行するアクションに応じて異なるトークンが必要になる場合があります。ソケットモードを使わないアプリでは、通常はボットトークン (`xoxb`) と署名シークレットが必要です。ソケットモードを使わない場合の例については、 HTTP 方式のやり方としてこのチュートリアルと対になっている [Bolt 入門ガイド(HTTP)](/tutorial/getting-started-http)を参照してください。
\ No newline at end of file
+* Bolt を使用すると、アプリにアタッチされているクライアントで [Web API メソッドを呼び出す](/concepts/web-api)ことができます。API サイトに [200 を超えるメソッド](https://api.slack.com/methods)を用意してあります。
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/conversation-store.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/conversation-store.md
similarity index 100%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/advanced/conversation-store.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/conversation-store.md
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/hubot-migration.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/hubot-migration.md
similarity index 86%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/hubot-migration.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/hubot-migration.md
index 30d5173db..2be027651 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/hubot-migration.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/hubot-migration.md
@@ -3,7 +3,6 @@ title: Hubot から Bolt に移行する方法
slug: hubot-migration
lang: ja-jp
---
-# Hubot のアプリを Bolt に移行する方法
Bolt は、Slack アプリを構築する時間と手間を減らすために作成されたフレームワークで、Slack 開発者のみなさんに最新機能とベストプラクティスを使用してアプリを構築できる単一のインターフェイスを提供します。このガイドでは、[Hubot で作成されたアプリを Bolt アプリに](https://hubot.github.com/docs/)移行するプロセスを順を追って説明します。
@@ -11,7 +10,7 @@ Bolt は、Slack アプリを構築する時間と手間を減らすために作
---
-### まずはじめに {#setting-the-stage}
+## まずはじめに {#setting-the-stage}
Hubot アプリを Bolt に変換するとき、それぞれが内部的にどのように機能しているかを把握しているとさらに理解を深めることができるでしょう。Slack の Hubot アダプターは、 WebSocket をベースとした [RTM API](https://api.slack.com/rtm) と接続するように実装されているので、Hubot アプリには一連のワークスペースイベントが一気にストリーミングされます。そして、RTM API は、新しいプラットフォーム機能をサポートしておらず、特にアプリが複数のまたは大規模な Slack チームにインストールされる場合には、膨大なリソースを消費する可能性があるため、ほとんどのユースケースでおすすめできません。
デフォルトの Bolt レシーバーは、[Events API](https://api.slack.com/events-api) をサポートするように構築されています。これは、HTTP ベースのイベントサブスクリプションを使用して Bolt アプリに JSON ペイロードを送信します。Events API には、RTM にはない新機能のイベントも含まれており、より細かい制御が可能でスケーラブルですのでほとんどのユースケースで推奨されています。しかし例外として、RTM API を使用し続けなければならない理由の 1 つに、アプリをホストしているサーバーにファイアウォールがあり、HTTP 送信リクエストのみを許可して、受信リクエストを許可しないというようなケースが挙げられます。
@@ -23,10 +22,10 @@ Bolt アプリを作成する前に考慮に入れた方がよい違いがほか
---
-### ボットの設定 {#configuring-your-bot}
-ボットユーザーを持つ既存の Slack アプリをお持ちの方は、[次のセクションに進むことができます](#ボットの設定-1)。わからない場合は、[App Management ページ](https://api.slack.com/apps) に移動し、自分の Hubot アプリがあるかどうかを確認してください。ある場合は、そのアプリの認証情報をそのまま使用できます ([次のセクションに進んでください](#ボットの設定-1))。ない場合は、下記の手順通りに進めていきましょう。
+## ボットの設定 {#configuring-your-bot}
+ボットユーザーを持つ既存の Slack アプリをお持ちの方は, 次のセクションに進むことができます。わからない場合は、[app settings ページ](https://api.slack.com/apps) に移動し、自分の Hubot アプリがあるかどうかを確認してください。ある場合は、そのアプリの認証情報をそのまま使用できます (次のセクションに進んでください)。ない場合は、下記の手順通りに進めていきましょう。
-#### Slack アプリを作成する
+## Slack アプリを作成する
まず最初に、Slack アプリを作成します。
:::tip
@@ -41,17 +40,21 @@ Bolt アプリを作成する前に考慮に入れた方がよい違いがほか
ひと通り確認し、アプリのアイコンと説明を追加したら、アプリの構成 🔩 を始めましょう。
-#### ボットユーザーを追加する
+### ボットユーザーを追加する
Slack では、Hubot アプリはユーザーとの対話型のボットユーザーを採用しています。
新しいアプリにボットユーザーを追加するには、左側のサイドバーの **Bot Users** をクリックしてから、**Add A Bot User** をクリックします。表示名とユーザー名を指定して、**Add Bot User** をクリックします。その他のフィールドの詳しい情報は、[API サイト](https://api.slack.com/bot-users#creating-bot-user) をご覧ください。
-### ボットの設定 {#configure-what-your-bot-will-hear}
+## ボットの設定 {#configure-what-your-bot-will-hear}
[Events API](https://api.slack.com/bot-users#app-mentions-response) は、ボットの目と耳に相当します。これによりボットは、投稿されたメッセージ、チャンネルの変更、Slack で発生するその他のアクティビティに反応することができます。
-> ⚠️ボットのイベントを設定する前に、パブリック URL が必要です。Bolt アプリを作成したことがない場合、または Events API を使用したことがない場合は、『Getting Started ガイド』の [ローカル Bolt プロジェクトの設定](/getting-started) と [イベントの設定](/getting-started#setting-up-events) を参考にしてください。
+:::warning
-#### メッセージのリスニング
+ボットのイベントを設定する前に、パブリック URL が必要です。Bolt アプリを作成したことがない場合、または Events API を使用したことがない場合は、『Getting Started ガイド』の [ローカル Bolt プロジェクトの設定](/getting-started) と [イベントの設定](/getting-started#setting-up-events) を参考にしてください。
+
+:::
+
+### メッセージのリスニング
すべての Hubot アプリは、デフォルトでメッセージをリッスンできるので、ボットユーザーがそうするように設定する必要があります。
[イベントの設定](/getting-started#setting-up-events) を行ってから、リクエスト URL を入力、そして検証されたことを確認したら、**Subscribe to Bot Events** にスクロールダウンします。メッセージに関連する次の 4 つのイベントがあります `message channel` (パブリックチャンネルのメッセージをリッスン)、`message group` (プライベートチャンネルのメッセージをリッスン)、`message.im` (アプリのホーム/DM スペースのメッセージをリッスン)、`message.mpim` (マルチパーソン DM のメッセージをリッスン)。
@@ -60,7 +63,7 @@ Slack では、Hubot アプリはユーザーとの対話型のボットユー
ボットにリッスンさせるメッセージイベントの種類を追加して、**Save Changes** をクリックします。
-#### その他のイベントのリッスン
+### その他のイベントのリッスン
使用していた機能に応じて、Hubot アプリはほかのイベントにも応答していたかもしれません。スクリプトを調べて、`react`、`respond`、`presenceChange` が使用されている箇所を特定してください。
- アプリで `respond` が使用されている場合、`app_mention` イベントをサブスクライブします。これで、ボットユーザーがメンションされる時をリッスンします。
- アプリで `react` が使用されている場合、`reaction_added` イベントをサブスクライブします。これにより、ボットユーザーがいるチャンネルのメッセージにリアクションが追加される時をリッスンします。
@@ -74,41 +77,57 @@ Bolt に追加された利点として、どの [Events API イベント](https:
アプリの機能に対応するイベントを追加 し終えたら、**Save Changes** をクリックします。
-### スクリプトインターフェイスの変更 {#changes-to-script-interfaces}
+## スクリプトインターフェイスの変更 {#changes-to-script-interfaces}
Bolt のインターフェイスは、可能な限り Slack API 言語に適合するように設計されましたが、Hubot は複数のサービスを抽象化するために一般化された言語を使用して設計されました。インターフェイスは似ていますが、Hubot スクリプトを Bolt スクリプトに変換するには、いくらかコードを変更する必要があります。
Bolt は、`res` を使用せず、Slack からの raw リクエストを公開しません。代わりに、`payload` 使ってペイロードボディを取得したり、`say()` を使ってメッセージを送信するといった一般的な機能を使用したりできます。
-> ⚙わかりやすくするために、サンプルスクリプトを Github 上に作成しました。このスクリプトは、[Bolt 用に書かれた機能と同等のものを使用している Hubot のコア機能を紹介しています。](https://github.com/slackapi/bolt-js/blob/master/examples/hubot-example/script.js)
+:::tip
+
+⚙わかりやすくするために、サンプルスクリプトを Github 上に作成しました。このスクリプトは、[Bolt 用に書かれた機能と同等のものを使用している Hubot のコア機能を紹介しています。](https://github.com/slackapi/bolt-js/blob/master/examples/hubot-example/script.js)
-#### `message()` を使用したパターンのリスニング
+:::
+
+### `message()` を使用したパターンのリスニング
Hubot スクリプトは、`hear()` を使用して、一致するパターンを持つメッセージをリッスンします。代わりに、 Bolt は `message()` を使用して、そのパターンの `string` または `RegExp` を受け入れます。
-> 👨💻👩💻コードで `hear()` を使用している箇所はすべて、`message()` を使用するように変更してください。
+:::tip
+
+👨💻👩💻コードで `hear()` を使用している箇所はすべて、`message()` を使用するように変更してください。
+
+:::
[メッセージのリスニングについてもっと詳しく読む](/concepts/message-listening).
-#### `say()` および `respond()` を使用したメッセージで応答する
+### `say()` および `respond()` を使用したメッセージで応答する
Hubot スクリプトは、`send()` を使用してメッセージを同じ会話に送信し、`reply()` を使用して、元のメッセージを送信したユーザー宛の@メンションを付けて、メッセージを同じ会話上に送信します。
Bolt は、`send()` の代わりに `say()` を使用し、`respond()` を使用して `response_url` で返信を送信します。返信の冒頭にメンションを追加するには、`context` オブジェクトにあるユーザー ID を使用できます。たとえば、メッセージイベントの場合は次のようにできます: `say('<@${message.user}>Hello :wave:')`
Hubot の `send()` と Bolt の `say()` はほとんど同じですが、`say()` を使用すると [ボタン、メニューの選択、デートピッカー](https://api.slack.com/messaging/interactivity#interaction) といったインタラクティブなコンポーネントを付けてメッセージを送信できます。
-> 👨💻👩💻コードで `send()` が使用されている箇所はすべて `say()` に変更してください
+:::tip
+
+👨💻👩💻コードで `send()` が使用されている箇所はすべて `say()` に変更してください
+
+:::
[メッセージへの応答についてもっと詳しく読む](/concepts/message-sending).
-#### `respond` と `react`
+### `respond` と `react`
前のセクションで、Hubot スクリプトで `respond()` が使用されている場合は `app_mention` イベントを、`react()` が使用されている場合は `reaction_added` をサブスクライブするようにアプリを設定しました。
Bolt は、`event()` と呼ばれるメソッドを使用して、任意の [Events API イベント](https://api.slack.com/events) をリッスンできます。コードを変更するには、`respond()` を app.event(‘app_mention’) に、`react()` を `app.event(‘reaction_added’)` に変更するだけです。この点は、[サンプルスクリプト](https://github.com/slackapi/bolt-js/blob/master/examples/hubot-example/script.js) で詳しく説明されています。
-> 👨💻👩💻コードで `respond()` が使用されている箇所はすべて、app.event ('app_mention') を使用するように変更してください。`react` が使用されている箇所はすべて `app.event('reaction_added')` に変更してください。
+:::tip
+
+👨💻👩💻コードで `respond()` が使用されている箇所はすべて、app.event ('app_mention') を使用するように変更してください。`react` が使用されている箇所はすべて `app.event('reaction_added')` に変更してください。
+
+:::
[イベントのリッスンについてもっと詳しく読む](/concepts/event-listening).
-### Bolt で Web API メソッドを使用する {#using-web-api-methods-with-bolt-for-javascript}
+## Bolt で Web API メソッドを使用する {#using-web-api-methods-with-bolt-for-javascript}
Hubot では、`@slack/client` から `WebClient` パッケージをインポートする必要がありました。Bolt では、`app.client` からアクセスできる `WebClient` インスタンスがデフォルトでインポートされます。
組み込みの `WebClient` を使用するには、アプリをインスタンス化するために使用されるトークン、またはリクエストの送信元のチームに関連付けられているトークンを渡す必要があります。これは、リスナー関数に渡された `context` オブジェクトにあります。たとえば、メッセージにリアクションを追加するには、次を使用します:
@@ -129,11 +148,15 @@ app.message('react', async ({ message, context, logger }) => {
});
```
-> 👨💻👩💻`app.client` で組み込みのクライアントを使用するように、Web API 呼び出しを変更してください。
+:::tip
+
+👨💻👩💻`app.client` で組み込みのクライアントを使用するように、Web API 呼び出しを変更してください。
+
+:::
[Bolt での Web API の使用についてもっと詳しく読む。](/concepts/web-api)
-### Bolt でのミドルウェアの使用 {#using-middleware-with-bolt-for-javascript}
+## Bolt でのミドルウェアの使用 {#using-middleware-with-bolt-for-javascript}
Hubot には、受信 (リスナーが呼び出される前に実行される)、リスナー (一致するすべてのリスナーに対して実行される)、応答 (送信されるすべての応答に対して実行される) という 3 種類のミドルウェアがあります。
Bolt には、グローバルとリスナーという 2 種類のミドルウェアしかありません。
@@ -146,7 +169,7 @@ Bolt では、グローバルとリスナーというミドルウェアはいず
ミドルウェアがイベントの後処理を実行する必要がある場合、`undefined` で呼び出すのではなく、後処理関数を使用して `await next()` を呼び出すことができます。後処理関数は、ミドルウェア関数が `await next()` を呼び出すのと同じ方法で` done()` を呼び出す必要があります(`Error` で呼び出すことも可能) 。
-### Brain を conversation store に移行する {#migrating-the-brain-to-the-conversation-store}
+## Brain を conversation store に移行する {#migrating-the-brain-to-the-conversation-store}
Hubot には、brain と呼ばれるメモリ内ストレージがあります。これによって、Hubot スクリプトはデータの基本部分を `get` および `set` することができます。Bolt は、conversation store と呼ばれる、`get()`/`set()` インターフェイスを含むグローバルミドルウェアを使用します。
デフォルトの組み込み conversation store は Hubot に似たメモリ内ストレージを使用し、ミリ秒単位で有効期限を設定できます。conversation の状態情報を get および set する方法は 2 つあります。
@@ -157,7 +180,7 @@ Hubot には、brain と呼ばれるメモリ内ストレージがあります
[会話ストアについてもっと詳しく読む](/concepts/conversation-store).
-### 次のステップ {#next-steps}
+## 次のステップ {#next-steps}
ここまで来れば、きっと Hubot アプリを Bolt アプリに変換できているはずです!✨⚡
新しくなってよりクールになった Bolt アプリを、さらにパワーアップしていくこともできます。
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/steps-from-apps.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/steps-from-apps.md
new file mode 100644
index 000000000..867785076
--- /dev/null
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/steps-from-apps.md
@@ -0,0 +1,194 @@
+---
+title: ワークフローステップの概要
+lang: ja-jp
+slug: /legacy/steps-from-apps
+---
+
+(アプリによる)ワークフローステップ(Workflow Steps from Apps) は、[ワークフロービルダー](https://api.slack.com/workflows)におけるワークフローに組み込み可能なカスタムのワークフローステップを任意の Slack アプリが提供することを可能とします。
+
+ワークフローステップは、三つの異なるユーザーイベントから構成されます:
+
+- ワークフロー作成者がワークフローにカスタムステップを追加・または編集する
+- ワークフロー作成者がステップの設定を保存・更新する
+- ワークフローの利用者がそのワークフローステップを実行する
+
+ワークフローステップを機能させるためには、これら三つのイベント全てを適切にハンドリングする必要があります。
+
+ワークフローステップのさらなる詳細については [API ドキュメント](https://api.slack.com/workflows/steps)を参考にしてください。
+
+---
+
+## ステップの定義
+
+ワークフローステップを作るための手段として Bolt は `WorkflowStep` というクラスを提供しています。
+
+新しい `WorkflowStep` インスタンスの生成には、そのステップの `callback_id` と設定オブジェクトを渡します。
+
+設定オブジェクトには `edit`、`save`、`execute` という三つのプロパティがあります。これらのそれぞれは単一のコールバック関数、またはコールバック関数の配列である必要があります。すべてのコールバック関数は、ワークフローステップのイベントに関する情報を保持しする `step` オブジェクトにアクセスすることができます。
+
+`WorkflowStep` インスタンスを生成したら、それを `app.step()` メソッドに渡します。これによって、Bolt アプリは対象のワークフローステップのイベントをリッスンしたり、設定オブジェクトが提供するコールバック関数を使ってイベントに応答したりすることができるようになります。
+
+
+```javascript
+const { App, WorkflowStep } = require('@slack/bolt');
+
+// いつも通り Bolt アプリを初期化
+const app = new App({
+ signingSecret: process.env.SLACK_SIGNING_SECRET,
+ token: process.env.SLACK_BOT_TOKEN,
+});
+
+// WorkflowStep インスタンスを生成
+const ws = new WorkflowStep('add_task', {
+ edit: async ({ ack, step, configure }) => {},
+ save: async ({ ack, step, update }) => {},
+ execute: async ({ step, complete, fail }) => {},
+});
+
+app.step(ws);
+```
+
+---
+
+## ステップの追加・編集
+
+ワークフローの作成者が、アプリが提供するステップをワークフローに追加(またはその設定を変更)するタイミングで、アプリは [`workflow_step_edit`](https://api.slack.com/reference/workflows/workflow_step_edit) というイベントを受信します。このイベントの受信時に `WorkflowStep` 設定オブジェクト内の `edit` コールバック関数が実行されます。
+
+このとき、ワークフロー作成・変更のどちらの場合でも、アプリは[ワークフローステップ設定のためのモーダル](https://api.slack.com/reference/workflows/configuration-view)を応答する必要があります。このモーダルは、ワークフローステップに固有の設定である必要があり、通常のモーダルにはない制約があります。最もわかりやすいものとしては、`title`、`submit`、`close` プロパティを設定することができません。また、デフォルトの設定では、この設定モーダルの `callback_id` はワークフローステップのものと同じものが使用されます。
+
+`edit` コールバック関数の中では モーダルの view のうち `blocks` だけを渡すだけで簡単にステップ設定モーダルをオープンすることができる `configure()` というユーティリティ関数が利用できます。これは、必要な入力内容が揃うまで設定の保存を無効にする `submit_disabled` というオプションを `true` に設定します。
+
+設定モーダルを開く処理に関するさらなる詳細は、[ドキュメント](https://api.slack.com/workflows/steps#handle_config_view)を参考にしてください。
+
+```javascript
+const ws = new WorkflowStep('add_task', {
+ edit: async ({ ack, step, configure }) => {
+ await ack();
+
+ const blocks = [
+ {
+ type: 'input',
+ block_id: 'task_name_input',
+ element: {
+ type: 'plain_text_input',
+ action_id: 'name',
+ placeholder: {
+ type: 'plain_text',
+ text: 'Add a task name',
+ },
+ },
+ label: {
+ type: 'plain_text',
+ text: 'Task name',
+ },
+ },
+ {
+ type: 'input',
+ block_id: 'task_description_input',
+ element: {
+ type: 'plain_text_input',
+ action_id: 'description',
+ placeholder: {
+ type: 'plain_text',
+ text: 'Add a task description',
+ },
+ },
+ label: {
+ type: 'plain_text',
+ text: 'Task description',
+ },
+ },
+ ];
+
+ await configure({ blocks });
+ },
+ save: async ({ ack, step, update }) => {},
+ execute: async ({ step, complete, fail }) => {},
+});
+```
+
+---
+
+## ステップの設定の保存
+
+ワークフローステップの設定モーダルが開いたら、アプリはワークフロー作成者がモーダルを送信するイベントである `view_submission` イベントを待ち受けます。このイベントを受信すると `WorkflowStep` 設定オブジェクト内の `save` コールバック関数が実行されます。
+
+`save` コールバック関数の中では、以下の引数を渡してステップの設定を保存するための `update()` 関数を利用できます。
+
+- `inputs` は、ワークフローステップ実行時にアプリが受け取ることを期待するデータの内容を表現するオブジェクトです
+- `outputs` は、ステップの実行が正常に完了したとき、同一ワークフロー内の後続のステップに提供するデータの内容を表現するオブジェクトの配列です。
+- `step_name` は、デフォルトのステップ名を上書きするために使用します
+- `step_image_url` は、デフォルトのステップのイメージ画像を上書きするために使用します
+
+これら引数をどのように構成するかの詳細は、[ドキュメント](https://api.slack.com/reference/workflows/workflow_step)を参考にしてください。
+
+```javascript
+const ws = new WorkflowStep('add_task', {
+ edit: async ({ ack, step, configure }) => {},
+ save: async ({ ack, step, view, update }) => {
+ await ack();
+
+ const { values } = view.state;
+ const taskName = values.task_name_input.name;
+ const taskDescription = values.task_description_input.description;
+
+ const inputs = {
+ taskName: { value: taskName.value },
+ taskDescription: { value: taskDescription.value }
+ };
+
+ const outputs = [
+ {
+ type: 'text',
+ name: 'taskName',
+ label: 'Task name',
+ },
+ {
+ type: 'text',
+ name: 'taskDescription',
+ label: 'Task description',
+ }
+ ];
+
+ await update({ inputs, outputs });
+ },
+ execute: async ({ step, complete, fail }) => {},
+});
+```
+
+
+---
+
+## ステップの実行
+
+ワークフローの利用者によって、アプリが提供するカスタムのワークフローステップが実行されるとき、アプリは[`workflow_step_execute`](https://api.slack.com/events/workflow_step_execute) というイベントを受信します。このイベントの受信時に `WorkflowStep` 設定オブジェクト内の `execute` コールバック関数が実行されます。
+
+`save` コールバック関数で予め規定された `inputs` の情報を使って、ここでの処理は、サードパーティの API を呼び出したり、データベースに情報を保存したり、そのユーザーのホームタブを更新したり、`outputs` オブジェクトを構築することで後続のワークフローステップが利用できる情報を設定したりします。
+
+`execute` コールバック関数内では、ステップの実行が成功であることを Slack 側に伝える `complete()` 関数、失敗であることを伝える `fail()` 関数のいずれかを呼び出す必要があります。
+
+```javascript
+const ws = new WorkflowStep('add_task', {
+ edit: async ({ ack, step, configure }) => {},
+ save: async ({ ack, step, update }) => {},
+ execute: async ({ step, complete, fail }) => {
+ const { inputs } = step;
+
+ const outputs = {
+ taskName: inputs.taskName.value,
+ taskDescription: inputs.taskDescription.value,
+ };
+
+ // もし全て OK なら
+ await complete({ outputs });
+ // 注意: processBeforeResponse: true を指定している場合
+ // ここでは await complete() はおすすめしません。呼び出す API の応答が遅いためです。
+ // これにより、3 秒以内に Slack のイベント API に応答することができなくなる場合があります。
+ // 代わりに以下のようにすることができます:
+ // complete({ outputs }).then(() => { console.log('workflow step execution complete registered'); });
+
+ // もし何か問題が起きたら
+ // fail({ error: { message: "Just testing step failure!" } }).then(() => { console.log('workflow step execution failure registered'); });
+ },
+});
+```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/migration-v2.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v2.md
similarity index 71%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/migration-v2.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v2.md
index ec65f0020..e105b15ba 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/migration-v2.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v2.md
@@ -1,18 +1,16 @@
---
title: 2.x マイグレーションガイド
-slug: migration-v2
+slug: /tutorial/migration-v2
lang: ja-jp
---
-# 2.x マイグレーションガイド
+`@slack/bolt@1.x` End of life は **2021 年 4 月 30 日** の予定です。この日からは `@slack/bolt@1.x` の開発は完全に終了となり、残っている open issue や pull request もクローズされます。
このガイドは Bolt 1.x を利用しているアプリを 2.x にアップグレードするための手順について説明します。いくつかの変更が必要とはなりますが、ほとんどのアプリの場合で、おそらく対応に必要な時間は 5 〜 15 分程度です。
-*注: もしすぐにアップグレードをしない場合は、[Bolt 1.x に関するサポートスケジュール](#bolt-1x-%E3%81%AE%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%82%B9%E3%82%B1%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB)をご確認ください*
-
---
-### リスナー関数を `async` 関数に変更 {#upgrading-your-listeners-to-async}
+## リスナー関数を `async` 関数に変更 {#upgrading-your-listeners-to-async}
Bolt アプリ内のリスナー関数は、全て `async` 関数に変更する必要があります。そして、そのリスナー関数内の `say()`、`respond()`、`ack()` メソッドの呼び出しも全て `await` を呼び出しの前につける必要があります。
@@ -34,11 +32,11 @@ app.action('some-action-id', async ({action, ack, say}) => {
})
```
-### エラーハンドリング {#error-handling}
+## エラーハンドリング {#error-handling}
Bolt for JavaScript 2.x では、より多くのユースケースで、必要に応じてエラーをキャッチし、グローバルエラーハンドラーにそれを送るかを制御できるよう改善されました。これまでと同様、グローバルエラーハンドラーに全て任せるよりは、可能な限り、リスナー関数の内部でエラーに対処することをおすすめします。
-#### リスナー関数内で `try`/`catch` 節を用いたエラーハンドリング
+### リスナー関数内で `try`/`catch` 節を用いたエラーハンドリング
```javascript
app.action('some-action-id', async ({action, ack, say, logger}) => {
@@ -52,7 +50,7 @@ app.action('some-action-id', async ({action, ack, say, logger}) => {
})
```
-#### グローバルエラーハンドラーによるエラーハンドリング
+### グローバルエラーハンドラーによるエラーハンドリング
```javascript
app.error(async (error) => {
@@ -66,7 +64,7 @@ app.error(async (error) => {
- リスナー関数が `ack()` メソッドを 3 秒間のうちに呼び出さなかった場合、これまでのように例外を投げるのではなくログを出力するようになりました
- もし一つのイベントに対して複数のリスナー関数を実行中に複数のエラーが発生した場合、Bolt for JavaScript は `ErrorCode.MultipleListenerError` の値での `code` と、発生した個々のエラーの配列を含む `originals` というパラメーターをラップしたエラーを返します
-### メッセージショートカット {#message-shortcuts}
+## メッセージショートカット {#message-shortcuts}
[メッセージショートカット](https://api.slack.com/interactivity/shortcuts/using#message_shortcuts) (以前はメッセージアクションと呼ばれていました)は、これまで `action()` メソッドでハンドリングしていましたが `shortcut()` メソッドを使うようになりました。
@@ -88,7 +86,7 @@ app.shortcut('message-action-callback', async ({shortcut, ack, context}) => {
})
```
-### ミドルウェアに関する変更 {#upgrading-middleware}
+## ミドルウェアに関する変更 {#upgrading-middleware}
もしカスタムのミドルウェアを書いている場合は、その関数を `async` に変更し、さらに `next()` の呼び出しを `await next()` に変更してください。もし後続の処理がある場合は、関数を `next()` に渡す代わりに、その後続の処理を `await next()` の後に実行してください。
@@ -116,10 +114,6 @@ async function noBotMessages({message, next }) {
}
```
-### Bolt 1.x のサポートスケジュール {#slackbolt1x-support-schedule}
-
-`@slack/bolt@1.x` は **2020 年 6 月 30 日** より非推奨となります。それまでの期間はケースバイケースでバグ修正や新機能のバックポートを対応を継続します。`@slack/bolt@1.x` が非推奨となった後は、End of life(正式サポートの終了日)まで **クリティカルなバグ修正のみ** を実装し、クリティカルではない issue や pull request はクローズします。End of life は **2021 年 4 月 30 日** の予定です。この日からは `@slack/bolt@1.x` の開発は完全に終了となり、残っている open issue や pull request もクローズされます。
-
-### TypeScript の最低必須バージョン {#minimum-typescript-version}
+## TypeScript の最低必須バージョン {#minimum-typescript-version}
TypeScript 利用ガイド でも説明していますが、`@slack/bolt@2.x` は TypeScript 3.7 以上が必須バージョンです。
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/migration-v3.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v3.md
similarity index 81%
rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/migration-v3.md
rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v3.md
index 2cea018cc..f644355d1 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/migration-v3.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v3.md
@@ -1,17 +1,16 @@
---
title: 3.x マイグレーションガイド
-slug: migration-v3
+slug: /tutorial/migration-v3
lang: ja-jp
---
-# 3.x マイグレーションガイド
-このガイドは Bolt 2.x を利用しているアプリを 3.x にアップグレードするための手順について説明します。いくつかの変更が必要とはなりますが、ほとんどのアプリの場合で、おそらく対応に必要な時間は 5 〜 15 分程度です。
+`@slack/bolt@2.x` End of life は **2021 年 5 月 31 日** の予定です。この日からは `@slack/bolt@2.x` の開発は完全に終了となり、残っている open issue や pull request もクローズされます。
-*注: もしすぐにアップグレードをしない場合は、[Bolt 2.x に関するサポートスケジュール](#slackbolt2x-support-schedule)をご確認ください*
+このガイドは Bolt 2.x を利用しているアプリを 3.x にアップグレードするための手順について説明します。いくつかの変更が必要とはなりますが、ほとんどのアプリの場合で、おそらく対応に必要な時間は 5 〜 15 分程度です。
---
-### InstallationStore と orgAuthorize での OrG レベルでのインストール対応に関する変更 {#org-wide-app-installation-changes-to-installationstore--orgauthorize}
+## InstallationStore と orgAuthorize での OrG レベルでのインストール対応に関する変更 {#org-wide-app-installation-changes-to-installationstore--orgauthorize}
[Bolt for JavaScript 2.5.0](https://github.com/slackapi/bolt-js/releases/tag/%40slack%2Fbolt%402.5.0) で、私たちは [OrG レベルでのインストール](https://api.slack.com/enterprise/apps)のサポートを追加しました。このサポートをあなたのアプリケーションに追加するには、OAuth フローの中で使用される `fetchOrgInstallation`、`storeOrgInstallation` という二つの新しいメソッドを導入する必要がありました。 3.x では、よりシンプルなインタフェースの実現と Bolt for Python、Bolt for Java との互換性を考慮して、これらの二つの新しいメソッドのサポートを廃止しました。マイグレーションに必要となる変更については以下のコード例を参考にしてください。
@@ -93,18 +92,14 @@ const authorizeFn = async ({ teamId, enterpriseId, isEnterpriseInstall}) => {
}
```
-### デフォルトのレシーバーを HTTPReceiver に変更 {#http-receiver-as-default}
+## デフォルトのレシーバーを HTTPReceiver に変更 {#http-receiver-as-default}
3.x から新しい [`HTTPReceiver`](https://github.com/slackapi/bolt-js/issues/670) というレシーバーを導入し、デフォルトのレシーバー実装を、これまでの `ExpressReceiver` からこのレシーバーに変更します。この変更は、Bolt for JavaScript を Express.js 以外の人気のある Web フレームワーク(Hapi.js や Koa など)とともに動作させることを容易にします。`ExpressReceiver` は引き続き Bolt for JavaScript のリリースに含まれます。また、`HTTPReceiver` は `ExpressReceiver` が提供する全ての機能を提供するわけではありません。例えば、一つのユースケースとしては、`HTTPReceiver` ではカスタムの HTTP ルート(例: ヘルスチェックのための URL を追加する)を追加する機能はサポートされていません。このようなユースケースに対応するためには、引き続き `ExpressReceiver` を利用することを推奨します。その場合はクラスを import して、インスタンス化したものを `App` のコンストラクタに渡してください。詳細は[カスタム HTTP ルートの追加](/concepts/custom-routes)を参考にしてください。
-### Bolt 2.x のサポートスケジュール {#slackbolt2x-support-schedule}
-
-`@slack/bolt@2.x` は **2021 年 1 月 12 日** より非推奨となります。それまでの期間はケースバイケースでバグ修正や新機能のバックポートを対応を継続します。`@slack/bolt@2.x` が非推奨となった後は、End of life(正式サポートの終了日)まで **クリティカルなバグ修正のみ** を実装し、クリティカルではない issue や pull request はクローズします。End of life は **2021 年 5 月 31 日** の予定です。この日からは `@slack/bolt@2.x` の開発は完全に終了となり、残っている open issue や pull request もクローズされます。
-
-### Node の最低必須バージョン {#minimum-node-version}
+## Node の最低必須バージョン {#minimum-node-version}
`@slack/bolt@3.x` は Node は `12.13.0` 以上、npm は `6.12.0` 以上が必須バージョンです。
-### TypeScript の最低必須バージョン {#minimum-typescript-version}
+## TypeScript の最低必須バージョン {#minimum-typescript-version}
TypeScript 利用ガイド でも説明していますが、`@slack/bolt@3.x` は TypeScript 4.1 以上が必須バージョンです。
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/reference.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/reference.md
index 175c11311..c0fbed56a 100644
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/reference.md
+++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/reference.md
@@ -1,25 +1,12 @@
---
-title: リファレンス
+title: リファレンス(Appインターフェイスと設定)
+sidebar_label: リファレンス
slug: reference
permalink: /reference
---
-# リファレンス(Appインターフェイスと設定)
-
このガイドでは、Bolt インターフェイスのリスナー関数、リスナー関数の引数、初期化オプション、エラーについて詳しく説明します。⚡[入門ガイド](/getting-started)をまだ完了していない場合は、先にそちらで Bolt for JavaScript アプリ開発の基本を確認しておきましょう。
-- [リスナー関数](#listener-functions)
- - [メソッド](#methods)
- - [リスナー関数の引数](#listener-function-arguments)
- - [リスナーミドルウェアとの違い](#difference-from-listener-middleware)
-- [初期化オプション](#initialization-options)
- - [レシーバーオプション](#receiver-options)
- - [Appオプション](#app-options)
-- [フレームワークのエラー](#framework-error-types)
- - [クライアント側のエラー](#client-errors)
-
----
-
## リスナー関数 {#listener-functions}
Slack アプリは通常、Slack からのイベント情報を受け取ったり、それに応答を返したりします。受信するイベントは 1 つの場合もあれば、多数の場合もあります。例えば、Events API のイベント(アプリに関連するリンクが共有されたときなど)や、ユーザーがアプリのショートカットを実行するイベントを受け取ったりします。Slack からのリクエストの種類に応じて、それぞれ異なるメソッドが用意されています。これらのメソッドに、それらのイベントを処理したり応答を返したりするための**リスナー関数**を渡します。
@@ -33,7 +20,7 @@ Slack アプリは通常、Slack からのイベント情報を受け取った
| `app.action(actionId, fn);` | Block Kit エレメントから送信される `action` イベントをリッスンします。このイベントにはユーザーのボタン操作、メニュー選択、日付ピッカーの操作などがあります。`actionId` は文字列型で、アプリがビュー内に含めたブロックエレメントに指定した一意の `action_id` の値と一致する必要があります。ここでいう「ビュー」とは、メッセージ、モーダル、アプリのホームタブのことを指します。アクションエレメントを `input` ブロックに配置した場合はイベントがトリガーされないことに注意してください。
| `app.shortcut(callbackId, fn);` | グローバルショートカットまたはメッセージショートカットの呼び出しをリッスンします。`callbackId` は文字列または正規表現で、アプリの設定で指定したショートカットの `callback_id` にマッチする必要があります。
| `app.view(callbackId, fn);` | `view_submission` イベントと `view_closed` イベントをリッスンします。`view_submission` イベントは、アプリが開いたモーダルでユーザーがデータ送信の操作をしたときに発生します。`view_closed` イベントは、ユーザーがデータ送信を実行せずにモーダルを閉じたときに発生します。
-| `app.step(workflowStep)` | `WorkflowStep` のインスタンスに渡されたコールバックを使用して、ワークフローステップイベントのリッスンと応答を行います。コールバックには `edit`、`save`、`execute` の 3 種類があります。ワークフローステップについて詳しくは、[ドキュメント](/concepts/adding-editing-steps)を参照してください。
+| `app.step(workflowStep)` | `WorkflowStep` のインスタンスに渡されたコールバックを使用して、ワークフローステップイベントのリッスンと応答を行います。コールバックには `edit`、`save`、`execute` の 3 種類があります。ワークフローステップについて詳しくは、[ドキュメント](/concepts/steps-from-apps)を参照してください。
| `app.command(commandName, fn);` | Slash コマンドの呼び出しをリッスンします。`commandName` は文字列型で、アプリの設定で指定したスラッシュコマンドと一致する必要があります。スラッシュコマンドの名前では `/` を最初に配置します(例 : `/helpdesk`)。
| `app.options(actionId, fn);` | 外部データソースを使用するセレクトメニューなどから送られる選択肢読み込みのリクエストをリッスンします。使う機会は多くありませんが、`app.action` と混同しないようにしましょう。`actionId` は文字列型で、アプリがビュー内に[外部データソースを使用するセレクトメニュー](https://api.slack.com/reference/block-kit/block-elements#external_select)を含めるときに指定した`action_id` と一致する必要があります。
@@ -120,7 +107,11 @@ App オプションは、`App` のコンストラクターに渡します。`rec
| `deferInitialization` | アプリの初期化を遅延させる真偽値です。有効にすると非同期の `App#init()` メソッドを手動で呼び出す必要があります。 また `init()` メソッドは `App#start()` を実行する前に呼び出さなければなりません。 デフォルトは `false` です。 |
| `signatureVerification` | Boltが着信リクエストでSlackの署名を検証する必要があるかどうかを決定するブール値。 デフォルトは`true`です。 |
-> Bolt のclientは [Node Slack SDK](https://tools.slack.dev/node-slack-sdk) の `WebClient` のインスタンスです。そのため、Node Slack SDK のドキュメントも合わせて参照すると、開発時の理解に役立つでしょう。
+:::tip
+
+Bolt のclientは [Node Slack SDK](https://tools.slack.dev/node-slack-sdk) の `WebClient` のインスタンスです。そのため、Node Slack SDK のドキュメントも合わせて参照すると、開発時の理解に役立つでしょう。
+
+:::
## フレームワークのエラー {#framework-error-types}
@@ -134,7 +125,7 @@ Bolt では、さまざまなエラーが定義されています。これらに
| `ReceiverMultipleAckError` | Receiver 内で、すでに確認が済んでいるリクエストに対してアプリがさらに `ack()` を呼んだ場合にスローされるエラーです。現在、デフォルトの `HTTPReceiver` でのみ使用されます。 |
| `ReceiverAuthenticityError` | アプリのリクエストの署名が検証できないときにスローされるエラーです。このエラーには、失敗した理由を示す情報が含まれます(例 : タイムスタンプが有効でない、ヘッダーに抜けがある、署名シークレットが有効でない)。
| `MultipleListenerError` | 単一のイベントに対して複数のリスナーでの処理中に複数のエラーが発生した場合にスローされるエラーです。個々のエラーを配列に収めた `originals` プロパティを持ちます。 |
-| `WorkflowStepInitializationError` | 新しい `WorkflowStep` をインスタンス化する際に、設定オプションが無効な場合、または不足している場合にスローされるエラーです。原因として、`callback_id` が指定されていない、または設定オブジェクトが指定されていないことが考えられます。ワークフローステップについて詳しくは、[ドキュメント](/concepts/creating-steps)を参照してください。 |
+| `WorkflowStepInitializationError` | 新しい `WorkflowStep` をインスタンス化する際に、設定オプションが無効な場合、または不足している場合にスローされるエラーです。原因として、`callback_id` が指定されていない、または設定オブジェクトが指定されていないことが考えられます。ワークフローステップについて詳しくは、[ドキュメント](/concepts/steps-from-apps)を参照してください。 |
| `UnknownError` | フレームワーク内でスローされる、特定のエラーコードを持たないエラーです。`original` プロパティで詳細を確認できます。 |
> [errors.ts](https://github.com/slackapi/bolt-js/blob/main/src/errors.ts) のコードで、エラー定義の部分とコンストラクターの部分を読み、参考にしてみてください。
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/adding-editing-steps.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/adding-editing-steps.md
deleted file mode 100644
index 376aedaee..000000000
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/adding-editing-steps.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: ステップの追加・編集
-lang: ja-jp
-slug: /concepts/adding-editing-steps
----
-
-ワークフローの作成者が、アプリが提供するステップをワークフローに追加(またはその設定を変更)するタイミングで、アプリは [`workflow_step_edit`](https://api.slack.com/reference/workflows/workflow_step_edit) というイベントを受信します。このイベントの受信時に `WorkflowStep` 設定オブジェクト内の `edit` コールバック関数が実行されます。
-
-このとき、ワークフロー作成・変更のどちらの場合でも、アプリは[ワークフローステップ設定のためのモーダル](https://api.slack.com/reference/workflows/configuration-view)を応答する必要があります。このモーダルは、ワークフローステップに固有の設定である必要があり、通常のモーダルにはない制約があります。最もわかりやすいものとしては、`title`、`submit`、`close` プロパティを設定することができません。また、デフォルトの設定では、この設定モーダルの `callback_id` はワークフローステップのものと同じものが使用されます。
-
-`edit` コールバック関数の中では モーダルの view のうち `blocks` だけを渡すだけで簡単にステップ設定モーダルをオープンすることができる `configure()` というユーティリティ関数が利用できます。これは、必要な入力内容が揃うまで設定の保存を無効にする `submit_disabled` というオプションを `true` に設定します。
-
-設定モーダルを開く処理に関するさらなる詳細は、[ドキュメント](https://api.slack.com/workflows/steps#handle_config_view)を参考にしてください。
-
-```javascript
-const ws = new WorkflowStep('add_task', {
- edit: async ({ ack, step, configure }) => {
- await ack();
-
- const blocks = [
- {
- type: 'input',
- block_id: 'task_name_input',
- element: {
- type: 'plain_text_input',
- action_id: 'name',
- placeholder: {
- type: 'plain_text',
- text: 'Add a task name',
- },
- },
- label: {
- type: 'plain_text',
- text: 'Task name',
- },
- },
- {
- type: 'input',
- block_id: 'task_description_input',
- element: {
- type: 'plain_text_input',
- action_id: 'description',
- placeholder: {
- type: 'plain_text',
- text: 'Add a task description',
- },
- },
- label: {
- type: 'plain_text',
- text: 'Task description',
- },
- },
- ];
-
- await configure({ blocks });
- },
- save: async ({ ack, step, update }) => {},
- execute: async ({ step, complete, fail }) => {},
-});
-```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/creating-steps.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/creating-steps.md
deleted file mode 100644
index 600504501..000000000
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/creating-steps.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: ステップの定義
-lang: ja-jp
-slug: /concepts/creating-steps
----
-
-ワークフローステップを作るための手段として Bolt は `WorkflowStep` というクラスを提供しています。
-
-新しい `WorkflowStep` インスタンスの生成には、そのステップの `callback_id` と設定オブジェクトを渡します。
-
-設定オブジェクトには `edit`、`save`、`execute` という三つのプロパティがあります。これらのそれぞれは単一のコールバック関数、またはコールバック関数の配列である必要があります。すべてのコールバック関数は、ワークフローステップのイベントに関する情報を保持しする `step` オブジェクトにアクセスすることができます。
-
-`WorkflowStep` インスタンスを生成したら、それを `app.step()` メソッドに渡します。これによって、Bolt アプリは対象のワークフローステップのイベントをリッスンしたり、設定オブジェクトが提供するコールバック関数を使ってイベントに応答したりすることができるようになります。
-
-
-```javascript
-const { App, WorkflowStep } = require('@slack/bolt');
-
-// いつも通り Bolt アプリを初期化
-const app = new App({
- signingSecret: process.env.SLACK_SIGNING_SECRET,
- token: process.env.SLACK_BOT_TOKEN,
-});
-
-// WorkflowStep インスタンスを生成
-const ws = new WorkflowStep('add_task', {
- edit: async ({ ack, step, configure }) => {},
- save: async ({ ack, step, update }) => {},
- execute: async ({ step, complete, fail }) => {},
-});
-
-app.step(ws);
-```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/executing-steps.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/executing-steps.md
deleted file mode 100644
index 2bd6660bd..000000000
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/executing-steps.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: ステップの実行
-lang: ja-jp
-slug: /concepts/executing-steps
----
-
-ワークフローの利用者によって、アプリが提供するカスタムのワークフローステップが実行されるとき、アプリは[`workflow_step_execute`](https://api.slack.com/events/workflow_step_execute) というイベントを受信します。このイベントの受信時に `WorkflowStep` 設定オブジェクト内の `execute` コールバック関数が実行されます。
-
-`save` コールバック関数で予め規定された `inputs` の情報を使って、ここでの処理は、サードパーティの API を呼び出したり、データベースに情報を保存したり、そのユーザーのホームタブを更新したり、`outputs` オブジェクトを構築することで後続のワークフローステップが利用できる情報を設定したりします。
-
-`execute` コールバック関数内では、ステップの実行が成功であることを Slack 側に伝える `complete()` 関数、失敗であることを伝える `fail()` 関数のいずれかを呼び出す必要があります。
-
-```javascript
-const ws = new WorkflowStep('add_task', {
- edit: async ({ ack, step, configure }) => {},
- save: async ({ ack, step, update }) => {},
- execute: async ({ step, complete, fail }) => {
- const { inputs } = step;
-
- const outputs = {
- taskName: inputs.taskName.value,
- taskDescription: inputs.taskDescription.value,
- };
-
- // もし全て OK なら
- await complete({ outputs });
- // 注意: processBeforeResponse: true を指定している場合
- // ここでは await complete() はおすすめしません。呼び出す API の応答が遅いためです。
- // これにより、3 秒以内に Slack のイベント API に応答することができなくなる場合があります。
- // 代わりに以下のようにすることができます:
- // complete({ outputs }).then(() => { console.log('workflow step execution complete registered'); });
-
- // もし何か問題が起きたら
- // fail({ error: { message: "Just testing step failure!" } }).then(() => { console.log('workflow step execution failure registered'); });
- },
-});
-```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/saving-steps.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/saving-steps.md
deleted file mode 100644
index 7eda9c243..000000000
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/saving-steps.md
+++ /dev/null
@@ -1,50 +0,0 @@
----
-title: ステップの設定の保存
-lang: ja-jp
-slug: /concepts/saving-steps
----
-
-ワークフローステップの設定モーダルが開いたら、アプリはワークフロー作成者がモーダルを送信するイベントである `view_submission` イベントを待ち受けます。このイベントを受信すると `WorkflowStep` 設定オブジェクト内の `save` コールバック関数が実行されます。
-
-`save` コールバック関数の中では、以下の引数を渡してステップの設定を保存するための `update()` 関数を利用できます。
-
-- `inputs` は、ワークフローステップ実行時にアプリが受け取ることを期待するデータの内容を表現するオブジェクトです
-- `outputs` は、ステップの実行が正常に完了したとき、同一ワークフロー内の後続のステップに提供するデータの内容を表現するオブジェクトの配列です。
-- `step_name` は、デフォルトのステップ名を上書きするために使用します
-- `step_image_url` は、デフォルトのステップのイメージ画像を上書きするために使用します
-
-これら引数をどのように構成するかの詳細は、[ドキュメント](https://api.slack.com/reference/workflows/workflow_step)を参考にしてください。
-
-```javascript
-const ws = new WorkflowStep('add_task', {
- edit: async ({ ack, step, configure }) => {},
- save: async ({ ack, step, view, update }) => {
- await ack();
-
- const { values } = view.state;
- const taskName = values.task_name_input.name;
- const taskDescription = values.task_description_input.description;
-
- const inputs = {
- taskName: { value: taskName.value },
- taskDescription: { value: taskDescription.value }
- };
-
- const outputs = [
- {
- type: 'text',
- name: 'taskName',
- label: 'Task name',
- },
- {
- type: 'text',
- name: 'taskDescription',
- label: 'Task description',
- }
- ];
-
- await update({ inputs, outputs });
- },
- execute: async ({ step, complete, fail }) => {},
-});
-```
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/steps.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/steps.md
deleted file mode 100644
index 405219353..000000000
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/steps.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: ワークフローステップの概要
-lang: ja-jp
-slug: /concepts/steps
----
-
-(アプリによる)ワークフローステップ(Workflow Steps from Apps) は、[ワークフロービルダー](https://api.slack.com/workflows)におけるワークフローに組み込み可能なカスタムのワークフローステップを任意の Slack アプリが提供することを可能とします。
-
-ワークフローステップは、三つの異なるユーザーイベントから構成されます:
-
-- ワークフロー作成者がワークフローにカスタムステップを追加・または編集する
-- ワークフロー作成者がステップの設定を保存・更新する
-- ワークフローの利用者がそのワークフローステップを実行する
-
-ワークフローステップを機能させるためには、これら三つのイベント全てを適切にハンドリングする必要があります。
-
-ワークフローステップのさらなる詳細については [API ドキュメント](https://api.slack.com/workflows/steps)を参考にしてください。
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/getting-started-http.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/getting-started-http.md
deleted file mode 100644
index 6b4dfa8d3..000000000
--- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/getting-started-http.md
+++ /dev/null
@@ -1,324 +0,0 @@
----
-title: Bolt 入門ガイド (HTTP)
-slug: getting-started-http
-lang: ja-jp
----
-
-# Bolt 入門ガイド (HTTP)
-
-このガイドでは、Bolt を使用して Slack アプリを起動し実行する方法について説明します。その過程で、新しい Slack アプリを作成し、ローカル環境を設定し、Slack ワークスペースからのメッセージをリッスンして応答するアプリを開発します。
-
-このガイドが終わったら、あなたはこの⚡️[Getting Started app](https://github.com/slackapi/bolt-js-getting-started-app)を実行したり、修正したり、自分で作ったりすることができます。
-
----
-
-### アプリを作成する {#create-an-app}
-最初にやるべきこと: Bolt で開発を始める前に、 [Slack アプリを作成](https://api.slack.com/apps/new)します。
-
-:::tip
-
-いつもの仕事のさまたげにならないように、別に開発用のワークスペースを使用することをおすすめします — [新しいワークスペースを無料で作成](https://slack.com/get-started#create)できます。
-
-:::
-
-アプリ名を入力し (後で変更可能)、インストール先のワークスペースを選択したら、`Create App` ボタンをクリックすると、アプリの **Basic Information** ページが表示されます。
-
-このページには、後で必要になる重要な認証情報 (**App Credentials** ヘッダーの下の `Signing Secret` など) に加えて、アプリケーションの概要が表示されます。
-
-![Basic Information page](/img/basic-information-page.png "Basic Information page")
-
-ひと通り確認し、アプリのアイコンと説明を追加してから、アプリの設定 🔩 を始めましょう。
-
----
-
-### トークンとアプリのインストール {#tokens-and-installing-apps}
-Slack アプリは、[OAuth を使用して、Slack の API へのアクセスを管理](https://api.slack.com/docs/oauth)します。アプリがインストールされると、トークンを受け取ります。そのトークンを使って、アプリは API メソッドを呼び出すことができます。
-
-Slack アプリで使用できるトークンには、ユーザートークン(`xoxp`)とボットトークン(`xoxb`)、アプリレベルトークン(`xapp`)の 3 種類があります。
-- [ユーザートークン](https://api.slack.com/authentication/token-types#user) を使用すると、アプリをインストールまたは認証したユーザーに成り代わって API メソッドを呼び出すことができます。1 つのワークスペースに複数のユーザートークンが存在する可能性があります。
-- [ボットトークン](https://api.slack.com/authentication/token-types#bot) はボットユーザーに関連づけられ、1 つのワークスペースでは最初に誰かがそのアプリをインストールした際に一度だけ発行されます。どのユーザーがインストールを実行しても、アプリが使用するボットトークンは同じになります。 _ほとんど_ のアプリで使用されるのは、ボットトークンです。
-- [アプリレベルトークン](https://api.slack.com/authentication/token-types#app) は、全ての組織(とその配下のワークスペースでの個々のユーザーによるインストール)を横断して、あなたのアプリを代理するものです。アプリレベルトークンは、アプリの WebSocket コネクションを確立するためによく使われます。
-
-説明を簡潔にするために、このガイドではボットトークンを使用します。
-
-1. 左側のサイドバーの **OAuth & Permissions** にアクセスして、**Bot Token Scopes** までスクロールします。そして、**Add an OAuth Scope** をクリックします。
-
-2. とりあえずは、[`chat:write`](https://api.slack.com/scopes/chat:write) というスコープだけを追加してみましょう。これは、アプリにボットユーザがメンバーとして参加しているチャンネルへのメッセージの投稿を許可するスコープです。
-
-3. ページ上部までスクロールして戻り、**Install App to Workspace** をクリックします。すると、開発用のワークスペースにこのアプリをインストールするための Slack の OAuth 確認画面へと誘導されます。
-
-4. インストールを承認すると、**OAuth & Permissions** ページが表示され、**Bot User OAuth Access Token** を確認することができるはずです。
-
-![OAuth Tokens](/img/bot-token.png "OAuth Tokens")
-
-:::tip
-
-トークンは、パスワードのように大切に扱い、[安全に保管](https://api.slack.com/docs/oauth-safety)してください。アプリではそのトークンを使用して、Slack ワークスペースからの情報を投稿および取得します。
-
-:::
-
----
-
-### ローカルプロジェクトの設定 {#setting-up-your-project}
-初期設定が完了したので、次は新しい Bolt プロジェクトを設定します。ここで、アプリのロジックを処理するコードを記述します。
-
-プロジェクトをまだ作成していない場合は、新しいプロジェクトを作成しましょう。次のように、空のディレクトリを作成して、新しいプロジェクトを初期化します。
-
-```shell
-mkdir first-bolt-app
-cd first-bolt-app
-npm init
-```
-
-新しいプロジェクトを説明するための一連の質問が表示されます (特に問題がなければ、各プロンプトで Enter を押すと、デフォルトを受け入れることができます)。完了すると、ディレクトリ内に新しい `package.json` ファイルが作成されます。
-
-Bolt パッケージを新しいプロジェクトにインストールする前に、アプリの設定時に生成されたボットトークンと signing secret (サイン認証) を保存しましょう。これらは環境変数として保存する必要があります。**バージョン管理では保存しない**でください。
-
-1. **Basic Information ページから Signing Secret をコピー**して、新しい環境変数に保存します。次の例は Linux と macOS で動作します。ただし、[Windows でも同様のコマンドが利用可能](https://superuser.com/questions/212150/how-to-set-env-variable-in-windows-cmd-line/212153#212153)です。
-```shell
-export SLACK_SIGNING_SECRET=
-```
-
-2. **OAuth & Permissions ページからボット (xoxb) トークンをコピー**し、それを別の環境変数に格納します。
-```shell
-export SLACK_BOT_TOKEN=xoxb-
-```
-
-それでは、アプリを作成しましょう。次のコマンドを使用して、`@slack/bolt` パッケージをインストールし、 `package.json` 中で依存ファイルとして保存します。
-
-```shell
-npm install @slack/bolt
-```
-
-このディレクトリ内に `app.js` という名前の新しいファイルを作成し、以下のコードを追加します。
-
-```javascript
-const { App } = require('@slack/bolt');
-
-// ボットトークンとソケットモードハンドラーを使ってアプリを初期化します
-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` ファイルを保存してから、以下のコマンドラインで動かします。
-
-```script
-node app.js
-```
-
-アプリから、起動し実行中であることが通知されます🎉
-
----
-
-### イベントの設定 (HTTP) {#setting-up-events-with-http}
-アプリはボットとしてチームメンバーのように動作し、メッセージを投稿したり、絵文字リアクションを追加したりすることができます。
-
-Slack ワークスペースで発生するイベント (メッセージが投稿されたときや、メッセージに対するリアクションが投稿されたときなど) をリッスンするには、[Events API を使用してイベントタイプに登録](https://api.slack.com/events-api)します。
-
-アプリのイベントを有効にしましょう。
-
-1. アプリのイベントを有効にするには、まずアプリ設定ページに戻ります ([アプリ管理ページ](https://api.slack.com/apps)でアプリをクリックします)。左側のサイドバーにある **Event Subscription** をクリックします。**Enable Events** のスイッチをオンにします。
-
-
-2. Request URLを追加します。Slackはイベントに対応するHTTP POSTリクエストをこの[Request URL](https://api.slack.com/apis/connections/events-api#the-events-api__subscribing-to-event-types__events-api-request-urls)エンドポイントに送信します。Boltは`/slack/events`のパスを使用して、すべての受信リクエスト(ショートカット、イベント、インタラクティビティのペイロードなど)をリッスンします。アプリの設定でRequest URLを設定する際には、`https:///slack/events`のように`/slack/events`を追加します。💡
-
-> ローカル開発では、[ngrok](https://ngrok.com/)のようなプロキシサービスを使って公開 URL を作成し、リクエストを開発環境にトンネリングすることができます。このトンネリングの方法については、[ngrok のガイド](https://ngrok.com/docs#getting-started-expose)を参照してください。
-
-最後に、聞きたいイベントをSlackに伝えましょう。**Event Subscriptions**の下にある、**Enable Events**というラベルの付いたスイッチを切り替えます。
-
-イベントが発生すると、Slack は、そのイベントをトリガーしたユーザーやイベントが発生したチャンネルなど、イベントに関する情報をアプリに送信します。アプリが詳細を処理し、それに応じて応答することができます。
-
-**Request URL** ボックスの **Enable Events** スイッチの下のフィールドにこの URL を貼り付けます。Bolt アプリが引き続き実行されている場合は、URL が検証されチェックマークが表示されます。
-
-Request URL が検証されたら、**Subscribe to Bot Events** までスクロールします。メッセージに関するイベントが4つあります:
-- `message.channels` あなたのアプリが追加されているパブリックチャンネルのメッセージをリッスン
-- `message.groups` あなたのアプリが追加されている🔒プライベートチャンネルのメッセージをリッスン
-- `message.im` あなたのアプリとユーザーのダイレクトメッセージをリッスン
-- `message.mpim` あなたのアプリが追加されているグループ DM をリッスン
-
-もしボットに参加しているすべての場所で全てのメッセージイベントをリッスンさせたいなら、これら4つ全てのイベントを選んでください。選択したら、緑の **Save Changes** ボタンをクリックします。
-
----
-
-### メッセージのリスニングと応答 {#listening-and-responding-to-a-message}
-これで、アプリでいくつかのロジックを設定する準備が整いました。まずは `message()` メソッドを使用して、メッセージのリスナーをアタッチしましょう。
-
-次の例では、あなたのアプリが追加されているチャンネルや DM で `hello` という単語を含むすべてのメッセージをリッスンし、 `Hey there @user!` と応答します。
-
-```javascript
-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` を含むメッセージを送信してみてください。アプリが応答したら成功です。
-
-これは基本的な例ですが、ここから自分の好きなようにアプリをカスタマイズしていくことができます。さらにインタラクティブな動作を試すために、プレーンテキストではなくボタンを送信してみましょう。
-
----
-
-### アクションの送信と応答 {#sending-and-responding-to-actions}
-
-ボタン、選択メニュー、日付ピッカー、モーダルなどの機能を使用するには、インタラクティブ性を有効にする必要があります。イベントと同様に、Slack の URL を指定してアクション ( 「ボタン・クリック」など) を送信する必要があります。
-
-アプリ設定ページに戻り、左側の **Interactivity & Shortcuts** をクリックします。**Request URL** ボックスがもう 1 つあることがわかります。
-
-:::tip
-
-デフォルトでは、Bolt はイベントに使用しているのと同じエンドポイントをインタラクティブコンポーネントに使用するように設定されているため、上記と同じリクエスト URL (この例では `https://8e8ec2d7.ngrok.io/slack/events`) を使用します。右下隅にある **Save Changes** ボタンを押してください。これでアプリのインタラクティブなコンポーネントを利用する設定が有効になりました!
-
-:::
-
-![Configuring a Request URL](/img/request-url-config.png "Configuring a Request URL")
-
-インタラクティブ機能を有効にすると、ショートカット、モーダル、インタラクティブコンポーネント(ボタン、セレクトメニュー、データピッカーなど)とのやり取りがイベントとしてアプリに送信されます。
-
-それでは、アプリのコードに戻り、インタラクティブな処理を追加しましょう。この実装は以下の二つのステップで構成されます。
-- 最初に、アプリからボタンを含むメッセージを送信します。
-- 次に、ユーザーがボタンをクリックしたときの動作をアプリでリッスンし、応答します。
-
-以下は、前のセクションで記述したアプリコードを、文字列だけでなく、ボタン付きのメッセージを送信するように変更したものです。
-
-```javascript
-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` が割り当てられています。これはボタンの一意の識別子として機能するため、アプリはどのアクションに応答するかを指定できます。
-
-:::tip
-
-[Block Kit ビルダー](https://app.slack.com/block-kit-builder)を使うとインタラクティブメッセージを簡単にプロトタイプすることができます。ビルダーを使用すると、ユーザー (またはそのチームメンバー) はメッセージをモックアップして、対応する JSON を生成し、それをアプリに直接貼り付けることができます。
-
-:::
-
-これで、アプリを再起動し、アプリが登録されているチャンネルで `hello` と入力すると、ボタン付きのメッセージが表示されます。ただしこのボタンをクリックしても、まだ何も起こりません。
-
-ボタンがクリックされるとフォローアップメッセージを送信するハンドラーを追加してみましょう。
-
-```javascript
-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 という新しいメッセージがアプリに表示されるはずです。
-
----
-
-### 次のステップ {#next-steps}
-これで最初の Bolt アプリが構築できました! 🎉
-
-基本的なアプリの作成ができましたので、次回は是非もっといろいろな、 Bolt の機能を使ってアプリを作ってみましょう。下記のリンクを辿っていろいろアイデアを模索してみてください!
-
-* 基本的な概念 をお読みください。Bolt アプリからアクセスできるさまざまなメソッドと機能について学ぶことができます。
-
-* ボットが[`events()` メソッド](/concepts/event-listening)でリッスンできるさまざまなイベントを確認しましょう。イベントはすべて[API サイト](https://api.slack.com/events)にリストされています。
-
-* Bolt を使用すると、アプリにアタッチされているクライアントで [Web API メソッドを呼び出す](/concepts/web-api)ことができます。API サイトに [200 を超えるメソッド](https://api.slack.com/methods)を用意してあります。
-
-* 異なるトークンの種類については、[APIサイト](https://api.slack.com/docs/token-types)を参照してください。アプリケーションが実行したいアクションに応じて、異なるトークンが必要になる場合があります。HTTPではなく[Socket Mode](/getting-started)を使用している場合は、`connections:write`スコープを持つ追加の(`xapp`)トークンが必要です。
\ No newline at end of file
diff --git a/docs/i18n/ja-jp/docusaurus-theme-classic/navbar.json b/docs/i18n/ja-jp/docusaurus-theme-classic/navbar.json
index d9ffa7ec8..6d84ae7e9 100644
--- a/docs/i18n/ja-jp/docusaurus-theme-classic/navbar.json
+++ b/docs/i18n/ja-jp/docusaurus-theme-classic/navbar.json
@@ -54,5 +54,9 @@
"item.label.Slack Community": {
"message": "Slack Community",
"description": "Navbar item with label Slack Community"
+ },
+ "logo.alt": {
+ "message": "Slack logo",
+ "description": "The alt text of navbar logo"
}
}
diff --git a/docs/navbarConfig.js b/docs/navbarConfig.js
new file mode 100644
index 000000000..e9deaab7d
--- /dev/null
+++ b/docs/navbarConfig.js
@@ -0,0 +1,89 @@
+const navbar = {
+ title: 'Slack Developer Tools',
+ logo: {
+ src: 'img/slack-logo.svg',
+ href: 'https://tools.slack.dev',
+ },
+ items: [
+ {
+ type: 'dropdown',
+ label: 'Bolt',
+ position: 'left',
+ items: [
+ {
+ label: 'Java',
+ to: 'https://tools.slack.dev/java-slack-sdk/guides/bolt-basics',
+ target: '_self',
+ },
+ {
+ label: 'JavaScript',
+ to: 'https://tools.slack.dev/bolt-js',
+ target: '_self',
+ },
+ {
+ label: 'Python',
+ to: 'https://tools.slack.dev/bolt-python',
+ target: '_self',
+ },
+ ],
+ },
+ {
+ type: 'dropdown',
+ label: 'SDKs',
+ position: 'left',
+ items: [
+ {
+ label: 'Java Slack SDK',
+ to: 'https://tools.slack.dev/java-slack-sdk/',
+ target: '_self',
+ },
+ {
+ label: 'Node Slack SDK',
+ to: 'https://tools.slack.dev/node-slack-sdk/',
+ target: '_self',
+ },
+ {
+ label: 'Python Slack SDK',
+ to: 'https://tools.slack.dev/python-slack-sdk/',
+ target: '_self',
+ },
+ {
+ label: 'Deno Slack SDK',
+ to: 'https://api.slack.com/automation/quickstart',
+ target: '_self',
+ },
+ ],
+ },
+ {
+ type: 'dropdown',
+ label: 'Community',
+ position: 'left',
+ items: [
+ {
+ label: 'Community tools',
+ to: 'https://tools.slack.dev/community-tools',
+ target: '_self',
+ },
+ {
+ label: 'Slack Community',
+ to: 'https://slackcommunity.com/',
+ target: '_self',
+ },
+ ],
+ },
+ {
+ to: 'https://api.slack.com/docs',
+ label: 'API Docs',
+ target: '_self',
+ },
+ {
+ 'aria-label': 'GitHub Repository',
+ className: 'navbar-github-link',
+ href: 'https://github.com/slackapi',
+ position: 'right',
+ target: '_self',
+ },
+ ],
+};
+
+module.exports = navbar;
diff --git a/docs/package-lock.json b/docs/package-lock.json
index fdd0d3fc7..50db73f50 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -11,7 +11,7 @@
"@docusaurus/core": "3.5.2",
"@docusaurus/plugin-client-redirects": "^3.5.2",
"@docusaurus/preset-classic": "3.5.2",
- "@mdx-js/react": "^3.0.0",
+ "@mdx-js/react": "^3.1.0",
"clsx": "^2.0.0",
"css-minimizer-webpack-plugin": "^7.0.0",
"docusaurus-theme-github-codeblock": "^2.0.2",
@@ -22,7 +22,7 @@
"devDependencies": {
"@docusaurus/module-type-aliases": "3.5.2",
"@docusaurus/types": "3.5.2",
- "stylelint": "^16.9.0",
+ "stylelint": "^16.10.0",
"stylelint-config-standard": "^36.0.1"
},
"engines": {
@@ -2947,8 +2947,9 @@
}
},
"node_modules/@mdx-js/react": {
- "version": "3.0.1",
- "license": "MIT",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz",
+ "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==",
"dependencies": {
"@types/mdx": "^2.0.0"
},
@@ -4966,9 +4967,10 @@
}
},
"node_modules/css-functions-list": {
- "version": "3.2.2",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz",
+ "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=12 || >=16"
}
@@ -5692,10 +5694,11 @@
"license": "MIT"
},
"node_modules/debug": {
- "version": "4.3.6",
- "license": "MIT",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -6516,9 +6519,10 @@
}
},
"node_modules/file-entry-cache": {
- "version": "9.0.0",
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.1.0.tgz",
+ "integrity": "sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"flat-cache": "^5.0.0"
},
@@ -6677,8 +6681,9 @@
},
"node_modules/flat-cache": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz",
+ "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"flatted": "^3.3.1",
"keyv": "^4.5.4"
@@ -6689,8 +6694,9 @@
},
"node_modules/flatted": {
"version": "3.3.1",
- "dev": true,
- "license": "ISC"
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
+ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
+ "dev": true
},
"node_modules/follow-redirects": {
"version": "1.15.6",
@@ -7594,8 +7600,9 @@
}
},
"node_modules/http-proxy-middleware": {
- "version": "2.0.6",
- "license": "MIT",
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
+ "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
"dependencies": {
"@types/http-proxy": "^1.17.8",
"http-proxy": "^1.18.1",
@@ -10432,8 +10439,9 @@
}
},
"node_modules/ms": {
- "version": "2.1.2",
- "license": "MIT"
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/multicast-dns": {
"version": "7.2.5",
@@ -10890,8 +10898,9 @@
}
},
"node_modules/picocolors": {
- "version": "1.0.1",
- "license": "ISC"
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
},
"node_modules/picomatch": {
"version": "2.3.1",
@@ -10978,9 +10987,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.44",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.44.tgz",
- "integrity": "sha512-Aweb9unOEpQ3ezu4Q00DPvvM2ZTUitJdNKeP/+uQgr1IBIqu574IaZoURId7BKtWMREwzKa9OgzPzezWGPWFQw==",
+ "version": "8.4.47",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
+ "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"funding": [
{
"type": "opencollective",
@@ -10997,8 +11006,8 @@
],
"dependencies": {
"nanoid": "^3.3.7",
- "picocolors": "^1.0.1",
- "source-map-js": "^1.2.0"
+ "picocolors": "^1.1.0",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
@@ -11451,7 +11460,9 @@
"dev": true
},
"node_modules/postcss-safe-parser": {
- "version": "7.0.0",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz",
+ "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==",
"dev": true,
"funding": [
{
@@ -11467,7 +11478,6 @@
"url": "https://github.com/sponsors/ai"
}
],
- "license": "MIT",
"engines": {
"node": ">=18.0"
},
@@ -12609,11 +12619,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
- "node_modules/send/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- },
"node_modules/send/node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -12930,8 +12935,9 @@
}
},
"node_modules/source-map-js": {
- "version": "1.2.0",
- "license": "BSD-3-Clause",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"engines": {
"node": ">=0.10.0"
}
@@ -13137,9 +13143,9 @@
}
},
"node_modules/stylelint": {
- "version": "16.9.0",
- "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.9.0.tgz",
- "integrity": "sha512-31Nm3WjxGOBGpQqF43o3wO9L5AC36TPIe6030Lnm13H3vDMTcS21DrLh69bMX+DBilKqMMVLian4iG6ybBoNRQ==",
+ "version": "16.10.0",
+ "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.10.0.tgz",
+ "integrity": "sha512-z/8X2rZ52dt2c0stVwI9QL2AFJhLhbPkyfpDFcizs200V/g7v+UYY6SNcB9hKOLcDDX/yGLDsY/pX08sLkz9xQ==",
"dev": true,
"funding": [
{
@@ -13160,17 +13166,17 @@
"balanced-match": "^2.0.0",
"colord": "^2.9.3",
"cosmiconfig": "^9.0.0",
- "css-functions-list": "^3.2.2",
- "css-tree": "^2.3.1",
- "debug": "^4.3.6",
+ "css-functions-list": "^3.2.3",
+ "css-tree": "^3.0.0",
+ "debug": "^4.3.7",
"fast-glob": "^3.3.2",
"fastest-levenshtein": "^1.0.16",
- "file-entry-cache": "^9.0.0",
+ "file-entry-cache": "^9.1.0",
"global-modules": "^2.0.0",
"globby": "^11.1.0",
"globjoin": "^0.1.4",
"html-tags": "^3.3.1",
- "ignore": "^5.3.2",
+ "ignore": "^6.0.2",
"imurmurhash": "^0.1.4",
"is-plain-object": "^5.0.0",
"known-css-properties": "^0.34.0",
@@ -13179,14 +13185,13 @@
"micromatch": "^4.0.8",
"normalize-path": "^3.0.0",
"picocolors": "^1.0.1",
- "postcss": "^8.4.41",
+ "postcss": "^8.4.47",
"postcss-resolve-nested-selector": "^0.1.6",
- "postcss-safe-parser": "^7.0.0",
+ "postcss-safe-parser": "^7.0.1",
"postcss-selector-parser": "^6.1.2",
"postcss-value-parser": "^4.2.0",
"resolve-from": "^5.0.0",
"string-width": "^4.2.3",
- "strip-ansi": "^7.1.0",
"supports-hyperlinks": "^3.1.0",
"svg-tags": "^1.0.0",
"table": "^6.8.2",
@@ -13274,11 +13279,39 @@
}
}
},
+ "node_modules/stylelint/node_modules/css-tree": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.0.0.tgz",
+ "integrity": "sha512-o88DVQ6GzsABn1+6+zo2ct801dBO5OASVyxbbvA2W20ue2puSh/VOuqUj90eUeMSX/xqGqBmOKiRQN7tJOuBXw==",
+ "dev": true,
+ "dependencies": {
+ "mdn-data": "2.10.0",
+ "source-map-js": "^1.0.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
"node_modules/stylelint/node_modules/emoji-regex": {
"version": "8.0.0",
"dev": true,
"license": "MIT"
},
+ "node_modules/stylelint/node_modules/ignore": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz",
+ "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/stylelint/node_modules/mdn-data": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.10.0.tgz",
+ "integrity": "sha512-qq7C3EtK3yJXMwz1zAab65pjl+UhohqMOctTgcqjLOWABqmwj+me02LSsCuEUxnst9X1lCBpoE0WArGKgdGDzw==",
+ "dev": true
+ },
"node_modules/stylelint/node_modules/resolve-from": {
"version": "5.0.0",
"dev": true,
@@ -13311,31 +13344,6 @@
"node": ">=8"
}
},
- "node_modules/stylelint/node_modules/strip-ansi": {
- "version": "7.1.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/stylelint/node_modules/strip-ansi/node_modules/ansi-regex": {
- "version": "6.0.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
"node_modules/supports-color": {
"version": "7.2.0",
"license": "MIT",
diff --git a/docs/package.json b/docs/package.json
index 0d07ca10a..81862610d 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -17,7 +17,7 @@
"@docusaurus/core": "3.5.2",
"@docusaurus/plugin-client-redirects": "^3.5.2",
"@docusaurus/preset-classic": "3.5.2",
- "@mdx-js/react": "^3.0.0",
+ "@mdx-js/react": "^3.1.0",
"clsx": "^2.0.0",
"css-minimizer-webpack-plugin": "^7.0.0",
"docusaurus-theme-github-codeblock": "^2.0.2",
@@ -28,7 +28,7 @@
"devDependencies": {
"@docusaurus/module-type-aliases": "3.5.2",
"@docusaurus/types": "3.5.2",
- "stylelint": "^16.9.0",
+ "stylelint": "^16.10.0",
"stylelint-config-standard": "^36.0.1"
},
"browserslist": {
diff --git a/docs/sidebars.js b/docs/sidebars.js
index 15ae96e45..9bbd80361 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -1,64 +1,62 @@
-/**
- The sidebars can be generated from the filesystem, or explicitly defined here.
- Create as many sidebars as you want.
- */
-
-// @ts-check
-
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
- // By default, Docusaurus generates a sidebar from the docs folder structure
- // tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
-
- // But you can create a sidebar manually
sidebarJSBolt: [
{
type: 'doc',
- id: 'index', // document ID
- label: 'Bolt for JavaScript', // sidebar label
+ id: 'index',
+ label: 'Bolt for JavaScript',
className: 'sidebar-title',
},
'getting-started',
{
type: 'category',
- label: 'Basic concepts',
+ label: 'Slack API calls',
+ items: ['concepts/message-sending', 'concepts/web-api'],
+ },
+ {
+ type: 'category',
+ label: 'Events',
+ items: ['concepts/message-listening', 'concepts/event-listening'],
+ },
+ {
+ type: 'category',
+ label: 'App UI & Interactivity',
items: [
- 'basic/message-listening',
- 'basic/message-sending',
- 'basic/event-listening',
- 'basic/web-api',
- 'basic/action-listening',
- 'basic/action-respond',
- 'basic/acknowledge',
- 'basic/shortcuts',
- 'basic/commands',
- 'basic/creating-modals',
- 'basic/updating-pushing-views',
- 'basic/view-submissions',
- 'basic/publishing-views',
- 'basic/custom-steps',
- 'basic/options',
- 'basic/authenticating-oauth',
- 'basic/socket-mode',
+ 'concepts/acknowledge',
+ 'concepts/shortcuts',
+ 'concepts/commands',
+ 'concepts/actions',
+ 'concepts/creating-modals',
+ 'concepts/updating-pushing-views',
+ 'concepts/view-submissions',
+ 'concepts/select-menu-options',
+ 'concepts/publishing-views',
],
},
+ 'concepts/assistant',
+ 'concepts/custom-steps',
{
type: 'category',
- label: 'Advanced concepts',
+ label: 'App Configuration',
items: [
- 'advanced/error-handling',
- 'advanced/authorization',
- 'advanced/token-rotation',
- 'advanced/conversation-store',
- 'advanced/global-middleware',
- 'advanced/listener-middleware',
- 'advanced/context',
- 'advanced/deferring-initialization',
- 'advanced/logging',
- 'advanced/custom-routes',
- 'advanced/receiver',
+ 'concepts/socket-mode',
+ 'concepts/error-handling',
+ 'concepts/logging',
+ 'concepts/custom-routes',
+ 'concepts/deferring-initialization',
+ 'concepts/receiver',
],
},
+ {
+ type: 'category',
+ label: 'Middleware & Context',
+ items: ['concepts/global-middleware', 'concepts/listener-middleware', 'concepts/context'],
+ },
+ {
+ type: 'category',
+ label: 'Authorization & Security',
+ items: ['concepts/authenticating-oauth', 'concepts/authorization', 'concepts/token-rotation'],
+ },
{
type: 'category',
label: 'Deployments',
@@ -66,26 +64,13 @@ const sidebars = {
},
{
type: 'category',
- label: 'Steps from apps (Deprecated)',
- items: [
- 'steps/steps',
- 'steps/creating-steps',
- 'steps/adding-editing-steps',
- 'steps/saving-steps',
- 'steps/executing-steps',
- ],
+ label: 'Migration Guides',
+ items: ['migration/migration-v2', 'migration/migration-v3', 'migration/migration-v4'],
},
- { type: 'html', value: '
' },
{
type: 'category',
- label: 'Tutorials',
- items: [
- 'tutorial/getting-started-http',
- 'tutorial/hubot-migration',
- 'tutorial/migration-v2',
- 'tutorial/migration-v3',
- 'tutorial/migration-v4',
- ],
+ label: 'Legacy',
+ items: ['legacy/hubot-migration', 'legacy/steps-from-apps', 'legacy/conversation-store'],
},
{ type: 'html', value: '
' },
'reference',
diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css
index 45378d07b..85adb3538 100644
--- a/docs/src/css/custom.css
+++ b/docs/src/css/custom.css
@@ -1,32 +1,16 @@
-/**
- * Any CSS included here will be global. The classic template
- * bundles Infima by default. Infima is a CSS framework designed to
- * work well for content-centric websites.
- */
-
:root {
/* set hex colors here pls */
--aubergine: #4a154b;
-
/* aubergine-active is used in light mode.
use something like #853c8c if you use as a link vs black text ( 3:1 contr) */
--aubergine-active: #7c3085;
-
- /* aubergine-light is used in dark mode. #b681b5 is another one. i just made both up */
- --aubergine-light: #ce70cc;
-
/* horchata is that beige color we use a lot */
--horchata: #f4ede4;
-
- /* slack-blue is 36C5F0. used for dark-mode links */
- --slack-link: #36c5f0;
- --slack-blue: #36c5f0;
+ /* cloud blue from slack.dev. used for dark-mode links */
+ --slack-cloud-blue: #1ab9ff;
/* slack marketing color for links 1264A3. used for light-mode links */
--slack-dark-blue: #1264a3;
-
- --grey: #868686;
--dim: #eef2f6;
- --white: #ffffff;
}
/* resets striped tables that hurt me eyes */
@@ -34,13 +18,13 @@ table tr:nth-child(even) {
background-color: inherit;
}
-p a {
- text-decoration: underline;
+/* changing the links to blue for accessibility */
+p a, .markdown a {
+ color: var(--slack-cloud-blue);
}
-.markdown a {
- color: var(--slack-link);
- text-decoration: underline;
+a:hover {
+ color: var(--slack-cloud-blue);
}
/* adjusting for light and dark modes */
@@ -48,29 +32,41 @@ p a {
--docusaurus-highlighted-code-line-bg: var(--dim);
--ifm-color-primary: var(--aubergine-active);
--ifm-footer-background-color: var(--horchata);
- --slack-link: var(--slack-dark-blue);
+ --ifm-footer-color: black;
+ --slack-cloud-blue: var(--slack-dark-blue);
+ --ifm-table-stripe-background: var(--horchata);
}
[data-theme="dark"] {
- --ifm-color-primary: var(--aubergine-light);
- --ifm-navbar-background-color: var(--aubergine);
- --ifm-footer-background-color: var(--aubergine);
- --slack-link: var(--slack-blue);
-}
-
-html[data-theme="dark"] {
--docusaurus-highlighted-code-line-bg: rgb(0 0 0 / 30%);
+ --ifm-color-primary: var(--slack-cloud-blue);
+ --ifm-navbar-background-color: var(--aubergine) !important;
+ --ifm-footer-background-color: var(--aubergine) !important;
+ --ifm-footer-color: white;
}
-/* bolding Toc for contrast */
+/* bolding ToC for contrast */
.table-of-contents__link--active {
font-weight: bold;
}
-/* only uncomment for home page -- colors white space on v tall screens */
-/* .main-wrapper {
- background: var(--horchata);
-} */
+/* removing ToC line */
+.table-of-contents__left-border {
+ border-left: none !important;
+}
+
+/* increasing name of SDK in sidebar */
+.sidebar-title {
+ font-size: 1.25em; /* Adjust the size as needed */
+ font-weight: bold;
+ color: #000;
+}
+
+/* removing sidebar line and adding space to match ToC */
+.theme-doc-sidebar-container {
+ border-right: none !important;
+ margin-right: 2rem;
+}
/* announcement bar up top */
div[class^="announcementBar_"] {
@@ -79,8 +75,7 @@ div[class^="announcementBar_"] {
background: var(--horchata);
}
-/* navbar */
-
+/* navbar github link */
.navbar-github-link {
width: 32px;
height: 32px;
@@ -108,8 +103,55 @@ html[data-theme="dark"] .navbar-github-link::before {
no-repeat;
}
-.sidebar-title {
- font-size: 1.25em; /* Adjust the size as needed */
- font-weight: bold;
- color: #000;
+/* Delineate tab blocks */
+.tabs-container {
+ border: 1px solid var(--ifm-color-primary); /* Adjust the color and thickness as needed */
+ border-radius: 5px; /* To give rounded corners */
+ padding: 0.5em; /* To add spacing inside the tab */
+}
+
+/* Docs code bubbles */
+[data-theme="light"] {
+ --code-link-background: #CFE9FE;
+ --code-link-text: rgb(21, 50, 59);
+
+ --method-link-background: #CDEFC4;
+ --method-link-text: rgb(0, 41, 0);
+
+ --scope-link-background: #FBF3E0;
+ --scope-link-text: rgb(63, 46, 0);
+
+ --event-link-background: #FDDDE3;
+ --event-link-text: rgb(74, 21, 75);
}
+
+[data-theme="dark"] {
+ --code-link-text: white;
+ --method-link-text: white;
+ --scope-link-text: white;
+ --event-link-text: white;
+ --code-link-background: #1AB9FF50;
+ --method-link-background: #41B65850;
+ --scope-link-background: #FCC00350;
+ --event-link-background: #E3066A50;
+}
+
+a code {
+ background-color: var(--code-link-background);
+ color: var(--code-link-text);
+}
+
+a[href^="https://api.slack.com/methods"] > code {
+ background-color: var(--method-link-background);
+ color: var(--method-link-text);
+}
+
+a[href^="https://api.slack.com/scopes"] > code {
+ background-color: var(--scope-link-background);
+ color: var(--scope-link-text);
+}
+
+a[href^="https://api.slack.com/events"] > code {
+ background-color: var(--event-link-background);
+ color: var(--event-link-text);
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index dbe421d9c..0ff1e3110 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@slack/bolt",
- "version": "4.0.0",
+ "version": "4.1.0",
"description": "A framework for building Slack apps, fast.",
"author": "Slack Technologies, LLC",
"license": "MIT",
@@ -58,7 +58,7 @@
"@tsconfig/node18": "^18.2.4",
"@types/chai": "^4.1.7",
"@types/mocha": "^10.0.1",
- "@types/node": "22.7.7",
+ "@types/node": "22.8.7",
"@types/sinon": "^7.0.11",
"@types/tsscmp": "^1.0.0",
"c8": "^10.1.2",
diff --git a/src/Assistant.ts b/src/Assistant.ts
index 15e37aa07..14d817d19 100644
--- a/src/Assistant.ts
+++ b/src/Assistant.ts
@@ -3,6 +3,7 @@ import type {
AssistantThreadsSetSuggestedPromptsResponse,
AssistantThreadsSetTitleResponse,
ChatPostMessageArguments,
+ MessageMetadataEventPayloadObject,
} from '@slack/web-api';
import {
type AssistantThreadContext,
@@ -44,11 +45,16 @@ type SetSuggestedPromptsFn = (
) => Promise;
interface SetSuggestedPromptsArguments {
+ /** @description Prompt suggestions that appear when opening assistant thread. */
prompts: [AssistantPrompt, ...AssistantPrompt[]];
+ /** @description Title for the prompts. */
+ title?: string;
}
interface AssistantPrompt {
+ /** @description Title of the prompt. */
title: string;
+ /** @description Message of the prompt. */
message: string;
}
@@ -301,12 +307,20 @@ export async function processAssistantMiddleware(
*/
function createSay(args: AllAssistantMiddlewareArgs): SayFn {
const { client, payload } = args;
- const { channelId: channel, threadTs: thread_ts } = extractThreadInfo(payload);
+ const { channelId: channel, threadTs: thread_ts, context } = extractThreadInfo(payload);
- return (message: Parameters[0]) => {
+ return async (message: Parameters[0]) => {
+ const threadContext = context.channel_id ? context : await args.getThreadContext(args);
const postMessageArgument: ChatPostMessageArguments =
typeof message === 'string' ? { text: message, channel, thread_ts } : { ...message, channel, thread_ts };
+ if (threadContext) {
+ postMessageArgument.metadata = {
+ event_type: 'assistant_thread_context',
+ event_payload: threadContext as MessageMetadataEventPayloadObject,
+ };
+ }
+
return client.chat.postMessage(postMessageArgument);
};
}
@@ -336,11 +350,12 @@ function createSetSuggestedPrompts(args: AllAssistantMiddlewareArgs): SetSuggest
const { channelId: channel_id, threadTs: thread_ts } = extractThreadInfo(payload);
return (params: Parameters[0]) => {
- const { prompts } = params;
+ const { prompts, title } = params;
return client.assistant.threads.setSuggestedPrompts({
channel_id,
thread_ts,
prompts,
+ title,
});
};
}
@@ -375,7 +390,11 @@ export function extractThreadInfo(payload: AllAssistantMiddlewareArgs['payload']
let context: AssistantThreadContext = {};
// assistant_thread_started, asssistant_thread_context_changed
- if ('assistant_thread' in payload) {
+ if (
+ 'assistant_thread' in payload &&
+ 'channel_id' in payload.assistant_thread &&
+ 'thread_ts' in payload.assistant_thread
+ ) {
channelId = payload.assistant_thread.channel_id;
threadTs = payload.assistant_thread.thread_ts;
context = payload.assistant_thread.context;
diff --git a/test/unit/Assistant.spec.ts b/test/unit/Assistant.spec.ts
index bbd52f8f6..40dc4b24f 100644
--- a/test/unit/Assistant.spec.ts
+++ b/test/unit/Assistant.spec.ts
@@ -208,7 +208,9 @@ describe('Assistant class', () => {
const mockThreadContextStore = createMockThreadContextStore();
const { enrichAssistantArgs } = await importAssistant();
// TODO: enrichAssistantArgs likely needs a different argument type, as AssistantMiddlewareArgs type already has the assistant utility enrichments present.
- const assistantArgs = enrichAssistantArgs(mockThreadContextStore, { payload } as AllAssistantMiddlewareArgs);
+ const assistantArgs = enrichAssistantArgs(mockThreadContextStore, {
+ payload,
+ } as AllAssistantMiddlewareArgs);
assert.exists(assistantArgs.say);
assert.exists(assistantArgs.setStatus);
@@ -221,7 +223,9 @@ describe('Assistant class', () => {
const mockThreadContextStore = createMockThreadContextStore();
const { enrichAssistantArgs } = await importAssistant();
// TODO: enrichAssistantArgs likely needs a different argument type, as AssistantMiddlewareArgs type already has the assistant utility enrichments present.
- const assistantArgs = enrichAssistantArgs(mockThreadContextStore, { payload } as AllAssistantMiddlewareArgs);
+ const assistantArgs = enrichAssistantArgs(mockThreadContextStore, {
+ payload,
+ } as AllAssistantMiddlewareArgs);
assert.exists(assistantArgs.say);
assert.exists(assistantArgs.setStatus);
@@ -234,7 +238,9 @@ describe('Assistant class', () => {
const mockThreadContextStore = createMockThreadContextStore();
const { enrichAssistantArgs } = await importAssistant();
// TODO: enrichAssistantArgs likely needs a different argument type, as AssistantMiddlewareArgs type already has the assistant utility enrichments present.
- const assistantArgs = enrichAssistantArgs(mockThreadContextStore, { payload } as AllAssistantMiddlewareArgs);
+ const assistantArgs = enrichAssistantArgs(mockThreadContextStore, {
+ payload,
+ } as AllAssistantMiddlewareArgs);
assert.exists(assistantArgs.say);
assert.exists(assistantArgs.setStatus);
@@ -306,6 +312,56 @@ describe('Assistant class', () => {
sinon.assert.called(fakeClient.chat.postMessage);
});
+ it('say should be called with message_metadata that includes thread context', async () => {
+ const mockThreadStartedArgs = wrapMiddleware(createDummyAssistantThreadStartedEventMiddlewareArgs());
+
+ const fakeClient = { chat: { postMessage: sinon.spy() } };
+ mockThreadStartedArgs.client = fakeClient as unknown as WebClient;
+ const mockThreadContextStore = createMockThreadContextStore();
+
+ const { enrichAssistantArgs } = await importAssistant();
+ const threadStartedArgs = enrichAssistantArgs(mockThreadContextStore, mockThreadStartedArgs);
+
+ await threadStartedArgs.say('Say called!');
+
+ const {
+ payload: {
+ assistant_thread: { channel_id, thread_ts, context },
+ },
+ } = mockThreadStartedArgs;
+
+ const expectedParams = {
+ text: 'Say called!',
+ channel: channel_id,
+ thread_ts,
+ metadata: {
+ event_type: 'assistant_thread_context',
+ event_payload: context,
+ },
+ };
+
+ sinon.assert.calledWith(fakeClient.chat.postMessage, expectedParams);
+ });
+
+ it('say should get context from store if no thread context is included in event', async () => {
+ const mockThreadStartedArgs = wrapMiddleware(createDummyAssistantThreadStartedEventMiddlewareArgs());
+ mockThreadStartedArgs.payload.assistant_thread.context = {};
+
+ const fakeClient = { chat: { postMessage: sinon.spy() } };
+ mockThreadStartedArgs.client = fakeClient as unknown as WebClient;
+ const mockThreadContextStore = { save: sinon.spy(), get: sinon.spy() };
+
+ const { enrichAssistantArgs } = await importAssistant();
+ const threadStartedArgs = enrichAssistantArgs(mockThreadContextStore, mockThreadStartedArgs);
+
+ // Verify that get is not called prior to say being used
+ sinon.assert.notCalled(mockThreadContextStore.get);
+
+ await threadStartedArgs.say('Say called!');
+
+ sinon.assert.calledOnce(mockThreadContextStore.get);
+ });
+
it('setStatus should call assistant.threads.setStatus', async () => {
const mockThreadStartedArgs = wrapMiddleware(createDummyAssistantThreadStartedEventMiddlewareArgs());
@@ -331,7 +387,7 @@ describe('Assistant class', () => {
const { enrichAssistantArgs } = await importAssistant();
const threadStartedArgs = enrichAssistantArgs(mockThreadContextStore, mockThreadStartedArgs);
- await threadStartedArgs.setSuggestedPrompts({ prompts: [{ title: '', message: '' }] });
+ await threadStartedArgs.setSuggestedPrompts({ prompts: [{ title: '', message: '' }], title: '' });
sinon.assert.called(fakeClient.assistant.threads.setSuggestedPrompts);
});
diff --git a/test/unit/helpers/events.ts b/test/unit/helpers/events.ts
index 5fc3c7a1a..d632b6539 100644
--- a/test/unit/helpers/events.ts
+++ b/test/unit/helpers/events.ts
@@ -353,7 +353,7 @@ export function createDummyCustomFunctionMiddlewareArgs<
options?: Options;
} = { callbackId: 'reverse', inputs: { stringToReverse: 'hello' }, options: { autoAcknowledge: true } as Options },
): SlackCustomFunctionMiddlewareArgs {
- data.callbackId = data.callbackId ? data.callbackId : 'reverse';
+ data.callbackId = data.callbackId || 'reverse';
data.inputs = data.inputs ? data.inputs : { stringToReverse: 'hello' };
data.options = data.options ? data.options : ({ autoAcknowledge: true } as Options);
const testFunction = {