From 6b3a43012ed3c713fe3b0d36ff3ad38964e21d2b Mon Sep 17 00:00:00 2001 From: Luke Russell Date: Thu, 24 Oct 2024 18:20:45 -0700 Subject: [PATCH 1/7] docs: reorg nav --- .../{basic => concepts}/acknowledge.md | 0 .../{basic => concepts}/action-listening.md | 0 .../{basic => concepts}/action-respond.md | 0 .../authenticating-oauth.md | 0 .../{advanced => concepts}/authorization.md | 0 docs/content/{basic => concepts}/commands.md | 0 .../content/{advanced => concepts}/context.md | 0 .../conversation-store.md | 0 .../{basic => concepts}/creating-modals.md | 0 .../{advanced => concepts}/custom-routes.md | 0 .../{basic => concepts}/custom-steps.md | 1 + .../deferring-initialization.md | 0 .../{advanced => concepts}/error-handling.md | 0 .../{basic => concepts}/event-listening.md | 2 +- .../global-middleware.md | 0 .../listener-middleware.md | 0 .../content/{advanced => concepts}/logging.md | 0 .../{basic => concepts}/message-listening.md | 0 .../{basic => concepts}/message-sending.md | 0 docs/content/{basic => concepts}/options.md | 0 .../{basic => concepts}/publishing-views.md | 0 .../{advanced => concepts}/receiver.md | 0 docs/content/{basic => concepts}/shortcuts.md | 0 .../{basic => concepts}/socket-mode.md | 0 .../{advanced => concepts}/token-rotation.md | 0 .../updating-pushing-views.md | 0 .../{basic => concepts}/view-submissions.md | 0 docs/content/{basic => concepts}/web-api.md | 2 +- ...getting-started.md => getting-started.mdx} | 206 ++++++++++- docs/content/steps/adding-editing-steps.md | 70 ---- docs/content/steps/creating-steps.md | 42 --- docs/content/steps/executing-steps.md | 49 --- docs/content/steps/saving-steps.md | 60 ---- docs/content/steps/steps.md | 177 +++++++++- docs/content/tutorial/getting-started-http.md | 326 ------------------ docs/docusaurus.config.js | 11 +- docs/sidebars.js | 154 ++++----- 37 files changed, 454 insertions(+), 646 deletions(-) rename docs/content/{basic => concepts}/acknowledge.md (100%) rename docs/content/{basic => concepts}/action-listening.md (100%) rename docs/content/{basic => concepts}/action-respond.md (100%) rename docs/content/{basic => concepts}/authenticating-oauth.md (100%) rename docs/content/{advanced => concepts}/authorization.md (100%) rename docs/content/{basic => concepts}/commands.md (100%) rename docs/content/{advanced => concepts}/context.md (100%) rename docs/content/{advanced => concepts}/conversation-store.md (100%) rename docs/content/{basic => concepts}/creating-modals.md (100%) rename docs/content/{advanced => concepts}/custom-routes.md (100%) rename docs/content/{basic => concepts}/custom-steps.md (99%) rename docs/content/{advanced => concepts}/deferring-initialization.md (100%) rename docs/content/{advanced => concepts}/error-handling.md (100%) rename docs/content/{basic => concepts}/event-listening.md (96%) rename docs/content/{advanced => concepts}/global-middleware.md (100%) rename docs/content/{advanced => concepts}/listener-middleware.md (100%) rename docs/content/{advanced => concepts}/logging.md (100%) rename docs/content/{basic => concepts}/message-listening.md (100%) rename docs/content/{basic => concepts}/message-sending.md (100%) rename docs/content/{basic => concepts}/options.md (100%) rename docs/content/{basic => concepts}/publishing-views.md (100%) rename docs/content/{advanced => concepts}/receiver.md (100%) rename docs/content/{basic => concepts}/shortcuts.md (100%) rename docs/content/{basic => concepts}/socket-mode.md (100%) rename docs/content/{advanced => concepts}/token-rotation.md (100%) rename docs/content/{basic => concepts}/updating-pushing-views.md (100%) rename docs/content/{basic => concepts}/view-submissions.md (100%) rename docs/content/{basic => concepts}/web-api.md (96%) rename docs/content/{getting-started.md => getting-started.mdx} (69%) delete mode 100644 docs/content/steps/adding-editing-steps.md delete mode 100644 docs/content/steps/creating-steps.md delete mode 100644 docs/content/steps/executing-steps.md delete mode 100644 docs/content/steps/saving-steps.md delete mode 100644 docs/content/tutorial/getting-started-http.md diff --git a/docs/content/basic/acknowledge.md b/docs/content/concepts/acknowledge.md similarity index 100% rename from docs/content/basic/acknowledge.md rename to docs/content/concepts/acknowledge.md diff --git a/docs/content/basic/action-listening.md b/docs/content/concepts/action-listening.md similarity index 100% rename from docs/content/basic/action-listening.md rename to docs/content/concepts/action-listening.md diff --git a/docs/content/basic/action-respond.md b/docs/content/concepts/action-respond.md similarity index 100% rename from docs/content/basic/action-respond.md rename to docs/content/concepts/action-respond.md diff --git a/docs/content/basic/authenticating-oauth.md b/docs/content/concepts/authenticating-oauth.md similarity index 100% rename from docs/content/basic/authenticating-oauth.md rename to docs/content/concepts/authenticating-oauth.md diff --git a/docs/content/advanced/authorization.md b/docs/content/concepts/authorization.md similarity index 100% rename from docs/content/advanced/authorization.md rename to docs/content/concepts/authorization.md diff --git a/docs/content/basic/commands.md b/docs/content/concepts/commands.md similarity index 100% rename from docs/content/basic/commands.md rename to docs/content/concepts/commands.md diff --git a/docs/content/advanced/context.md b/docs/content/concepts/context.md similarity index 100% rename from docs/content/advanced/context.md rename to docs/content/concepts/context.md diff --git a/docs/content/advanced/conversation-store.md b/docs/content/concepts/conversation-store.md similarity index 100% rename from docs/content/advanced/conversation-store.md rename to docs/content/concepts/conversation-store.md diff --git a/docs/content/basic/creating-modals.md b/docs/content/concepts/creating-modals.md similarity index 100% rename from docs/content/basic/creating-modals.md rename to docs/content/concepts/creating-modals.md diff --git a/docs/content/advanced/custom-routes.md b/docs/content/concepts/custom-routes.md similarity index 100% rename from docs/content/advanced/custom-routes.md rename to docs/content/concepts/custom-routes.md diff --git a/docs/content/basic/custom-steps.md b/docs/content/concepts/custom-steps.md similarity index 99% rename from docs/content/basic/custom-steps.md rename to docs/content/concepts/custom-steps.md index 495745551..324d1ddda 100644 --- a/docs/content/basic/custom-steps.md +++ b/docs/content/concepts/custom-steps.md @@ -1,5 +1,6 @@ --- title: Listening and responding to custom steps +sidebar_label: Custom Steps lang: en slug: /concepts/custom-steps --- diff --git a/docs/content/advanced/deferring-initialization.md b/docs/content/concepts/deferring-initialization.md similarity index 100% rename from docs/content/advanced/deferring-initialization.md rename to docs/content/concepts/deferring-initialization.md diff --git a/docs/content/advanced/error-handling.md b/docs/content/concepts/error-handling.md similarity index 100% rename from docs/content/advanced/error-handling.md rename to docs/content/concepts/error-handling.md diff --git a/docs/content/basic/event-listening.md b/docs/content/concepts/event-listening.md similarity index 96% rename from docs/content/basic/event-listening.md rename to docs/content/concepts/event-listening.md index b71ad2298..721bca121 100644 --- a/docs/content/basic/event-listening.md +++ b/docs/content/concepts/event-listening.md @@ -4,7 +4,7 @@ lang: en slug: /concepts/event-listening --- -You can listen to [any Events API event](https://api.slack.com/events) using the `event()` method after subscribing to it in your app configuration. This allows your app to take action when something happens in Slack, like a user reacting to a message or joining a channel. +You can listen to any [Events API event](https://api.slack.com/events) using the `event()` method after subscribing to it in your app configuration. This allows your app to take action when something happens in Slack, like a user reacting to a message or joining a channel. The `event()` method requires an `eventType` of type string. diff --git a/docs/content/advanced/global-middleware.md b/docs/content/concepts/global-middleware.md similarity index 100% rename from docs/content/advanced/global-middleware.md rename to docs/content/concepts/global-middleware.md diff --git a/docs/content/advanced/listener-middleware.md b/docs/content/concepts/listener-middleware.md similarity index 100% rename from docs/content/advanced/listener-middleware.md rename to docs/content/concepts/listener-middleware.md diff --git a/docs/content/advanced/logging.md b/docs/content/concepts/logging.md similarity index 100% rename from docs/content/advanced/logging.md rename to docs/content/concepts/logging.md diff --git a/docs/content/basic/message-listening.md b/docs/content/concepts/message-listening.md similarity index 100% rename from docs/content/basic/message-listening.md rename to docs/content/concepts/message-listening.md diff --git a/docs/content/basic/message-sending.md b/docs/content/concepts/message-sending.md similarity index 100% rename from docs/content/basic/message-sending.md rename to docs/content/concepts/message-sending.md diff --git a/docs/content/basic/options.md b/docs/content/concepts/options.md similarity index 100% rename from docs/content/basic/options.md rename to docs/content/concepts/options.md diff --git a/docs/content/basic/publishing-views.md b/docs/content/concepts/publishing-views.md similarity index 100% rename from docs/content/basic/publishing-views.md rename to docs/content/concepts/publishing-views.md diff --git a/docs/content/advanced/receiver.md b/docs/content/concepts/receiver.md similarity index 100% rename from docs/content/advanced/receiver.md rename to docs/content/concepts/receiver.md diff --git a/docs/content/basic/shortcuts.md b/docs/content/concepts/shortcuts.md similarity index 100% rename from docs/content/basic/shortcuts.md rename to docs/content/concepts/shortcuts.md diff --git a/docs/content/basic/socket-mode.md b/docs/content/concepts/socket-mode.md similarity index 100% rename from docs/content/basic/socket-mode.md rename to docs/content/concepts/socket-mode.md diff --git a/docs/content/advanced/token-rotation.md b/docs/content/concepts/token-rotation.md similarity index 100% rename from docs/content/advanced/token-rotation.md rename to docs/content/concepts/token-rotation.md diff --git a/docs/content/basic/updating-pushing-views.md b/docs/content/concepts/updating-pushing-views.md similarity index 100% rename from docs/content/basic/updating-pushing-views.md rename to docs/content/concepts/updating-pushing-views.md diff --git a/docs/content/basic/view-submissions.md b/docs/content/concepts/view-submissions.md similarity index 100% rename from docs/content/basic/view-submissions.md rename to docs/content/concepts/view-submissions.md diff --git a/docs/content/basic/web-api.md b/docs/content/concepts/web-api.md similarity index 96% rename from docs/content/basic/web-api.md rename to docs/content/concepts/web-api.md index c6c2f27cd..0e1b3cdbe 100644 --- a/docs/content/basic/web-api.md +++ b/docs/content/concepts/web-api.md @@ -4,7 +4,7 @@ lang: en slug: /concepts/web-api --- -You can call [any Web API method](https://api.slack.com/methods) using the [`WebClient`](https://tools.slack.dev/node-slack-sdk/web-api) provided to your app's listeners as `client`. This uses either the token that initialized your app **or** the token that is returned from the [`authorize`](/concepts/authorization) function for the incoming event. The built-in [OAuth support](/concepts/authenticating-oauth) handles the second case by default. +You can call any [Web API method](https://api.slack.com/methods) using the [`WebClient`](https://tools.slack.dev/node-slack-sdk/web-api) provided to your app's listeners as `client`. This uses either the token that initialized your app **or** the token that is returned from the [`authorize`](/concepts/authorization) function for the incoming event. The built-in [OAuth support](/concepts/authenticating-oauth) handles the second case by default. Your Bolt app also has a top-level `app.client` which you can manually pass the `token` parameter. If the incoming request is not authorized or you're calling a method from outside of a listener, use the top-level `app.client`. diff --git a/docs/content/getting-started.md b/docs/content/getting-started.mdx similarity index 69% rename from docs/content/getting-started.md rename to docs/content/getting-started.mdx index be5d6f037..a8910320d 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.mdx @@ -1,6 +1,6 @@ --- title: Getting started with Bolt for JavaScript -sidebar_label: Getting started +sidebar_label: Getting Started --- This guide is meant to walk you through getting up and running with a Slack app using Bolt for JavaScript. Along the way, we’ll create a new Slack app, set up your local environment, and develop an app that listens and responds to messages from a Slack workspace. @@ -40,7 +40,7 @@ We're going to use bot and app tokens for this guide. 1. Navigate to the **OAuth & Permissions** on the left sidebar and scroll down to the **Bot Token Scopes** section. Click **Add an OAuth Scope**. -2. For now, we'll just add one scope: [`chat:write`](https://api.slack.com/scopes/chat:write). This grants your app the permission to post messages in channels it's a member of. +2. For now, we'll just add one scope: [`chat:write`](https://api.slack.com/scopes/chat:write). This scope grants your app the permission to post messages in channels it's a member of. 3. Scroll up to the top of the OAuth & Permissions page and click **Install App to Workspace**. You'll be led through Slack's OAuth UI, where you should allow your app to be installed to your development workspace. @@ -72,6 +72,7 @@ You’ll be prompted with a series of questions to describe your new project (yo Before we install the Bolt for JavaScript package to your new project, let's save the **bot token** and **Signing Secret** that were generated when you configured your app. 1. **Copy your Signing Secret from the Basic Information page** and then store it in a new environment variable. The following example works on Linux and macOS; but [similar commands are available on Windows](https://superuser.com/questions/212150/how-to-set-env-variable-in-windows-cmd-line/212153#212153). + ```shell export SLACK_SIGNING_SECRET= ``` @@ -126,15 +127,19 @@ Your app should let you know that it's up and running. 🎉 ## Setting up events {#setting-up-events} Your app behaves similarly to people on your team — it can post messages, add emoji reactions, and listen and respond to events. -To listen for events happening in a Slack workspace (like when a message is posted or when a reaction is posted to a message) you'll use the [Events API to subscribe to event types](https://api.slack.com/events-api). For this guide, we are going to be using [Socket Mode](https://api.slack.com/apis/connections/socket), our recommended option for those just getting started and building something for their team. +To listen for events happening in a Slack workspace (like when a message is posted or when a reaction is posted to a message) you'll use the [Events API to subscribe to event types](https://api.slack.com/events-api). -:::tip +For those just starting, we recommend using [Socket Mode](https://api.slack.com/apis/connections/socket). Socket Mode allows your app to use the Events API and interactive features without exposing a public HTTP Request URL. This can be helpful during development, or if you're receiving requests from behind a firewall. -Socket Mode lets apps use the Events API and interactive components without exposing a public HTTP endpoint. This can be helpful during development, or if you're receiving requests from behind a firewall. HTTP is more useful for apps being deployed to hosting environments (like [AWS](/deployments/aws-lambda) or [Heroku](/deployments/heroku)), or apps intended for distribution via the Slack App Directory. To continue this setting up guide with HTTP, head over [here](/tutorial/getting-started-http#setting-up-events-with-http). +That being said, you're welcome to set up an app with a public HTTP Request URL. HTTP is more useful for apps being deployed to hosting environments (like [AWS](/deployments/aws-lambda) or [Heroku](/deployments/heroku)), or apps intended for distribution via the Slack App Directory. -::: +We've provided instructions for both ways in this guide. -Okay, let's enable Socket Mode: +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + 1. Head to your app's configuration page (click on the app [from your app management page](https://api.slack.com/apps)). Navigate to **Socket Mode** on the left side menu and toggle to enable. @@ -144,6 +149,23 @@ Finally, it's time to tell Slack what events we'd like to listen for. Under **Ev 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. + + + +1. Go back to your app configuration page (click on the app from your [app management page](https://api.slack.com/apps)). Click **Event Subscriptions** on the left sidebar. Toggle the switch labeled **Enable Events**. + +2. Add your Request URL. Slack will send HTTP POST requests corresponding to events to this [Request URL](https://api.slack.com/apis/connections/events-api#the-events-api__subscribing-to-event-types__events-api-request-urls) endpoint. Bolt uses the `/slack/events` path to listen to all incoming requests (whether shortcuts, events, or interactivity payloads). When configuring your Request URL within your app configuration, you'll append `/slack/events`, e.g. `https:///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. + +::: + + + + + 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 @@ -153,13 +175,17 @@ Scroll down to **Subscribe to Bot Events**. There are four events related to mes 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. + + + + Back in your project, make sure to store the `xapp` token you saved earlier in your environment. ```shell export SLACK_APP_TOKEN=xapp- ``` -Make a simple change to your Bolt initialization code and restart the app. +Change your Bolt initialization code and restart the app. ```javascript // Initializes your app in socket mode with your app token and signing secret @@ -171,6 +197,9 @@ const app = new App({ }); ``` + + + --- ## Listening and responding to a message {#listening-and-responding-to-a-message} @@ -178,6 +207,10 @@ Your app is now ready for some logic. Let's start by using the `message()` metho 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'); @@ -205,6 +238,34 @@ 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, +}); + +// 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. @@ -215,11 +276,22 @@ This is a basic example, but it gives you a place to start customizing your app To use features like buttons, select menus, datepickers, modals, and shortcuts, you’ll need to enable interactivity. Head over to **Interactivity & Shortcuts** in your app configuration. -:::tip -You'll notice that with Socket Mode on, basic interactivity is enabled for us by default, so no further action here is needed. If you're using HTTP, you'll need to supply a [Request URL](https://api.slack.com/apis/connections/events-api#the-events-api__subscribing-to-event-types__events-api-request-urls) for Slack to send events to. + + -::: +With Socket Mode on, basic interactivity is enabled for us by default, so no further action here is needed + + + + +Similar to events, you'll need to specify a Request URL for Slack to send the action (such as *user clicked a button*). + + +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. @@ -229,6 +301,9 @@ Now, let’s go back to your app’s code and add logic to handle those events: 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'); @@ -275,6 +350,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 +}); + +// 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. @@ -289,23 +411,79 @@ Now, if you restart your app and say "hello" in a channel your app is in, you'll Let's add a handler to send a followup message when someone clicks the button: + + + ```js reference https://github.com/slackapi/bolt-js-getting-started-app/blob/main/app.js ``` + + + + ```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 `sample_button`. 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) with Socket Mode! 🎉 +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 pages to learn about the different methods and features your Bolt app has access to. +* Read through the concepts pages 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()`](/concepts/event-listening) method. 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. For apps that do not use Socket Mode, typically only a bot (`xoxb`) token is required. For example of this, see [Getting Started with HTTP](/tutorial/getting-started-http). \ No newline at end of file +* 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. \ No newline at end of file diff --git a/docs/content/steps/adding-editing-steps.md b/docs/content/steps/adding-editing-steps.md deleted file mode 100644 index 0622d17a4..000000000 --- a/docs/content/steps/adding-editing-steps.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: Adding or editing steps from apps -lang: en -slug: /concepts/adding-editing-steps ---- - -:::danger - -Steps from Apps are a deprecated feature. - -Steps from Apps are different than, and not interchangeable with, Slack automation workflows. We encourage those who are currently publishing steps from apps to consider the new [Slack automation features](https://api.slack.com/automation), such as [custom steps for Bolt](https://api.slack.com/automation/functions/custom-bolt). - -Please [read the Slack API changelog entry](https://api.slack.com/changelog/2023-08-workflow-steps-from-apps-step-back) for more information. - -::: - -When a builder adds (or later edits) your step in their workflow, your app will receive a [`workflow_step_edit` event](https://api.slack.com/reference/workflows/workflow_step_edit). The `edit` callback in your `WorkflowStep` configuration will be run when this event is received. - -Whether a builder is adding or editing a step, you need to send them a [step from app configuration modal](https://api.slack.com/reference/workflows/configuration-view). This modal is where step-specific settings are chosen, and it has more restrictions than typical modals—most notably, it cannot include `title​`, `submit​`, or `close`​ properties. By default, the configuration modal's `callback_id` will be the same as the step from app. - -Within the `edit` callback, the `configure()` utility can be used to easily open your step's configuration modal by passing in an object with your view's `blocks`. To disable saving the configuration before certain conditions are met, pass in `submit_disabled` with a value of `true`. - -To learn more about opening configuration modals, [read the documentation](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 }) => {}, -}); -``` diff --git a/docs/content/steps/creating-steps.md b/docs/content/steps/creating-steps.md deleted file mode 100644 index f39714ede..000000000 --- a/docs/content/steps/creating-steps.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Creating steps from apps -lang: en -slug: /concepts/creating-steps ---- - -:::danger - -Steps from Apps are a deprecated feature. - -Steps from Apps are different than, and not interchangeable with, Slack automation workflows. We encourage those who are currently publishing steps from apps to consider the new [Slack automation features](https://api.slack.com/automation), such as [custom steps for Bolt](https://api.slack.com/automation/functions/custom-bolt). - -Please [read the Slack API changelog entry](https://api.slack.com/changelog/2023-08-workflow-steps-from-apps-step-back) for more information. - -::: - -To create a step from app, Bolt provides the `WorkflowStep` class. - -When instantiating a new `WorkflowStep`, pass in the step's `callback_id` and a configuration object. - -The configuration object contains three properties: `edit`, `save`, and `execute`. Each of these properties must be a single callback or an array of callbacks. All callbacks have access to a `step` object that contains information about the step from app event. - -After instantiating a `WorkflowStep`, you can pass it into `app.step()`. Behind the scenes, your app will listen and respond to the step’s events using the callbacks provided in the configuration object. - -```javascript -const { App, WorkflowStep } = require('@slack/bolt'); - -// Initiate the Bolt app as you normally would -const app = new App({ - signingSecret: process.env.SLACK_SIGNING_SECRET, - token: process.env.SLACK_BOT_TOKEN, -}); - -// Create a new WorkflowStep instance -const ws = new WorkflowStep('add_task', { - edit: async ({ ack, step, configure }) => {}, - save: async ({ ack, step, update }) => {}, - execute: async ({ step, complete, fail }) => {}, -}); - -app.step(ws); -``` diff --git a/docs/content/steps/executing-steps.md b/docs/content/steps/executing-steps.md deleted file mode 100644 index 55194cecb..000000000 --- a/docs/content/steps/executing-steps.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Executing steps from apps -lang: en -slug: /concepts/executing-steps ---- - -:::danger - -Steps from Apps are a deprecated feature. - -Steps from Apps are different than, and not interchangeable with, Slack automation workflows. We encourage those who are currently publishing steps from apps to consider the new [Slack automation features](https://api.slack.com/automation), such as [custom steps for Bolt](https://api.slack.com/automation/functions/custom-bolt). - -Please [read the Slack API changelog entry](https://api.slack.com/changelog/2023-08-workflow-steps-from-apps-step-back) for more information. - -::: - -When your step from app is executed by an end user, your app will receive a [`workflow_step_execute` event](https://api.slack.com/events/workflow_step_execute). The `execute` callback in your `WorkflowStep` configuration will be run when this event is received. - -Using the `inputs` from the `save` callback, this is where you can make third-party API calls, save information to a database, update the user's Home tab, or decide the outputs that will be available to subsequent steps by mapping values to the `outputs` object. - -Within the `execute` callback, your app must either call `complete()` to indicate that the step's execution was successful, or `fail()` to indicate that the step's execution failed. - -```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, - }; - - // signal back to Slack that everything was successful - await complete({ outputs }); - // NOTE: If you run your app with processBeforeResponse: true option, - // `await complete()` is not recommended because of the slow response of the API endpoint - // which could result in not responding to the Slack Events API within the required 3 seconds - // instead, use: - // complete({ outputs }).then(() => { console.log('step from app execution complete registered'); }); - - // let Slack know if something went wrong - // await fail({ error: { message: "Just testing step failure!" } }); - // NOTE: If you run your app with processBeforeResponse: true, use this instead: - // fail({ error: { message: "Just testing step failure!" } }).then(() => { console.log('step from app execution failure registered'); }); - }, -}); -``` diff --git a/docs/content/steps/saving-steps.md b/docs/content/steps/saving-steps.md deleted file mode 100644 index 5f3e4a4ba..000000000 --- a/docs/content/steps/saving-steps.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: Saving step configurations -lang: en -slug: /concepts/saving-steps ---- - -:::danger - -Steps from Apps are a deprecated feature. - -Steps from Apps are different than, and not interchangeable with, Slack automation workflows. We encourage those who are currently publishing steps from apps to consider the new [Slack automation features](https://api.slack.com/automation), such as [custom steps for Bolt](https://api.slack.com/automation/functions/custom-bolt). - -Please [read the Slack API changelog entry](https://api.slack.com/changelog/2023-08-workflow-steps-from-apps-step-back) for more information. - -::: - -After the configuration modal is opened, your app will listen for the `view_submission` event. The `save` callback in your `WorkflowStep` configuration will be run when this event is received. - -Within the `save` callback, the `update()` method can be used to save the builder's step configuration by passing in the following arguments: - -- `inputs` is an object representing the data your app expects to receive from the user upon step from app execution. -- `outputs` is an array of objects containing data that your app will provide upon the step's completion. Outputs can then be used in subsequent steps of the workflow. -- `step_name` overrides the default Step name -- `step_image_url` overrides the default Step image - -To learn more about how to structure these parameters, [read the documentation](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 }) => {}, -}); -``` diff --git a/docs/content/steps/steps.md b/docs/content/steps/steps.md index f344894f3..398a10183 100644 --- a/docs/content/steps/steps.md +++ b/docs/content/steps/steps.md @@ -1,12 +1,12 @@ --- -title: Overview of steps from apps +title: Steps from Apps lang: en slug: /concepts/steps --- :::danger -Steps from Apps are a deprecated feature. +Steps from Apps is a deprecated feature. Steps from Apps are different than, and not interchangeable with, Slack automation workflows. We encourage those who are currently publishing steps from apps to consider the new [Slack automation features](https://api.slack.com/automation), such as [custom steps for Bolt](https://api.slack.com/automation/functions/custom-bolt). @@ -14,8 +14,6 @@ Please [read the Slack API changelog entry](https://api.slack.com/changelog/2023 ::: ---- - Steps from apps allow your app to create and process steps that users can add using [Workflow Builder](https://api.slack.com/workflows). A step from app is made up of three distinct user events: @@ -27,3 +25,174 @@ A step from app is made up of three distinct user events: All three events must be handled for a step from app to function. Read more about steps from apps in the [API documentation](https://api.slack.com/legacy/workflows/steps). + +--- + +## Creating steps from apps + +To create a step from app, Bolt provides the `WorkflowStep` class. + +When instantiating a new `WorkflowStep`, pass in the step's `callback_id` and a configuration object. + +The configuration object contains three properties: `edit`, `save`, and `execute`. Each of these properties must be a single callback or an array of callbacks. All callbacks have access to a `step` object that contains information about the step from app event. + +After instantiating a `WorkflowStep`, you can pass it into `app.step()`. Behind the scenes, your app will listen and respond to the step’s events using the callbacks provided in the configuration object. + +```javascript +const { App, WorkflowStep } = require('@slack/bolt'); + +// Initiate the Bolt app as you normally would +const app = new App({ + signingSecret: process.env.SLACK_SIGNING_SECRET, + token: process.env.SLACK_BOT_TOKEN, +}); + +// Create a new WorkflowStep instance +const ws = new WorkflowStep('add_task', { + edit: async ({ ack, step, configure }) => {}, + save: async ({ ack, step, update }) => {}, + execute: async ({ step, complete, fail }) => {}, +}); + +app.step(ws); +``` + +## Adding or editing steps from apps + +When a builder adds (or later edits) your step in their workflow, your app will receive a [`workflow_step_edit` event](https://api.slack.com/reference/workflows/workflow_step_edit). The `edit` callback in your `WorkflowStep` configuration will be run when this event is received. + +Whether a builder is adding or editing a step, you need to send them a [step from app configuration modal](https://api.slack.com/reference/workflows/configuration-view). This modal is where step-specific settings are chosen, and it has more restrictions than typical modals—most notably, it cannot include `title​`, `submit​`, or `close`​ properties. By default, the configuration modal's `callback_id` will be the same as the step from app. + +Within the `edit` callback, the `configure()` utility can be used to easily open your step's configuration modal by passing in an object with your view's `blocks`. To disable saving the configuration before certain conditions are met, pass in `submit_disabled` with a value of `true`. + +To learn more about opening configuration modals, [read the documentation](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 }) => {}, +}); +``` + +## Saving step configurations + +After the configuration modal is opened, your app will listen for the `view_submission` event. The `save` callback in your `WorkflowStep` configuration will be run when this event is received. + +Within the `save` callback, the `update()` method can be used to save the builder's step configuration by passing in the following arguments: + +- `inputs` is an object representing the data your app expects to receive from the user upon step from app execution. +- `outputs` is an array of objects containing data that your app will provide upon the step's completion. Outputs can then be used in subsequent steps of the workflow. +- `step_name` overrides the default Step name +- `step_image_url` overrides the default Step image + +To learn more about how to structure these parameters, [read the documentation](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 }) => {}, +}); +``` + +## Executing steps from apps + +When your step from app is executed by an end user, your app will receive a [`workflow_step_execute` event](https://api.slack.com/events/workflow_step_execute). The `execute` callback in your `WorkflowStep` configuration will be run when this event is received. + +Using the `inputs` from the `save` callback, this is where you can make third-party API calls, save information to a database, update the user's Home tab, or decide the outputs that will be available to subsequent steps by mapping values to the `outputs` object. + +Within the `execute` callback, your app must either call `complete()` to indicate that the step's execution was successful, or `fail()` to indicate that the step's execution failed. + +```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, + }; + + // signal back to Slack that everything was successful + await complete({ outputs }); + // NOTE: If you run your app with processBeforeResponse: true option, + // `await complete()` is not recommended because of the slow response of the API endpoint + // which could result in not responding to the Slack Events API within the required 3 seconds + // instead, use: + // complete({ outputs }).then(() => { console.log('step from app execution complete registered'); }); + + // let Slack know if something went wrong + // await fail({ error: { message: "Just testing step failure!" } }); + // NOTE: If you run your app with processBeforeResponse: true, use this instead: + // fail({ error: { message: "Just testing step failure!" } }).then(() => { console.log('step from app execution failure registered'); }); + }, +}); +``` diff --git a/docs/content/tutorial/getting-started-http.md b/docs/content/tutorial/getting-started-http.md deleted file mode 100644 index 8be737eb3..000000000 --- a/docs/content/tutorial/getting-started-http.md +++ /dev/null @@ -1,326 +0,0 @@ ---- -title: Getting started with Bolt for JavaScript and HTTP -slug: getting-started-http -lang: en ---- - -This guide is meant to walk you through getting up and running with a Slack app using Bolt for JavaScript. Along the way, we’ll create a new Slack app, set up your local environment, and develop an app that listens and responds to messages from a Slack workspace. - -When you’re finished, you’ll have this ⚡[Getting Started app](https://github.com/slackapi/bolt-js-getting-started-app) to run, modify, and make your own. - ---- - -### Create an app {#create-an-app} -First thing's first: before you start developing with Bolt, you'll want to [create a Slack app](https://api.slack.com/apps/new). - -:::tip - -We recommend using a workspace where you won't disrupt real work getting done — [you can create a new one for free](https://slack.com/get-started#create). - -::: - -After you fill out an app name (_you can change it later_) and pick a workspace to install it to, hit the `Create App` button and you'll land on your app's **Basic Information** page. - -This page contains an overview of your app in addition to important credentials you'll need later, like the `Signing Secret` under the **App Credentials** header. - -![Basic Information page](/img/basic-information-page.png "Basic Information page") - -Look around, add an app icon and description, and then let's start configuring your app. 🔩 - ---- - -### Tokens and installing apps {#tokens-and-installing-apps} -Slack apps use [OAuth to manage access to Slack's APIs](https://api.slack.com/docs/oauth). When an app is installed, you'll receive a token that the app can use to call API methods. - -There are three main token types available to a Slack app: user (`xoxp`), bot (`xoxb`), and app (`xapp`) tokens. -- [User tokens](https://api.slack.com/authentication/token-types#user) allow you to call API methods on behalf of users after they install or authenticate the app. There may be several user tokens for a single workspace. -- [Bot tokens](https://api.slack.com/authentication/token-types#bot) are associated with bot users, and are only granted once in a workspace where someone installs the app. The bot token your app uses will be the same no matter which user performed the installation. Bot tokens are the token type that _most_ apps use. -- [App-level tokens](https://api.slack.com/authentication/token-types#app) represent your app across organizations, including installations by all individual users on all workspaces in a given organization and are commonly used for creating websocket connections to your app. - -For brevity, we're going to use bot tokens for this guide. - -1. Navigate to the **OAuth & Permissions** on the left sidebar and scroll down to the **Bot Token Scopes** section. Click **Add an OAuth Scope**. - -2. For now, we'll just add one scope: [`chat:write`](https://api.slack.com/scopes/chat:write). This grants your app the permission to post messages in channels it's a member of. - -3. Scroll up to the top of the OAuth & Permissions page and click **Install App to Workspace**. You'll be led through Slack's OAuth UI, where you should allow your app to be installed to your development workspace. - -4. Once you authorize the installation, you'll land on the **OAuth & Permissions** page and see a **Bot User OAuth Access Token**. - -![OAuth Tokens](/img/bot-token.png "Bot OAuth Token") - -:::tip - -Treat your token like a password and [keep it safe](https://api.slack.com/docs/oauth-safety). Your app uses it to post and retrieve information from Slack workspaces. - -::: - ---- - -### Setting up your project {#setting-up-your-project} -With the initial configuration handled, it's time to set up a new Bolt project. This is where you'll write the code that handles the logic for your app. - -If you don’t already have a project, let’s create a new one. Create an empty directory and initialize a new project: - -```shell -mkdir first-bolt-app -cd first-bolt-app -npm init -``` - -You’ll be prompted with a series of questions to describe your new project (you can accept the defaults by hitting Enter on each prompt if you aren’t picky). After you’re done, you’ll have a new `package.json` file in your directory. - -Before we install the Bolt for JavaScript package to your new project, let's save the **bot token** and **Signing Secret** that were generated when you configured your app. - -1. **Copy your Signing Secret from the Basic Information page** and then store it in a new environment variable. The following example works on Linux and macOS; but [similar commands are available on Windows](https://superuser.com/questions/212150/how-to-set-env-variable-in-windows-cmd-line/212153#212153). - -```shell -export SLACK_SIGNING_SECRET= -``` - -2. **Copy your bot (xoxb) token from the OAuth & Permissions page** and store it in another environment variable. -```shell -export SLACK_BOT_TOKEN=xoxb- -``` - -:::warning - -Remember to keep your token and signing secret secure. At a minimum, you should avoid checking them into public version control, and access them via environment variables as we've done above. Checkout the API documentation for more on [best practices for app security](https://api.slack.com/authentication/best-practices). - -::: - -Now, let's create your app. Install the `@slack/bolt` package and save it to your `package.json` dependencies using the following command: - -```shell -npm install @slack/bolt -``` - -Create a new entrypoint file called `app.js` in this directory and add the following code: - -```javascript -const { App } = require('@slack/bolt'); - -// Initializes your app with your bot token and signing secret -const app = new App({ - token: process.env.SLACK_BOT_TOKEN, - signingSecret: process.env.SLACK_SIGNING_SECRET -}); - -(async () => { - // Start your app - await app.start(process.env.PORT || 3000); - - console.log('⚡ Bolt app is running!'); -})(); -``` - -Save your `app.js` file, then on the command line run the following: - -```script -node app.js -``` - -Your app should let you know that it's up and running. 🎉 - ---- - -### Setting up events with HTTP {#setting-up-events-with-http} -Your app behaves similarly to people on your team — it can post messages, add emoji reactions, and listen and respond to events. - -To listen for events happening in a Slack workspace (like when a message is posted or when a reaction is posted to a message) you'll use the [Events API to subscribe to event types](https://api.slack.com/events-api). - -Let's enable events for your app: - -1. Go back to your app configuration page (click on the app from your [app management page](https://api.slack.com/apps)). Click **Event Subscriptions** on the left sidebar. Toggle the switch labeled **Enable Events**. - -2. Add your Request URL. Slack will send HTTP POST requests corresponding to events to this [Request URL](https://api.slack.com/apis/connections/events-api#the-events-api__subscribing-to-event-types__events-api-request-urls) endpoint. Bolt uses the `/slack/events` path to listen to all incoming requests (whether shortcuts, events, or interactivity payloads). When configuring your Request URL within your app configuration, you'll append `/slack/events`, e.g. `https:///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..9700d0cb5 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -57,7 +57,16 @@ const config = { redirects: [ { to: '/getting-started', - from: ['/tutorial/getting-started'], + from: ['/tutorial/getting-started','/tutorial/getting-started-http'], + }, + { + to: '/concepts/steps', + from: [ + '/concepts/creating-steps', + '/concepts/adding-editing-steps', + '/concepts/saving-steps', + '/concepts/executing-steps' + ], }, { to: '/', diff --git a/docs/sidebars.js b/docs/sidebars.js index 15ae96e45..7af0d2800 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -1,109 +1,107 @@ -/** - 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 - className: 'sidebar-title', + type: "doc", + id: "index", + label: "Bolt for JavaScript", + className: "sidebar-title", + }, + "getting-started", + { + type: "category", + label: "Slack API calls", + items: ["concepts/message-sending", "concepts/web-api"], + }, + { + type: "category", + label: "Events", + items: ["concepts/message-listening", "concepts/event-listening"], }, - 'getting-started', { - type: 'category', - label: 'Basic concepts', + type: "category", + label: "Interactivity & Shortcuts", 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/action-listening", + "concepts/action-respond", + "concepts/creating-modals", + "concepts/updating-pushing-views", + "concepts/view-submissions", + "concepts/options", + "concepts/publishing-views", ], }, + "concepts/custom-steps", { - type: 'category', - label: 'Advanced concepts', + type: "category", + 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: 'Deployments', - items: ['deployments/aws-lambda', 'deployments/heroku'], + type: "category", + label: "Middleware & Context", + items: [ + "concepts/global-middleware", + "concepts/listener-middleware", + "concepts/context", + ], }, { - type: 'category', - label: 'Steps from apps (Deprecated)', + type: "category", + label: "Authorization & Security", items: [ - 'steps/steps', - 'steps/creating-steps', - 'steps/adding-editing-steps', - 'steps/saving-steps', - 'steps/executing-steps', + "concepts/authorization", + "concepts/authenticating-oauth", + "concepts/token-rotation", + "concepts/conversation-store", ], }, - { type: 'html', value: '
' }, { - type: 'category', - label: 'Tutorials', + type: "category", + label: "Deployments", + items: ["deployments/aws-lambda", "deployments/heroku"], + }, + { + type: "category", + label: "Migration Guides", items: [ - 'tutorial/getting-started-http', - 'tutorial/hubot-migration', - 'tutorial/migration-v2', - 'tutorial/migration-v3', - 'tutorial/migration-v4', + "tutorial/migration-v2", + "tutorial/migration-v3", + "tutorial/migration-v4", ], }, - { type: 'html', value: '
' }, - 'reference', - { type: 'html', value: '
' }, { - type: 'link', - label: 'Release notes', - href: 'https://github.com/slackapi/bolt-js/releases', + type: "category", + label: "Legacy", + items: ["tutorial/hubot-migration", "steps/steps"], + }, + { type: "html", value: "
" }, + "reference", + { type: "html", value: "
" }, + { + type: "link", + label: "Release notes", + href: "https://github.com/slackapi/bolt-js/releases", }, { - type: 'link', - label: 'Code on GitHub', - href: 'https://github.com/SlackAPI/bolt-js', + type: "link", + label: "Code on GitHub", + href: "https://github.com/SlackAPI/bolt-js", }, { - type: 'link', - label: 'Contributors Guide', - href: 'https://github.com/SlackAPI/bolt-js/blob/main/.github/contributing.md', + type: "link", + label: "Contributors Guide", + href: "https://github.com/SlackAPI/bolt-js/blob/main/.github/contributing.md", }, ], }; From 5cbb4f820fc1955ed188b6b2b33bebc58ab0eb62 Mon Sep 17 00:00:00 2001 From: Luke Russell Date: Thu, 24 Oct 2024 18:25:28 -0700 Subject: [PATCH 2/7] docs: added assistant --- docs/content/concepts/assistant.md | 186 +++++++++++++++++++++++++++++ docs/sidebars.js | 1 + 2 files changed, 187 insertions(+) create mode 100644 docs/content/concepts/assistant.md diff --git a/docs/content/concepts/assistant.md b/docs/content/concepts/assistant.md new file mode 100644 index 000000000..ae89ad35a --- /dev/null +++ b/docs/content/concepts/assistant.md @@ -0,0 +1,186 @@ +--- +title: Agents & Assistants +lang: en +slug: /concepts/assistant +--- + +:::info[This feature requires a paid plan] +If you don't have a paid workspace for development, you can join the [Developer Program](https://api.slack.com/developer-program) and provision a sandbox with access to all Slack features for free. +::: + +Agents and assistants comprise a new messaging experience for Slack. If you're unfamiliar with using agents and assistants within Slack, you'll want to read the [API documentation on the subject](https://api.slack.com/docs/apps/ai). Then, come back here to implement them with Bolt! + +## Configuring your app to support assistants + +1. Within [App Settings](https://api.slack.com/apps), enable the **Agents & Assistants** feature. + +2. Within the App Settings **OAuth & Permissions** page, add the following scopes: + * [`assistant:write`](https://api.slack.com/scopes/assistant:write) + * [`chat:write`](https://api.slack.com/scopes/chat:write) + * [`im:history`](https://api.slack.com/scopes/im:history) + +3 Within the App Settings **Event Subscriptions** page, subscribe to the following events: + * [`assistant_thread_started`](https://api.slack.com/events/assistant_thread_started) + * [`assistant_thread_context_changed`](https://api.slack.com/events/assistant_thread_context_changed) + * [`message.im`](https://api.slack.com/events/message.im) + +:::info +You _could_ implement your own assistants by [listening](/concepts/event-listening) for the `assistant_thread_started`, `assistant_thread_context_changed`, and `message.im` events. That being said, using the `Assistant` class will streamline the process. And we already wrote this nice guide for you! +::: + +## The `Assistant` class + +### Instance template + +```ts +const assistant = new Assistant({ + threadContextStore: { + get: async ({ context, client, payload }) => {}, + save: async ({ context, client, payload }) => {}, + }, + threadStarted: async ({ say, saveThreadContext, setStatus, setSuggestedPrompts, setTitle }) => {}, + threadContextChanged: async ({ say, setStatus, setSuggestedPrompts, setTitle }) => {}, + userMessage: async ({ say, getThreadContext, setStatus, setSuggestedPrompts, setTitle }) => {}, +}); +``` + +### The `AssistantConfig` configuration object + +| Property | Required? | Description | +|---|---|---| +|`threadContextStore` | Optional, but recommended | When provided, must have the required methods to get and save thread context, which will override the `getThreadContext` and `saveThreadContext` utilities.

If not provided, a `DefaultAssistantContextStore` instance is used. +| `threadStarted` | Required | Executes when the user opens the assistant container or otherwise begins a new chat, thus sending the [`assistant_thread_started`](https://api.slack.com/events/assistant_thread_started) event. +| `threadContextChanged` | Optional | Executes when a user switches channels while the assistant container is open, thus sending the [`assistant_thread_context_changed`](https://api.slack.com/events/assistant_thread_context_changed) event.

If not provided, context will be saved using the AssistantContextStore's `save` method (either the `DefaultAssistantContextStore` instance or provided `threadContextStore`). +| `userMessage` | Required | Executes when a [message](https://api.slack.com/events/message), thus sending the [`message.im`](https://api.slack.com/events/message.im) event. These messages do not contain a subtype and must be deduced based on their shape and metadata (if provided). Bolt handles this deduction out of the box for those using the `Assistant` class. + +### Utilities + +Utility | Description +|---|---| +| `getThreadContext` | Alias for `AssistantContextStore.get()` method. Executed if custom `AssistantContextStore` value is provided.

If not provided, the `DefaultAssistantContextStore` instance will retrieve the most recent context saved to the instance. +| `saveThreadContext` | Alias for `AssistantContextStore.save()`. Executed if `AssistantContextStore` value is provided.

If not provided, the `DefaultAssistantContextStore` instance will save the `assistant_thread.context` to the instance and attach it to the initial assistant message that was sent to the thread. +| `say(message: string)` | Alias for the `postMessage` method.

Sends a message to the current assistant thread. +| `setTitle(title: string)` | [Sets the title](https://api.slack.com/methods/assistant.threads.setTitle) of the assistant thread to capture the initial topic/question. +| `setStatus(status: string)` | Sets the [status](https://api.slack.com/methods/assistant.threads.setStatus) of the assistant to give the appearance of active processing. +| `setSuggestedPrompts({ prompts: [{ title: string; message: string; }]` | Provides the user up to 4 optional, preset [prompts](https://api.slack.com/methods/assistant.threads.setSuggestedPrompts) to choose from. + +## Handling a new thread + +The `threadStarted` event handler allows your app to respond to new threads opened by users. In the example below, the app is sending a message — containing context message metadata — to the user, along with a single [prompt](https://api.slack.com/methods/assistant.threads.setSuggestedPrompts). + +```js +const assistant = new Assistant({ + threadStarted: async ({ event, say, setSuggestedPrompts, saveThreadContext }) => { + const { context } = event.assistant_thread; + + await say({ + text: 'Hi, how can I help?', + metadata: { event_type: 'assistant_thread_context', event_payload: context }, + }); + + await saveThreadContext(); + + const prompts = [{ + title: 'Fun Slack fact', + message: 'Give me a fun fact about Slack, please!', + }]; + + // Provide the user up to 4 optional, preset prompts to choose from. + await setSuggestedPrompts({ prompts }); + }, +... +``` + +:::tip +When a user opens an assistant thread while in a channel, the channel info is stored as the thread's `AssistantThreadContext` data. You can grab that info using the `getThreadContext()` utility, as subsequent user message event payloads won't include the channel info. +::: + + +## Handling context changes + +You can store context through the `threadContextStore` property but it must feature `get` and `save` methods. + +```js +threadContextStore: { + get: async ({ context, client, payload }) => {}, + save: async ({ context, client, payload }) => {}, + }, +``` + +If not provided, a `DefaultThreadContextStore` instance is utilized instead, which is a reference implementation that relies on storing and retrieving message metadata as the context changes. + +When the user switches channels, the `assistant_thread_context_changed` event will be sent to your app. Capture this with the `threadContextChanged` handler. + +```js +... + threadContextChanged: async ({ saveThreadContext }) => { + await saveThreadContext(); + }, +... +``` + +If you use the built-in `AssistantThreadContextStore` without any custom configuration the updated context data is automatically saved as message metadata on the first reply from the assistant bot. + +## Handling the user response + +User messages are handled with the `userMessage` event handler. The `setTitle` and `setStatus` utilities are useful in curating the user experience. + +:::warning +Messages sent to the assistant do not contain a subtype and must be deduced based on their shape and any provided metadata. +::: + + ```js + ... + userMessage: async ({ client, message, say, setTitle, setStatus }) => { + const { channel, thread_ts } = message; + + // Set the title of the Assistant thread to capture the initial topic/question + await setTitle(message.text); + + // Set the status of the Assistant to give the appearance of active processing. + await setStatus('is typing..'); + + // Retrieve the Assistant thread history for context of question being asked + const thread = await client.conversations.replies({ + channel, + ts: thread_ts, + oldest: thread_ts, + }); + + // Prepare and tag each message for LLM processing + const userMessage = { role: 'user', content: message.text }; + const threadHistory = thread.messages.map((m) => { + const role = m.bot_id ? 'assistant' : 'user'; + return { role, content: m.text }; + }); + + const messages = [ + { role: 'system', content: DEFAULT_SYSTEM_CONTENT }, + ...threadHistory, + userMessage, + ]; + + // Send message history and newest question to LLM + const llmResponse = await openai.chat.completions.create({ + model: 'gpt-4o-mini', + n: 1, + messages, + }); + + // Provide a response to the user + await say(llmResponse.choices[0].message.content); + }, +}); + +app.assistant(assistant); +``` + +## Full example + +
+App Agent & Assistant Template + +```js reference title="app.js" +https://github.com/slack-samples/bolt-js-assistant-template/blob/main/app.js +``` +
\ No newline at end of file diff --git a/docs/sidebars.js b/docs/sidebars.js index 7af0d2800..cb8a4c656 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -34,6 +34,7 @@ const sidebars = { "concepts/publishing-views", ], }, + "concepts/assistant", "concepts/custom-steps", { type: "category", From ac518e1ecb14cf771f8d05cdc41827f88a44d9c8 Mon Sep 17 00:00:00 2001 From: Luke Russell Date: Fri, 25 Oct 2024 11:49:03 -0700 Subject: [PATCH 3/7] docs: moving stuff around --- docs/content/concepts/action-listening.md | 2 +- docs/content/concepts/custom-steps.md | 5 +- docs/content/concepts/error-handling.md | 2 +- docs/content/getting-started.mdx | 5 + .../conversation-store.md | 0 .../{tutorial => legacy}/hubot-migration.md | 4 +- .../steps.md => legacy/steps-from-apps.md} | 0 .../{tutorial => migration}/migration-v2.md | 4 +- .../{tutorial => migration}/migration-v3.md | 2 +- .../{tutorial => migration}/migration-v4.md | 2 +- .../{basic => concepts}/acknowledge.md | 0 .../{basic => concepts}/action-listening.md | 2 +- .../{basic => concepts}/action-respond.md | 0 .../authenticating-oauth.md | 0 .../{advanced => concepts}/authorization.md | 0 .../current/{basic => concepts}/commands.md | 0 .../current/{advanced => concepts}/context.md | 0 .../{basic => concepts}/creating-modals.md | 0 .../{advanced => concepts}/custom-routes.md | 0 .../{basic => concepts}/custom-steps.md | 0 .../deferring-initialization.md | 0 .../{advanced => concepts}/error-handling.md | 2 +- .../{basic => concepts}/event-listening.md | 0 .../global-middleware.md | 2 +- .../listener-middleware.md | 2 +- .../current/{advanced => concepts}/logging.md | 0 .../{basic => concepts}/message-listening.md | 0 .../{basic => concepts}/message-sending.md | 0 .../current/{basic => concepts}/options.md | 0 .../{basic => concepts}/publishing-views.md | 0 .../{advanced => concepts}/receiver.md | 0 .../current/{basic => concepts}/shortcuts.md | 0 .../{basic => concepts}/socket-mode.md | 0 .../{advanced => concepts}/token-rotation.md | 0 .../updating-pushing-views.md | 0 .../{basic => concepts}/view-submissions.md | 0 .../current/{basic => concepts}/web-api.md | 0 ...getting-started.md => getting-started.mdx} | 213 +++++++++++- .../conversation-store.md | 0 .../{tutorials => legacy}/hubot-migration.md | 0 .../current/legacy/steps-from-apps.md | 194 +++++++++++ .../{tutorials => migration}/migration-v2.md | 0 .../{tutorials => migration}/migration-v3.md | 0 .../current/steps/adding-editing-steps.md | 60 ---- .../current/steps/creating-steps.md | 33 -- .../current/steps/executing-steps.md | 37 -- .../current/steps/saving-steps.md | 50 --- .../current/steps/steps.md | 17 - .../current/tutorials/getting-started-http.md | 324 ------------------ docs/sidebars.js | 13 +- docs/src/css/custom.css | 6 + 51 files changed, 425 insertions(+), 556 deletions(-) rename docs/content/{concepts => legacy}/conversation-store.md (100%) rename docs/content/{tutorial => legacy}/hubot-migration.md (99%) rename docs/content/{steps/steps.md => legacy/steps-from-apps.md} (100%) rename docs/content/{tutorial => migration}/migration-v2.md (99%) rename docs/content/{tutorial => migration}/migration-v3.md (99%) rename docs/content/{tutorial => migration}/migration-v4.md (99%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/acknowledge.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/action-listening.md (96%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/action-respond.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/authenticating-oauth.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => concepts}/authorization.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/commands.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => concepts}/context.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/creating-modals.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => concepts}/custom-routes.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/custom-steps.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => concepts}/deferring-initialization.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => concepts}/error-handling.md (98%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/event-listening.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => concepts}/global-middleware.md (96%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => concepts}/listener-middleware.md (96%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => concepts}/logging.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/message-listening.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/message-sending.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/options.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/publishing-views.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => concepts}/receiver.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/shortcuts.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/socket-mode.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => concepts}/token-rotation.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/updating-pushing-views.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/view-submissions.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{basic => concepts}/web-api.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{getting-started.md => getting-started.mdx} (70%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{advanced => legacy}/conversation-store.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{tutorials => legacy}/hubot-migration.md (100%) create mode 100644 docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/steps-from-apps.md rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{tutorials => migration}/migration-v2.md (100%) rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/{tutorials => migration}/migration-v3.md (100%) delete mode 100644 docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/adding-editing-steps.md delete mode 100644 docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/creating-steps.md delete mode 100644 docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/executing-steps.md delete mode 100644 docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/saving-steps.md delete mode 100644 docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/steps/steps.md delete mode 100644 docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/tutorials/getting-started-http.md diff --git a/docs/content/concepts/action-listening.md b/docs/content/concepts/action-listening.md index e61b50c32..504d88041 100644 --- a/docs/content/concepts/action-listening.md +++ b/docs/content/concepts/action-listening.md @@ -12,7 +12,7 @@ You’ll notice in all `action()` examples, `ack()` is used. It is required to c :::info -Since v2, message shortcuts (previously message actions) now use the `shortcut()` method instead of the `action()` method. View the [migration guide for V2](/tutorial/migration-v2) to learn about the changes. +Since v2, message shortcuts (previously message actions) now use the `shortcut()` method instead of the `action()` method. View the [migration guide for V2](/migration/migration-v2) to learn about the changes. ::: diff --git a/docs/content/concepts/custom-steps.md b/docs/content/concepts/custom-steps.md index 324d1ddda..0d7cd6b79 100644 --- a/docs/content/concepts/custom-steps.md +++ b/docs/content/concepts/custom-steps.md @@ -1,6 +1,5 @@ --- -title: Listening and responding to custom steps -sidebar_label: Custom Steps +title: Custom Steps lang: en slug: /concepts/custom-steps --- @@ -65,7 +64,7 @@ Example app manifest definition --- -### Listening to custom step interactivity events +## 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 diff --git a/docs/content/concepts/error-handling.md b/docs/content/concepts/error-handling.md index 4cd94eaa7..87d673504 100644 --- a/docs/content/concepts/error-handling.md +++ b/docs/content/concepts/error-handling.md @@ -6,7 +6,7 @@ slug: /concepts/error-handling :::info -Since v2, error handling has improved! View the [migration guide for V2](/tutorial/migration-v2) to learn about the changes. +Since v2, error handling has improved! View the [migration guide for V2](/migration/migration-v2) to learn about the changes. ::: diff --git a/docs/content/getting-started.mdx b/docs/content/getting-started.mdx index a8910320d..34a62ae59 100644 --- a/docs/content/getting-started.mdx +++ b/docs/content/getting-started.mdx @@ -197,6 +197,11 @@ const app = new App({ }); ``` + + + +Carry on! + diff --git a/docs/content/concepts/conversation-store.md b/docs/content/legacy/conversation-store.md similarity index 100% rename from docs/content/concepts/conversation-store.md rename to docs/content/legacy/conversation-store.md diff --git a/docs/content/tutorial/hubot-migration.md b/docs/content/legacy/hubot-migration.md similarity index 99% rename from docs/content/tutorial/hubot-migration.md rename to docs/content/legacy/hubot-migration.md index 3f2ef5b2e..2aa2a1c33 100644 --- a/docs/content/tutorial/hubot-migration.md +++ b/docs/content/legacy/hubot-migration.md @@ -1,15 +1,13 @@ --- title: Migrating apps from Hubot to Bolt for JavaScript -slug: hubot-migration +slug: /tutorial/hubot-migration lang: en -layout: tutorial --- Bolt was created to reduce the time and complexity it takes to build Slack apps. It provides Slack developers a single interface to build using modern features and best practices. This guide is meant to step you through the process of migrating your app from using [Hubot](https://hubot.github.com/docs/) to Bolt for JavaScript. If you already have an [app with a bot user](https://api.slack.com/bot-users#getting-started) or if you’re looking for code samples that translate Hubot code to Bolt for JavaScript code, you may find it valuable to start by reading through the [example script in the Bolt for JavaScript repository](https://github.com/slackapi/bolt-js/blob/master/examples/hubot-example/script.js). - --- ### Setting the stage {#setting-the-stage} diff --git a/docs/content/steps/steps.md b/docs/content/legacy/steps-from-apps.md similarity index 100% rename from docs/content/steps/steps.md rename to docs/content/legacy/steps-from-apps.md diff --git a/docs/content/tutorial/migration-v2.md b/docs/content/migration/migration-v2.md similarity index 99% rename from docs/content/tutorial/migration-v2.md rename to docs/content/migration/migration-v2.md index 32b851037..f7b5b2dff 100644 --- a/docs/content/tutorial/migration-v2.md +++ b/docs/content/migration/migration-v2.md @@ -1,7 +1,7 @@ --- title: Migrating to V2 -slug: migration-v2 -lang: en--- +slug: /tutorial/migration-v2 +lang: en --- This guide will walk you through the process of updating your app from using `@slack/bolt@1.x` to `@slack/bolt@2.x`. There are a few changes you'll need to make but for most apps, these changes can be applied in 5 - 15 minutes. diff --git a/docs/content/tutorial/migration-v3.md b/docs/content/migration/migration-v3.md similarity index 99% rename from docs/content/tutorial/migration-v3.md rename to docs/content/migration/migration-v3.md index 73aa4c6b6..b453984a2 100644 --- a/docs/content/tutorial/migration-v3.md +++ b/docs/content/migration/migration-v3.md @@ -1,6 +1,6 @@ --- title: Migrating to V3 -slug: migration-v3 +slug: /tutorial/migration-v3 lang: en --- diff --git a/docs/content/tutorial/migration-v4.md b/docs/content/migration/migration-v4.md similarity index 99% rename from docs/content/tutorial/migration-v4.md rename to docs/content/migration/migration-v4.md index 75097bf84..b96b58801 100644 --- a/docs/content/tutorial/migration-v4.md +++ b/docs/content/migration/migration-v4.md @@ -1,6 +1,6 @@ --- title: Migrating to V4 -slug: migration-v4 +slug: /tutorial/migration-v4 lang: en --- 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/action-listening.md similarity index 96% 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/action-listening.md index bfe5edbe1..19eadbe30 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/action-listening.md @@ -10,7 +10,7 @@ Bolt アプリは `action` メ゜ッドを甚いお、ボタンのクリック すべおの `action()` の䟋で `ack()` が䜿甚されおいるこずに泚目しおください。Slack からリク゚ストを受信したこずを確認するために、アクションリスナヌ内で `ack()` 関数を呌び出す必芁がありたす。これに぀いおは、「[リク゚ストの確認](/concepts/acknowledge)」 セクションで説明しおいたす。 -*泚: Bolt 2.x からメッセヌゞショヌトカット以前はメッセヌゞアクションず呌ばれおいたしたは `action()` ではなく `shortcut()` メ゜ッドを䜿甚するようになりたした。この倉曎に぀いおは [2.x マむグレヌションガむド](/tutorial/migration-v2)を参照しおください。* +*泚: Bolt 2.x からメッセヌゞショヌトカット以前はメッセヌゞアクションず呌ばれおいたしたは `action()` ではなく `shortcut()` メ゜ッドを䜿甚するようになりたした。この倉曎に぀いおは [2.x マむグレヌションガむド](/migration/migration-v2)を参照しおください。* `block_actions` ペむロヌドの詳现に぀いおは、[こちら](https://api.slack.com/reference/interaction-payloads) をご芧ください。リスナヌ内からビュヌの完党なペむロヌドにアクセスするには、コヌルバック関数内で `body` 匕数を参照したす。 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/concepts/action-respond.md similarity index 100% rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/action-respond.md rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/action-respond.md 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 100% 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 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 100% 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 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 100% 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 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/concepts/custom-steps.md similarity index 100% rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/basic/custom-steps.md rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/custom-steps.md 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 98% 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..a36d9109d 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 @@ -4,7 +4,7 @@ lang: ja-jp slug: /concepts/error-handling --- -*泚: Bolt 2.x から゚ラヌハンドリングが改善されたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/tutorial/migration-v2)を参照しおください。* +*泚: Bolt 2.x から゚ラヌハンドリングが改善されたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/migration/migration-v2)を参照しおください。* リスナヌで゚ラヌが発生した堎合は `try`/`catch` を䜿っお盎接ハンドリングするこずをおすすめしたす。しかし、それでもなおすり抜けおしたう゚ラヌのパタヌンもあるでしょう。デフォルトでは、このような゚ラヌはコン゜ヌルにログ出力されたす。ご自身でこれらをハンドリングするには、`app.error(fn)` メ゜ッドによっお、グロヌバル゚ラヌハンドラヌを定矩しおください。 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 100% 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 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 96% 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..1eaf01fa8 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,7 @@ slug: /concepts/global-middleware たずえば、アプリが、察応する内郚認蚌サヌビス (SSO プロバむダ、LDAP など) で識別されたナヌザヌにのみ応答する必芁があるずしたす。この堎合、グロヌバルミドルりェアを䜿甚しお認蚌サヌビス内のナヌザヌレコヌドを怜玢し、ナヌザヌが芋぀からない堎合ぱラヌずなるように定矩するのがよいでしょう。 -*泚: Bolt 2.x からグロヌバルミドルりェアが `async` 関数をサポヌトしたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/tutorial/migration-v2)を参照しおください。* +*泚: Bolt 2.x からグロヌバルミドルりェアが `async` 関数をサポヌトしたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/migration/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 96% 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..d5017e8f4 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,7 @@ slug: /concepts/listener-middleware 䟋ずしお、リスナヌが人ボットではないナヌザヌからのメッセヌゞのみを扱うケヌスを考えおみたしょう。このためには、党おのボットメッセヌゞを陀倖するリスナヌミドルりェアを実装したす。 -*泚: Bolt 2.x からミドルりェアが `async` 関数をサポヌトしたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/tutorial/migration-v2)を参照しおください。* +*泚: Bolt 2.x からミドルりェアが `async` 関数をサポヌトしたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/migration/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 100% 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 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 100% 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 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 100% 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 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/options.md similarity index 100% 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/options.md 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/shortcuts.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/shortcuts.md similarity index 100% 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 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 100% 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 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 100% 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 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 100% 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 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 100% 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 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 70% 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..50adbf396 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 @@ -9,11 +9,7 @@ lang: ja-jp このガむドでは、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)を実行したり、修正したり、自分で䜜ったりするこずができたす。 --- @@ -79,17 +75,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` 䞭で䟝存ファむルずしお保存したす。 @@ -130,11 +132,19 @@ node app.js アプリはワヌクスペヌス内の他のメンバヌず同じように振る舞い、メッセヌゞを投皿したり、絵文字リアクションを远加したり、むベントをリッスンしお返答したりできたす。 -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 での情報に぀いおは[こちらのドキュメント](/tutorial/getting-started-#setting-up-events)を参照しおください。 ::: @@ -144,6 +154,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 からアプリに送信されたす。アプリではこれらの情報を凊理しお、適切な応答を返したす。 @@ -163,6 +197,9 @@ Slack ワヌクスペヌスで発生するむベントメッセヌゞが投 次の䟋では、あなたのアプリが远加されおいるチャンネルや DM で `hello` ずいう単語を含むすべおのメッセヌゞをリッスンし、 `Hey there @user!` ず応答したす。 + + + ```javascript const { App } = require('@slack/bolt'); @@ -190,6 +227,34 @@ 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` を含むメッセヌゞを送信しおみおください。アプリが応答したら成功です。 これは基本的な䟋ですが、ここから自分の奜きなようにアプリをカスタマむズしおいくこずができたす。さらにむンタラクティブな動䜜を詊すために、プレヌンテキストではなくボタンを送信しおみたしょう。 @@ -200,12 +265,27 @@ app.message('hello', async ({ message, say }) => { ボタン、遞択メニュヌ、日付ピッカヌ、モヌダルなどの機胜を䜿甚するには、むンタラクティブ機胜を有効にする必芁がありたす。むベントず同様に、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 +294,9 @@ app.message('hello', async ({ message, say }) => { 以䞋は、前のセクションで蚘述したアプリコヌドを、文字列だけでなく、ボタン付きのメッセヌゞを送信するように倉曎したものです。 + + + ```javascript const { App } = require('@slack/bolt'); @@ -260,6 +343,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 +404,9 @@ app.message('hello', async ({ message, say }) => { ボタンがクリックされるずフォロヌアップメッセヌゞを送信するハンドラヌを远加しおみたしょう。 + + + ```javascript const { App } = require('@slack/bolt'); @@ -326,12 +459,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 アプリを゜ケットモヌドを䜿っお構築できたした! 🎉 +これで最初の Bolt アプリが構築できたした! 🎉 基本的なアプリの䜜成ができたしたので、次回は是非もっずいろいろな、 Bolt の機胜を䜿っおアプリを䜜っおみたしょう。䞋蚘のリンクを蟿っおいろいろアむデアを暡玢しおみおください @@ -340,5 +527,3 @@ 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 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 100% 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 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..d2e266173 --- /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: /concepts/steps +--- + +アプリによるワヌクフロヌステップ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 100% 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 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 100% 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 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** たでスクロヌルしたす。メッセヌゞに関するむベントが぀ありたす: -- `message.channels` あなたのアプリが远加されおいるパブリックチャンネルのメッセヌゞをリッスン -- `message.groups` あなたのアプリが远加されおいる🔒プラむベヌトチャンネルのメッセヌゞをリッスン -- `message.im` あなたのアプリずナヌザヌのダむレクトメッセヌゞをリッスン -- `message.mpim` あなたのアプリが远加されおいるグルヌプ DM をリッスン - -もしボットに参加しおいるすべおの堎所で党おのメッセヌゞむベントをリッスンさせたいなら、これら぀党おのむベントを遞んでください。遞択したら、緑の **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/sidebars.js b/docs/sidebars.js index cb8a4c656..32776b7ed 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -64,7 +64,6 @@ const sidebars = { "concepts/authorization", "concepts/authenticating-oauth", "concepts/token-rotation", - "concepts/conversation-store", ], }, { @@ -76,15 +75,19 @@ const sidebars = { type: "category", label: "Migration Guides", items: [ - "tutorial/migration-v2", - "tutorial/migration-v3", - "tutorial/migration-v4", + "migration/migration-v2", + "migration/migration-v3", + "migration/migration-v4", ], }, { type: "category", label: "Legacy", - items: ["tutorial/hubot-migration", "steps/steps"], + 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..c6cc91b1a 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -113,3 +113,9 @@ html[data-theme="dark"] .navbar-github-link::before { font-weight: bold; color: #000; } + +.tabs-container { + border: 2px solid var(--ifm-hr-background-color); /* Adjust the color and thickness as needed */ + border-radius: 5px; /* To give rounded corners */ + padding: 0.5em; /* To add spacing inside the tab */ +} From b99edbaf4d3326f86c03dc8b3a5c23fc88bc16ff Mon Sep 17 00:00:00 2001 From: Luke Russell Date: Fri, 25 Oct 2024 11:53:29 -0700 Subject: [PATCH 4/7] add translation json --- docs/i18n/ja-jp/code.json | 28 ++++++++++ .../current.json | 56 +++++++++++++------ .../docusaurus-theme-classic/navbar.json | 4 ++ 3 files changed, 72 insertions(+), 16 deletions(-) diff --git a/docs/i18n/ja-jp/code.json b/docs/i18n/ja-jp/code.json index eb1a022fa..bdbb626b2 100644 --- a/docs/i18n/ja-jp/code.json +++ b/docs/i18n/ja-jp/code.json @@ -285,5 +285,33 @@ "theme.unlistedContent.message": { "message": "このペヌゞは非公開です。 怜玢察象倖ずなり、このペヌゞのリンクに盎接アクセスできるナヌザヌのみに公開されたす。", "description": "The unlisted content banner message" + }, + "theme.blog.author.pageTitle": { + "message": "{authorName} - {nPosts}", + "description": "The title of the page for a blog author" + }, + "theme.blog.authorsList.pageTitle": { + "message": "Authors", + "description": "The title of the authors page" + }, + "theme.blog.authorsList.viewAll": { + "message": "View All Authors", + "description": "The label of the link targeting the blog authors page" + }, + "theme.contentVisibility.unlistedBanner.title": { + "message": "非公開のペヌゞ", + "description": "The unlisted content banner title" + }, + "theme.contentVisibility.unlistedBanner.message": { + "message": "このペヌゞは非公開です。 怜玢察象倖ずなり、このペヌゞのリンクに盎接アクセスできるナヌザヌのみに公開されたす。", + "description": "The unlisted content banner message" + }, + "theme.contentVisibility.draftBanner.title": { + "message": "Draft page", + "description": "The draft content banner title" + }, + "theme.contentVisibility.draftBanner.message": { + "message": "This page is a draft. It will only be visible in dev and be excluded from the production build.", + "description": "The draft content banner message" } } 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..da0aa29b4 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 calls", + "description": "The label for category Slack API calls in sidebar sidebarJSBolt" + }, + "sidebar.sidebarJSBolt.category.Events": { + "message": "Events", + "description": "The label for category Events in sidebar sidebarJSBolt" + }, + "sidebar.sidebarJSBolt.category.Interactivity & Shortcuts": { + "message": "Interactivity & Shortcuts", + "description": "The label for category Interactivity & Shortcuts in sidebar sidebarJSBolt" + }, + "sidebar.sidebarJSBolt.category.App Configuration": { + "message": "App Configuration", + "description": "The label for category App Configuration in sidebar sidebarJSBolt" + }, + "sidebar.sidebarJSBolt.category.Middleware & Context": { + "message": "Middleware & Context", + "description": "The label for category Middleware & Context in sidebar sidebarJSBolt" + }, + "sidebar.sidebarJSBolt.category.Authorization & Security": { + "message": "Authorization & Security", + "description": "The label for category Authorization & Security in sidebar sidebarJSBolt" + }, + "sidebar.sidebarJSBolt.category.Migration Guides": { + "message": "Migration Guides", + "description": "The label for category Migration Guides in sidebar sidebarJSBolt" + }, + "sidebar.sidebarJSBolt.category.Legacy": { + "message": "Legacy", + "description": "The label for category Legacy in sidebar sidebarJSBolt" + }, + "sidebar.sidebarJSBolt.link.Release notes": { + "message": "Release notes", + "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-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" } } From 9c5307783af1b11a02005ee545b0ee3a2181a4ef Mon Sep 17 00:00:00 2001 From: Luke Russell Date: Fri, 25 Oct 2024 11:55:48 -0700 Subject: [PATCH 5/7] docs: remove superfluous generated translation json --- docs/i18n/ja-jp/code.json | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/docs/i18n/ja-jp/code.json b/docs/i18n/ja-jp/code.json index bdbb626b2..eb1a022fa 100644 --- a/docs/i18n/ja-jp/code.json +++ b/docs/i18n/ja-jp/code.json @@ -285,33 +285,5 @@ "theme.unlistedContent.message": { "message": "このペヌゞは非公開です。 怜玢察象倖ずなり、このペヌゞのリンクに盎接アクセスできるナヌザヌのみに公開されたす。", "description": "The unlisted content banner message" - }, - "theme.blog.author.pageTitle": { - "message": "{authorName} - {nPosts}", - "description": "The title of the page for a blog author" - }, - "theme.blog.authorsList.pageTitle": { - "message": "Authors", - "description": "The title of the authors page" - }, - "theme.blog.authorsList.viewAll": { - "message": "View All Authors", - "description": "The label of the link targeting the blog authors page" - }, - "theme.contentVisibility.unlistedBanner.title": { - "message": "非公開のペヌゞ", - "description": "The unlisted content banner title" - }, - "theme.contentVisibility.unlistedBanner.message": { - "message": "このペヌゞは非公開です。 怜玢察象倖ずなり、このペヌゞのリンクに盎接アクセスできるナヌザヌのみに公開されたす。", - "description": "The unlisted content banner message" - }, - "theme.contentVisibility.draftBanner.title": { - "message": "Draft page", - "description": "The draft content banner title" - }, - "theme.contentVisibility.draftBanner.message": { - "message": "This page is a draft. It will only be visible in dev and be excluded from the production build.", - "description": "The draft content banner message" } } From 92681409d97a95dcad8774bde3cdaac2d83e157e Mon Sep 17 00:00:00 2001 From: Luke Russell <31357343+lukegalbraithrussell@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:32:17 -0700 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: Kazuhiro Sera --- docs/content/getting-started.mdx | 2 +- .../current.json | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/content/getting-started.mdx b/docs/content/getting-started.mdx index 34a62ae59..af9bfa0a7 100644 --- a/docs/content/getting-started.mdx +++ b/docs/content/getting-started.mdx @@ -131,7 +131,7 @@ To listen for events happening in a Slack workspace (like when a message is post For those just starting, we recommend using [Socket Mode](https://api.slack.com/apis/connections/socket). Socket Mode allows your app to use the Events API and interactive features without exposing a public HTTP Request URL. This can be helpful during development, or if you're receiving requests from behind a firewall. -That being said, you're welcome to set up an app with a public HTTP Request URL. HTTP is more useful for apps being deployed to hosting environments (like [AWS](/deployments/aws-lambda) or [Heroku](/deployments/heroku)), or apps intended for distribution via the Slack App Directory. +That being said, you're welcome to set up an app with a public HTTP Request URL. HTTP is more useful for apps being deployed to hosting environments (like [AWS](/deployments/aws-lambda) or [Heroku](/deployments/heroku) to stably respond within a large corporate Slack workspaces/organization, or apps intended for distribution via the Slack Martketplace. We've provided instructions for both ways in this guide. 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 da0aa29b4..9b5ae4aba 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current.json +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current.json @@ -20,39 +20,39 @@ "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 calls", + "message": "Slack API コヌル", "description": "The label for category Slack API calls in sidebar sidebarJSBolt" }, "sidebar.sidebarJSBolt.category.Events": { - "message": "Events", + "message": "むベント API", "description": "The label for category Events in sidebar sidebarJSBolt" }, "sidebar.sidebarJSBolt.category.Interactivity & Shortcuts": { - "message": "Interactivity & Shortcuts", + "message": "むンタラクティビティ & ショヌトカット", "description": "The label for category Interactivity & Shortcuts in sidebar sidebarJSBolt" }, "sidebar.sidebarJSBolt.category.App Configuration": { - "message": "App Configuration", + "message": "App の蚭定", "description": "The label for category App Configuration in sidebar sidebarJSBolt" }, "sidebar.sidebarJSBolt.category.Middleware & Context": { - "message": "Middleware & Context", + "message": "ミドルりェア & コンテキスト", "description": "The label for category Middleware & Context in sidebar sidebarJSBolt" }, "sidebar.sidebarJSBolt.category.Authorization & Security": { - "message": "Authorization & Security", + "message": "認可 & セキュリティ", "description": "The label for category Authorization & Security in sidebar sidebarJSBolt" }, "sidebar.sidebarJSBolt.category.Migration Guides": { - "message": "Migration Guides", + "message": "マむグレヌションガむド", "description": "The label for category Migration Guides in sidebar sidebarJSBolt" }, "sidebar.sidebarJSBolt.category.Legacy": { - "message": "Legacy", + "message": "レガシヌ非掚奚", "description": "The label for category Legacy in sidebar sidebarJSBolt" }, "sidebar.sidebarJSBolt.link.Release notes": { - "message": "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": { From 4041ac638198fa1d71344b5febe9aedf3049fefc Mon Sep 17 00:00:00 2001 From: Luke Russell Date: Mon, 28 Oct 2024 15:18:51 -0700 Subject: [PATCH 7/7] feedback from PR --- docs/content/concepts/action-respond.md | 36 ---- .../{action-listening.md => actions.md} | 49 +++-- docs/content/concepts/assistant.md | 186 ------------------ docs/content/concepts/commands.md | 4 +- docs/content/concepts/custom-steps.md | 2 +- docs/content/concepts/error-handling.md | 2 +- docs/content/concepts/event-listening.md | 27 +-- docs/content/concepts/message-listening.md | 29 ++- .../{options.md => select-menu-options.md} | 4 +- docs/content/concepts/shortcuts.md | 2 +- .../concepts/updating-pushing-views.md | 2 +- docs/content/legacy/steps-from-apps.md | 2 +- docs/content/migration/migration-v4.md | 2 +- docs/content/reference.md | 4 +- docs/docusaurus.config.js | 9 +- docs/i18n/ja-jp/README.md | 2 +- .../current.json | 2 +- .../current/concepts/action-respond.md | 37 ---- .../{action-listening.md => actions.md} | 42 +++- .../current/concepts/commands.md | 2 +- .../current/concepts/custom-steps.md | 167 ---------------- .../current/concepts/error-handling.md | 2 +- .../current/concepts/event-listening.md | 27 +-- .../current/concepts/global-middleware.md | 2 +- .../current/concepts/listener-middleware.md | 2 +- .../current/concepts/message-listening.md | 27 ++- .../{options.md => select-menu-options.md} | 2 +- .../current/getting-started.mdx | 2 +- .../current/legacy/hubot-migration.md | 2 +- .../current/legacy/steps-from-apps.md | 2 +- .../current/migration/migration-v2.md | 4 +- .../current/migration/migration-v3.md | 2 +- .../current/reference.md | 16 +- docs/sidebars.js | 10 +- 34 files changed, 153 insertions(+), 559 deletions(-) delete mode 100644 docs/content/concepts/action-respond.md rename docs/content/concepts/{action-listening.md => actions.md} (53%) delete mode 100644 docs/content/concepts/assistant.md rename docs/content/concepts/{options.md => select-menu-options.md} (91%) delete mode 100644 docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/action-respond.md rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/{action-listening.md => actions.md} (58%) delete mode 100644 docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/custom-steps.md rename docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/{options.md => select-menu-options.md} (92%) diff --git a/docs/content/concepts/action-respond.md b/docs/content/concepts/action-respond.md deleted file mode 100644 index 958471935..000000000 --- a/docs/content/concepts/action-respond.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Responding to actions -lang: en -slug: /concepts/action-respond ---- - -There are two main ways to respond to actions. The first (and most common) way is to use the `say` function. The `say` function sends a message back to the conversation where the incoming request took place. - -The second way to respond to actions is using `respond()`, which is a simple utility to use the `response_url` associated with an action. - -```javascript -// Your middleware will be called every time an interactive component with the action_id “approve_button” is triggered -app.action('approve_button', async ({ ack, say }) => { - // Acknowledge action request - await ack(); - await say('Request approved 👍'); -}); -``` - -
- -Using `respond()` - - -Since `respond()` is a utility for calling the `response_url`, it behaves in the same way. You can pass a JSON object with a new message payload that will be published back to the source of the original interaction with optional properties like `response_type` (which has a value of `in_channel` or `ephemeral`), `replace_original`, and `delete_original`. - -```javascript -// Listens to actions triggered with action_id of “user_select” -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/content/concepts/action-listening.md b/docs/content/concepts/actions.md similarity index 53% rename from docs/content/concepts/action-listening.md rename to docs/content/concepts/actions.md index 504d88041..d64cfc780 100644 --- a/docs/content/concepts/action-listening.md +++ b/docs/content/concepts/actions.md @@ -1,21 +1,17 @@ --- -title: Listening to actions +title: Listening & responding to actions lang: en -slug: /concepts/action-listening +slug: /concepts/actions --- -Your app can listen to user actions like button clicks, and menu selects, using the `action` method. +Your app can listen and respond to user actions like button clicks, and menu selects, using the `action` method. + +## Listening to actions Actions can be filtered on an `action_id` of type string or RegExp object. `action_id`s act as unique identifiers for interactive components on the Slack platform. You’ll notice in all `action()` examples, `ack()` is used. It is required to call the `ack()` function within an action listener to acknowledge that the request was received from Slack. This is discussed in the [acknowledging requests section](/concepts/acknowledge). -:::info - -Since v2, message shortcuts (previously message actions) now use the `shortcut()` method instead of the `action()` method. View the [migration guide for V2](/migration/migration-v2) to learn about the changes. - -::: - View more information about the `block_actions` payload within the [relevant API documentation page](https://api.slack.com/reference/interaction-payloads). To access the full payload of a view from within a listener, reference the `body` argument within your callback function. ```javascript @@ -26,10 +22,7 @@ app.action('approve_button', async ({ ack }) => { }); ``` -
- -Listening to actions using a constraint object - +### Listening to actions using a constraint object You can use a constraints object to listen to `callback_id`s, `block_id`s, and `action_id`s (or any combination of them). Constraints in the object can be of type string or RegExp object. @@ -56,4 +49,32 @@ app.action({ action_id: 'select_user', block_id: 'assign_ticket' }, }); ``` -
\ No newline at end of file +## Responding to actions + +There are two main ways to respond to actions. The first (and most common) way is to use the `say` function. The `say` function sends a message back to the conversation where the incoming request took place. + +The second way to respond to actions is using `respond()`, which is a simple utility to use the `response_url` associated with an action. + +```javascript +// Your middleware will be called every time an interactive component with the action_id “approve_button” is triggered +app.action('approve_button', async ({ ack, say }) => { + // Acknowledge action request + await ack(); + await say('Request approved 👍'); +}); +``` + + +### Using the `respond()` utility + +Since `respond()` is a utility for calling the `response_url`, it behaves in the same way. You can pass a JSON object with a new message payload that will be published back to the source of the original interaction with optional properties like `response_type` (which has a value of `in_channel` or `ephemeral`), `replace_original`, and `delete_original`. + +```javascript +// Listens to actions triggered with action_id of “user_select” +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/content/concepts/assistant.md b/docs/content/concepts/assistant.md deleted file mode 100644 index ae89ad35a..000000000 --- a/docs/content/concepts/assistant.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -title: Agents & Assistants -lang: en -slug: /concepts/assistant ---- - -:::info[This feature requires a paid plan] -If you don't have a paid workspace for development, you can join the [Developer Program](https://api.slack.com/developer-program) and provision a sandbox with access to all Slack features for free. -::: - -Agents and assistants comprise a new messaging experience for Slack. If you're unfamiliar with using agents and assistants within Slack, you'll want to read the [API documentation on the subject](https://api.slack.com/docs/apps/ai). Then, come back here to implement them with Bolt! - -## Configuring your app to support assistants - -1. Within [App Settings](https://api.slack.com/apps), enable the **Agents & Assistants** feature. - -2. Within the App Settings **OAuth & Permissions** page, add the following scopes: - * [`assistant:write`](https://api.slack.com/scopes/assistant:write) - * [`chat:write`](https://api.slack.com/scopes/chat:write) - * [`im:history`](https://api.slack.com/scopes/im:history) - -3 Within the App Settings **Event Subscriptions** page, subscribe to the following events: - * [`assistant_thread_started`](https://api.slack.com/events/assistant_thread_started) - * [`assistant_thread_context_changed`](https://api.slack.com/events/assistant_thread_context_changed) - * [`message.im`](https://api.slack.com/events/message.im) - -:::info -You _could_ implement your own assistants by [listening](/concepts/event-listening) for the `assistant_thread_started`, `assistant_thread_context_changed`, and `message.im` events. That being said, using the `Assistant` class will streamline the process. And we already wrote this nice guide for you! -::: - -## The `Assistant` class - -### Instance template - -```ts -const assistant = new Assistant({ - threadContextStore: { - get: async ({ context, client, payload }) => {}, - save: async ({ context, client, payload }) => {}, - }, - threadStarted: async ({ say, saveThreadContext, setStatus, setSuggestedPrompts, setTitle }) => {}, - threadContextChanged: async ({ say, setStatus, setSuggestedPrompts, setTitle }) => {}, - userMessage: async ({ say, getThreadContext, setStatus, setSuggestedPrompts, setTitle }) => {}, -}); -``` - -### The `AssistantConfig` configuration object - -| Property | Required? | Description | -|---|---|---| -|`threadContextStore` | Optional, but recommended | When provided, must have the required methods to get and save thread context, which will override the `getThreadContext` and `saveThreadContext` utilities.

If not provided, a `DefaultAssistantContextStore` instance is used. -| `threadStarted` | Required | Executes when the user opens the assistant container or otherwise begins a new chat, thus sending the [`assistant_thread_started`](https://api.slack.com/events/assistant_thread_started) event. -| `threadContextChanged` | Optional | Executes when a user switches channels while the assistant container is open, thus sending the [`assistant_thread_context_changed`](https://api.slack.com/events/assistant_thread_context_changed) event.

If not provided, context will be saved using the AssistantContextStore's `save` method (either the `DefaultAssistantContextStore` instance or provided `threadContextStore`). -| `userMessage` | Required | Executes when a [message](https://api.slack.com/events/message), thus sending the [`message.im`](https://api.slack.com/events/message.im) event. These messages do not contain a subtype and must be deduced based on their shape and metadata (if provided). Bolt handles this deduction out of the box for those using the `Assistant` class. - -### Utilities - -Utility | Description -|---|---| -| `getThreadContext` | Alias for `AssistantContextStore.get()` method. Executed if custom `AssistantContextStore` value is provided.

If not provided, the `DefaultAssistantContextStore` instance will retrieve the most recent context saved to the instance. -| `saveThreadContext` | Alias for `AssistantContextStore.save()`. Executed if `AssistantContextStore` value is provided.

If not provided, the `DefaultAssistantContextStore` instance will save the `assistant_thread.context` to the instance and attach it to the initial assistant message that was sent to the thread. -| `say(message: string)` | Alias for the `postMessage` method.

Sends a message to the current assistant thread. -| `setTitle(title: string)` | [Sets the title](https://api.slack.com/methods/assistant.threads.setTitle) of the assistant thread to capture the initial topic/question. -| `setStatus(status: string)` | Sets the [status](https://api.slack.com/methods/assistant.threads.setStatus) of the assistant to give the appearance of active processing. -| `setSuggestedPrompts({ prompts: [{ title: string; message: string; }]` | Provides the user up to 4 optional, preset [prompts](https://api.slack.com/methods/assistant.threads.setSuggestedPrompts) to choose from. - -## Handling a new thread - -The `threadStarted` event handler allows your app to respond to new threads opened by users. In the example below, the app is sending a message — containing context message metadata — to the user, along with a single [prompt](https://api.slack.com/methods/assistant.threads.setSuggestedPrompts). - -```js -const assistant = new Assistant({ - threadStarted: async ({ event, say, setSuggestedPrompts, saveThreadContext }) => { - const { context } = event.assistant_thread; - - await say({ - text: 'Hi, how can I help?', - metadata: { event_type: 'assistant_thread_context', event_payload: context }, - }); - - await saveThreadContext(); - - const prompts = [{ - title: 'Fun Slack fact', - message: 'Give me a fun fact about Slack, please!', - }]; - - // Provide the user up to 4 optional, preset prompts to choose from. - await setSuggestedPrompts({ prompts }); - }, -... -``` - -:::tip -When a user opens an assistant thread while in a channel, the channel info is stored as the thread's `AssistantThreadContext` data. You can grab that info using the `getThreadContext()` utility, as subsequent user message event payloads won't include the channel info. -::: - - -## Handling context changes - -You can store context through the `threadContextStore` property but it must feature `get` and `save` methods. - -```js -threadContextStore: { - get: async ({ context, client, payload }) => {}, - save: async ({ context, client, payload }) => {}, - }, -``` - -If not provided, a `DefaultThreadContextStore` instance is utilized instead, which is a reference implementation that relies on storing and retrieving message metadata as the context changes. - -When the user switches channels, the `assistant_thread_context_changed` event will be sent to your app. Capture this with the `threadContextChanged` handler. - -```js -... - threadContextChanged: async ({ saveThreadContext }) => { - await saveThreadContext(); - }, -... -``` - -If you use the built-in `AssistantThreadContextStore` without any custom configuration the updated context data is automatically saved as message metadata on the first reply from the assistant bot. - -## Handling the user response - -User messages are handled with the `userMessage` event handler. The `setTitle` and `setStatus` utilities are useful in curating the user experience. - -:::warning -Messages sent to the assistant do not contain a subtype and must be deduced based on their shape and any provided metadata. -::: - - ```js - ... - userMessage: async ({ client, message, say, setTitle, setStatus }) => { - const { channel, thread_ts } = message; - - // Set the title of the Assistant thread to capture the initial topic/question - await setTitle(message.text); - - // Set the status of the Assistant to give the appearance of active processing. - await setStatus('is typing..'); - - // Retrieve the Assistant thread history for context of question being asked - const thread = await client.conversations.replies({ - channel, - ts: thread_ts, - oldest: thread_ts, - }); - - // Prepare and tag each message for LLM processing - const userMessage = { role: 'user', content: message.text }; - const threadHistory = thread.messages.map((m) => { - const role = m.bot_id ? 'assistant' : 'user'; - return { role, content: m.text }; - }); - - const messages = [ - { role: 'system', content: DEFAULT_SYSTEM_CONTENT }, - ...threadHistory, - userMessage, - ]; - - // Send message history and newest question to LLM - const llmResponse = await openai.chat.completions.create({ - model: 'gpt-4o-mini', - n: 1, - messages, - }); - - // Provide a response to the user - await say(llmResponse.choices[0].message.content); - }, -}); - -app.assistant(assistant); -``` - -## Full example - -
-App Agent & Assistant Template - -```js reference title="app.js" -https://github.com/slack-samples/bolt-js-assistant-template/blob/main/app.js -``` -
\ No newline at end of file diff --git a/docs/content/concepts/commands.md b/docs/content/concepts/commands.md index c16d8ad89..9a173efdf 100644 --- a/docs/content/concepts/commands.md +++ b/docs/content/concepts/commands.md @@ -1,5 +1,5 @@ --- -title: Listening and responding to commands +title: Listening & responding to commands lang: en slug: /concepts/commands --- @@ -14,7 +14,7 @@ If you use `command()` multiple times with overlapping RegExp matches, _all_ mat Commands must be acknowledged with `ack()` to inform Slack your app has received the request. -There are two ways to respond to slash commands. The first way is to use `say()`, which accepts a string or JSON payload. The second is `respond()` which is a utility for the `response_url`. These are explained in more depth in the [responding to actions](/concepts/action-respond) section. +There are two ways to respond to slash commands. The first way is to use `say()`, which accepts a string or JSON payload. The second is `respond()` which is a utility for the `response_url`. These are explained in more depth in the [responding to actions](/concepts/actions) section. When configuring commands within your app configuration, you'll continue to append `/slack/events` to your request URL. diff --git a/docs/content/concepts/custom-steps.md b/docs/content/concepts/custom-steps.md index 0d7cd6b79..f54c01cd1 100644 --- a/docs/content/concepts/custom-steps.md +++ b/docs/content/concepts/custom-steps.md @@ -68,7 +68,7 @@ Example app manifest definition 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). +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/actions). _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. diff --git a/docs/content/concepts/error-handling.md b/docs/content/concepts/error-handling.md index 87d673504..4cd94eaa7 100644 --- a/docs/content/concepts/error-handling.md +++ b/docs/content/concepts/error-handling.md @@ -6,7 +6,7 @@ slug: /concepts/error-handling :::info -Since v2, error handling has improved! View the [migration guide for V2](/migration/migration-v2) to learn about the changes. +Since v2, error handling has improved! View the [migration guide for V2](/tutorial/migration-v2) to learn about the changes. ::: diff --git a/docs/content/concepts/event-listening.md b/docs/content/concepts/event-listening.md index 721bca121..92d4025c7 100644 --- a/docs/content/concepts/event-listening.md +++ b/docs/content/concepts/event-listening.md @@ -25,29 +25,4 @@ app.event('team_join', async ({ event, client, logger }) => { logger.error(error); } }); -``` - -
- -Filtering on message subtypes - - -A `message()` listener is equivalent to `event('message')` - -You can filter on subtypes of events by using the built-in `subtype()` middleware. Common message subtypes like `message_changed` and `message_replied` can be found [on the message event page](https://api.slack.com/events/message#message_subtypes). - -```javascript -// Import subtype from the package -const { App, subtype } = require('@slack/bolt'); - -// Matches all message changes from users -app.message(subtype('message_changed'), ({ event, logger }) => { - // This if statement is required in TypeScript code - 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/content/concepts/message-listening.md b/docs/content/concepts/message-listening.md index 8a8b6f479..77b2b2914 100644 --- a/docs/content/concepts/message-listening.md +++ b/docs/content/concepts/message-listening.md @@ -4,9 +4,9 @@ lang: en slug: /concepts/message-listening --- -To listen to messages that [your app has access to receive](https://api.slack.com/messaging/retrieving#permissions), you can use the `message()` method which filters out events that aren’t of type `message`. +To listen to messages that [your app has access to receive](https://api.slack.com/messaging/retrieving#permissions), you can use the `message()` method which filters out events that aren’t of type `message` .A `message()` listener is equivalent to `event('message')` -`message()` accepts an optional `pattern` parameter of type `string` or `RegExp` object which filters out any messages that don’t match the pattern. +The `message()` listener accepts an optional `pattern` parameter of type `string` or `RegExp` object which filters out any messages that don’t match the pattern. ```javascript // This will match any message that contains 👋 @@ -21,10 +21,7 @@ app.message(':wave:', async ({ message, say }) => { }); ``` -
- -Using a RegExp pattern - +## Using a RegExp pattern {#using-regexp} A RegExp pattern can be used instead of a string for more granular matching. @@ -38,4 +35,22 @@ app.message(/^(hi|hello|hey).*/, async ({ context, say }) => { await say(`${greeting}, how are you?`); }); ``` -
\ No newline at end of file + +## Filtering on event subtypes {#filtering-event-subtypes} + +You can filter on subtypes of events by using the built-in `subtype()` middleware. Common message subtypes like `message_changed` and `message_replied` can be found [on the message event page](https://api.slack.com/events/message#message_subtypes). + +```javascript +// Import subtype from the package +const { App, subtype } = require('@slack/bolt'); + +// Matches all message changes from users +app.message(subtype('message_changed'), ({ event, logger }) => { + // This if statement is required in TypeScript code + 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}`); + } +}); +``` diff --git a/docs/content/concepts/options.md b/docs/content/concepts/select-menu-options.md similarity index 91% rename from docs/content/concepts/options.md rename to docs/content/concepts/select-menu-options.md index 475e554e5..6589cd3d4 100644 --- a/docs/content/concepts/options.md +++ b/docs/content/concepts/select-menu-options.md @@ -1,10 +1,10 @@ --- -title: Listening and responding to options +title: Listening & responding to select menu options lang: en slug: /concepts/options --- -The `options()` method listens for incoming option request payloads from Slack. [Similar to `action()`](/concepts/action-listening), +The `options()` method listens for incoming option request payloads from Slack. [Similar to `action()`](/concepts/actions), an `action_id` or constraints object is required. While it's recommended to use `action_id` for `external_select` menus, dialogs do not yet support Block Kit so you'll have to diff --git a/docs/content/concepts/shortcuts.md b/docs/content/concepts/shortcuts.md index 4ff2bcf6c..0c57d792e 100644 --- a/docs/content/concepts/shortcuts.md +++ b/docs/content/concepts/shortcuts.md @@ -1,5 +1,5 @@ --- -title: Listening and responding to shortcuts +title: Listening & responding to shortcuts lang: en slug: /concepts/shortcuts --- diff --git a/docs/content/concepts/updating-pushing-views.md b/docs/content/concepts/updating-pushing-views.md index 485678af1..3ccf4f14a 100644 --- a/docs/content/concepts/updating-pushing-views.md +++ b/docs/content/concepts/updating-pushing-views.md @@ -1,5 +1,5 @@ --- -title: Updating and pushing views +title: Updating & pushing views lang: en slug: /concepts/updating-pushing-views --- diff --git a/docs/content/legacy/steps-from-apps.md b/docs/content/legacy/steps-from-apps.md index 398a10183..659786c2d 100644 --- a/docs/content/legacy/steps-from-apps.md +++ b/docs/content/legacy/steps-from-apps.md @@ -1,7 +1,7 @@ --- title: Steps from Apps lang: en -slug: /concepts/steps +slug: /concepts/steps-from-apps --- :::danger diff --git a/docs/content/migration/migration-v4.md b/docs/content/migration/migration-v4.md index b96b58801..cadc5233d 100644 --- a/docs/content/migration/migration-v4.md +++ b/docs/content/migration/migration-v4.md @@ -94,7 +94,7 @@ import { defaultProcessEventHandler } from '@slack/bolt'; ### 🏭 Built-in middleware changes {#built-in-middleware-changes} -Two [built-in middlewares](../reference#built-in-listener-middleware-functions), `ignoreSelf` and `directMention`, previously needed to be invoked as a function in order to _return_ a middleware. These two built-in middlewares were not parameterized in the sense that they should just be used directly; as a result, you no longer should invoke them and instead pass them directly. +Two [built-in middlewares](../reference#built-in-middleware-functions), `ignoreSelf` and `directMention`, previously needed to be invoked as a function in order to _return_ a middleware. These two built-in middlewares were not parameterized in the sense that they should just be used directly; as a result, you no longer should invoke them and instead pass them directly. As an example, previously you may have leveraged `directMention` like this: diff --git a/docs/content/reference.md b/docs/content/reference.md index 44e9f1fec..a71dab74b 100644 --- a/docs/content/reference.md +++ b/docs/content/reference.md @@ -22,7 +22,7 @@ Below is the current list of methods that accept listener functions. These metho | `app.action(actionId, fn);` | Listens for an action event from a Block Kit element, such as a user interaction with a button, select menu, or datepicker. The `actionId` identifier is a `string` that should match the unique `action_id` included when your app sends the element to a view. Note that a view can be a message, modal, or app home. Note that action elements included in an `input` block do not trigger any events. | `app.shortcut(callbackId, fn);` | Listens for global or message shortcut invocation. The `callbackId` is a `string` or `RegExp` that must match a shortcut `callback_id` specified within your app's configuration. | `app.view(callbackId, fn);` | Listens for `view_submission` and `view_closed` events. `view_submission` events are sent when a user submits a modal that your app opened. `view_closed` events are sent when a user closes the modal rather than submits it. -| `app.step(workflowStep)` | Listen and responds to steps from apps events using the callbacks passed in an instance of `WorkflowStep`. Callbacks include three callbacks: `edit`, `save`, and `execute`. More information on steps from apps can be found [in the documentation](/concepts/adding-editing-steps). +| `app.step(workflowStep)` | Listen and responds to steps from apps events using the callbacks passed in an instance of `WorkflowStep`. Callbacks include three callbacks: `edit`, `save`, and `execute`. More information on steps from apps can be found [in the documentation](/concepts/steps-from-apps). | `app.command(commandName, fn);` | Listens for slash command invocations. The `commandName` is a `string` that must match a slash command specified in your app's configuration. Slash command names should be prefaced with a `/` (ex: `/helpdesk`). | `app.options(actionId, fn);` | Listens for options requests (from select menus with an external data source). This isn't often used, and shouldn't be mistaken with `app.action`. The `actionId` identifier is a `string` that matches the unique `action_id` included when you app sends a [select with an external data source](https://api.slack.com/reference/block-kit/block-elements#external_select). @@ -162,7 +162,7 @@ Bolt includes a set of error types to make errors easier to handle, with more sp | `ReceiverMultipleAckError` | Error thrown within Receiver when your app calls `ack()` when that request has previously been acknowledged. Currently only used in the default `HTTPReceiver`. | | `ReceiverAuthenticityError` | Error thrown when your app's request signature could not be verified. The error includes information on why it failed, such as an invalid timestamp, missing headers, or invalid signing secret. | `MultipleListenerError` | Thrown when multiple errors occur when processing multiple listeners for a single event. Includes an `originals` property with an array of the individual errors. | -| `WorkflowStepInitializationError` | Error thrown when configuration options are invalid or missing when instantiating a new `WorkflowStep` instance. This could be scenarios like not including a `callback_id`, or not including a configuration object. More information on steps from apps [can be found in the documentation](/concepts/steps). | +| `WorkflowStepInitializationError` | Error thrown when configuration options are invalid or missing when instantiating a new `WorkflowStep` instance. This could be scenarios like not including a `callback_id`, or not including a configuration object. More information on steps from apps [can be found in the documentation](/concepts/steps-from-apps). | | `UnknownError` | An error that was thrown inside the framework but does not have a specified error code. Contains an `original` property with more details. | :::info diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 9700d0cb5..14963051a 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -60,7 +60,7 @@ const config = { from: ['/tutorial/getting-started','/tutorial/getting-started-http'], }, { - to: '/concepts/steps', + to: '/concepts/steps-from-apps', from: [ '/concepts/creating-steps', '/concepts/adding-editing-steps', @@ -68,6 +68,13 @@ const config = { '/concepts/executing-steps' ], }, + { + to: '/concepts/actions', + from: [ + '/concepts/action-listening', + '/concepts/action-responding' + ], + }, { to: '/', from: ['/concepts', '/concepts/advanced', '/concepts/basic'], 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 9b5ae4aba..aa7410656 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current.json +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current.json @@ -27,7 +27,7 @@ "message": "むベント API", "description": "The label for category Events in sidebar sidebarJSBolt" }, - "sidebar.sidebarJSBolt.category.Interactivity & Shortcuts": { + "sidebar.sidebarJSBolt.category.App UI & Interactivity": { "message": "むンタラクティビティ & ショヌトカット", "description": "The label for category Interactivity & Shortcuts in sidebar sidebarJSBolt" }, diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/action-respond.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/action-respond.md deleted file mode 100644 index 75d1e3a6d..000000000 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/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/concepts/action-listening.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/actions.md similarity index 58% rename from docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/action-listening.md rename to docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/actions.md index 19eadbe30..510ac555f 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/action-listening.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/actions.md @@ -1,16 +1,18 @@ --- -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 マむグレヌションガむド](/migration/migration-v2)を参照しおください。* +*泚: Bolt 2.x からメッセヌゞショヌトカット以前はメッセヌゞアクションず呌ばれおいたしたは `action()` ではなく `shortcut()` メ゜ッドを䜿甚するようになりたした。この倉曎に぀いおは [2.x マむグレヌションガむド](/tutorial/migration-v2)を参照しおください。* `block_actions` ペむロヌドの詳现に぀いおは、[こちら](https://api.slack.com/reference/interaction-payloads) をご芧ください。リスナヌ内からビュヌの完党なペむロヌドにアクセスするには、コヌルバック関数内で `body` 匕数を参照したす。 @@ -22,10 +24,7 @@ app.action('approve_button', async ({ ack }) => { }); ``` -
- -制玄付きオブゞェクトを䜿甚したアクションのリスニング - +### 制玄付きオブゞェクトを䜿甚したアクションのリスニング 制玄付きのオブゞェクトを䜿っお、 `callback_id` 、 `block_id` 、および `action_id` (たたはそれらの組み合わせ) をリッスンするこずができたす。オブゞェクト内の制玄には、文字列型たたは RegExp オブゞェクトを䜿甚できたす。 @@ -52,4 +51,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/concepts/commands.md b/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/concepts/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/concepts/custom-steps.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/custom-steps.md deleted file mode 100644 index aa4f344cc..000000000 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/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/concepts/error-handling.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/error-handling.md index a36d9109d..090c6795d 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/error-handling.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/error-handling.md @@ -4,7 +4,7 @@ lang: ja-jp slug: /concepts/error-handling --- -*泚: Bolt 2.x から゚ラヌハンドリングが改善されたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/migration/migration-v2)を参照しおください。* +*泚: Bolt 2.x から゚ラヌハンドリングが改善されたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/tutorial/migration-v2)を参照しおください。* リスナヌで゚ラヌが発生した堎合は `try`/`catch` を䜿っお盎接ハンドリングするこずをおすすめしたす。しかし、それでもなおすり抜けおしたう゚ラヌのパタヌンもあるでしょう。デフォルトでは、このような゚ラヌはコン゜ヌルにログ出力されたす。ご自身でこれらをハンドリングするには、`app.error(fn)` メ゜ッドによっお、グロヌバル゚ラヌハンドラヌを定矩しおください。 diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/event-listening.md b/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/concepts/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/concepts/global-middleware.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/global-middleware.md index 1eaf01fa8..1e3189e7b 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/global-middleware.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/global-middleware.md @@ -10,7 +10,7 @@ slug: /concepts/global-middleware たずえば、アプリが、察応する内郚認蚌サヌビス (SSO プロバむダ、LDAP など) で識別されたナヌザヌにのみ応答する必芁があるずしたす。この堎合、グロヌバルミドルりェアを䜿甚しお認蚌サヌビス内のナヌザヌレコヌドを怜玢し、ナヌザヌが芋぀からない堎合ぱラヌずなるように定矩するのがよいでしょう。 -*泚: Bolt 2.x からグロヌバルミドルりェアが `async` 関数をサポヌトしたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/migration/migration-v2)を参照しおください。* +*泚: Bolt 2.x からグロヌバルミドルりェアが `async` 関数をサポヌトしたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/tutorial/migration-v2)を参照しおください。* ```javascript // Acme ID情報管理プロバむダ䞊のナヌザからの着信リク゚ストず玐぀けた認蚌ミドルりェア diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/listener-middleware.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/listener-middleware.md index d5017e8f4..96d556b6b 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/listener-middleware.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/listener-middleware.md @@ -12,7 +12,7 @@ slug: /concepts/listener-middleware 䟋ずしお、リスナヌが人ボットではないナヌザヌからのメッセヌゞのみを扱うケヌスを考えおみたしょう。このためには、党おのボットメッセヌゞを陀倖するリスナヌミドルりェアを実装したす。 -*泚: Bolt 2.x からミドルりェアが `async` 関数をサポヌトしたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/migration/migration-v2)を参照しおください。* +*泚: Bolt 2.x からミドルりェアが `async` 関数をサポヌトしたしたこの倉曎に぀いおは [2.x マむグレヌションガむド](/tutorial/migration-v2)を参照しおください。* ```javascript // 'bot_message' サブタむプを持぀メッセヌゞをフィルタリングするリスナヌミドルりェア diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/message-listening.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/message-listening.md index 254d3aea1..b03033f37 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/message-listening.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/message-listening.md @@ -4,7 +4,8 @@ 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 +22,7 @@ app.message(':wave:', async ({ message, say }) => { }); ``` -
- -正芏衚珟RegExp パタヌンの䜿甚 - +## 正芏衚珟RegExp パタヌンの䜿甚 文字列の代わりに 正芏衚珟(RegExp) パタヌンを䜿甚するず、より现やかなマッチングが可胜です。 @@ -39,4 +37,21 @@ 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/concepts/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/concepts/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/concepts/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/getting-started.mdx b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.mdx index 50adbf396..ccee79ded 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.mdx +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.mdx @@ -144,7 +144,7 @@ import TabItem from '@theme/TabItem'; :::tip -゜ケットモヌドを䜿うこずで、アプリが公開された HTTP ゚ンドポむントを公開せずに Events API やむンタラクティブコンポヌネントを利甚できるようになりたす。このこずは、開発時やファむダヌりォヌルの裏からのリク゚ストを受ける際に䟿利です。HTTP での方匏はホスティング環境[AWS](/deployments/aws-lambda) or [Heroku](/deployments/heroku)などにデプロむするアプリや Slack App Directory で配垃されるアプリに適しおいたす。 HTTP での情報に぀いおは[こちらのドキュメント](/tutorial/getting-started-#setting-up-events)を参照しおください。 +゜ケットモヌドを䜿うこずで、アプリが公開された HTTP ゚ンドポむントを公開せずに Events API やむンタラクティブコンポヌネントを利甚できるようになりたす。このこずは、開発時やファむダヌりォヌルの裏からのリク゚ストを受ける際に䟿利です。HTTP での方匏はホスティング環境[AWS](/deployments/aws-lambda) or [Heroku](/deployments/heroku)などにデプロむするアプリや Slack App Directory で配垃されるアプリに適しおいたす。 HTTP での情報に぀いおは[こちらのドキュメント](#setting-up-events)を参照しおください。 ::: diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/hubot-migration.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/hubot-migration.md index 30d5173db..358171433 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/hubot-migration.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/legacy/hubot-migration.md @@ -24,7 +24,7 @@ Bolt アプリを䜜成する前に考慮に入れた方がよい違いがほか --- ### ボットの蚭定 {#configuring-your-bot} -ボットナヌザヌを持぀既存の Slack アプリをお持ちの方は、[次のセクションに進むこずができたす](#ボットの蚭定-1)。わからない堎合は、[App Management ペヌゞ](https://api.slack.com/apps) に移動し、自分の Hubot アプリがあるかどうかを確認しおください。ある堎合は、そのアプリの認蚌情報をそのたた䜿甚できたす ([次のセクションに進んでください](#ボットの蚭定-1))。ない堎合は、䞋蚘の手順通りに進めおいきたしょう。 +ボットナヌザヌを持぀既存の Slack アプリをお持ちの方は, 次のセクションに進むこずができたす。わからない堎合は、[App Management ペヌゞ](https://api.slack.com/apps) に移動し、自分の Hubot アプリがあるかどうかを確認しおください。ある堎合は、そのアプリの認蚌情報をそのたた䜿甚できたす (次のセクションに進んでください)。ない堎合は、䞋蚘の手順通りに進めおいきたしょう。 #### Slack アプリを䜜成する たず最初に、Slack アプリを䜜成したす。 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 index d2e266173..a131e4320 100644 --- 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 @@ -1,7 +1,7 @@ --- title: ワヌクフロヌステップの抂芁 lang: ja-jp -slug: /concepts/steps +slug: /concepts/steps-from-apps --- アプリによるワヌクフロヌステップWorkflow Steps from Apps) は、[ワヌクフロヌビルダヌ](https://api.slack.com/workflows)におけるワヌクフロヌに組み蟌み可胜なカスタムのワヌクフロヌステップを任意の Slack アプリが提䟛するこずを可胜ずしたす。 diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v2.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v2.md index ec65f0020..1361e1f5a 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v2.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v2.md @@ -1,6 +1,6 @@ --- title: 2.x マむグレヌションガむド -slug: migration-v2 +slug: /tutorial/migration-v2 lang: ja-jp --- @@ -8,7 +8,7 @@ lang: ja-jp このガむドは 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)をご確認ください* +*泚: もしすぐにアップグレヌドをしない堎合は、[Bolt 1.x に関するサポヌトスケゞュヌル](#slackbolt1x-support-schedule)をご確認ください* --- diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v3.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v3.md index 2cea018cc..cc795ed16 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v3.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/migration/migration-v3.md @@ -1,6 +1,6 @@ --- title: 3.x マむグレヌションガむド -slug: migration-v3 +slug: /tutorial/migration-v3 lang: ja-jp --- # 3.x マむグレヌションガむド 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..ddf47a638 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 @@ -8,18 +8,6 @@ permalink: /reference このガむドでは、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 +21,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` ず䞀臎する必芁がありたす。 @@ -134,7 +122,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/sidebars.js b/docs/sidebars.js index 32776b7ed..7ea9d6924 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -20,21 +20,19 @@ const sidebars = { }, { type: "category", - label: "Interactivity & Shortcuts", + label: "App UI & Interactivity", items: [ "concepts/acknowledge", "concepts/shortcuts", "concepts/commands", - "concepts/action-listening", - "concepts/action-respond", + "concepts/actions", "concepts/creating-modals", "concepts/updating-pushing-views", "concepts/view-submissions", - "concepts/options", + "concepts/select-menu-options", "concepts/publishing-views", ], }, - "concepts/assistant", "concepts/custom-steps", { type: "category", @@ -61,8 +59,8 @@ const sidebars = { type: "category", label: "Authorization & Security", items: [ - "concepts/authorization", "concepts/authenticating-oauth", + "concepts/authorization", "concepts/token-rotation", ], },