diff --git a/docs/content/guides/bolt-basics.md b/docs/content/guides/bolt-basics.md index 9ae3c6ec8..2a9e22147 100644 --- a/docs/content/guides/bolt-basics.md +++ b/docs/content/guides/bolt-basics.md @@ -31,19 +31,20 @@ Here is the list of the available methods to dispatch events. |Method|Constraints (value: type)|Description| |-|-|-| -|`app.event`|event type: `Class\`|[Events API](/guides/events-api): Responds to any kinds of bot/user events you subscribe.| -|`app.message`|keyword: `String` \| `Pattern`|[Events API](/guides/events-api): Responds to messages posted by a user only when the text in messages matches the given keyword or regular expressions.| -|`app.command`|command name: `String` \| `Pattern`|[Slash Commands](/guides/slash-commands): Responds to slash command invocations in the workspace.| +|`app.attachmentAction`|callback_id: `String` \| `Pattern`|Legacy Messaging: Responds to user actions in attachments. These events can be triggered in only messages.| |`app.blockAction`|action_id: `String` \| `Pattern`|[Interactive Components](/guides/interactive-components): Responds to user actions (e.g., click a button, choose an item from select menus, radio buttons, etc.) in `blocks`. These events can be triggered in all the surfaces (messages, modals, and Home tabs).| |`app.blockSuggestion`|action_id: `String` \| `Pattern`|[Interactive Components](/guides/interactive-components): Responds to user actions to input a keyword (the length needs to be the `min_query_length` or longer) in select menus (external data source).| -|`app.viewSubmission`|callback_id: `String` \| `Pattern`|[Modals](/guides/modals): Responds to data submissions in modals.| -|`app.viewClosed`|callback_id: `String` \| `Pattern`|[Modals](/guides/modals): Responds to the events where users close modals by clicking Cancel buttons. The `notify_on_close` has to be `true` when opening/pushing the modal.| -|`app.globalShortcut`|callback_id: `String` \| `Pattern`|[Shortcuts](/guides/shortcuts): Responds to global shortcut invocations.| -|`app.messageShortcut`|callback_id: `String` \| `Pattern`|[Shortcuts](/guides/shortcuts): Responds to shortcut invocations in message menus.| +|`app.command`|command name: `String` \| `Pattern`|[Slash Commands](/guides/slash-commands): Responds to slash command invocations in the workspace.| +|`app.dialogCancellation`|callback_id `String` \| `Pattern`|Dialogs: Responds to the events where users close dialogs by clicking Cancel buttons.| |`app.dialogSubmission`|callback_id: `String` \| `Pattern`|Dialogs: Responds to data submissions in dialogs.| |`app.dialogSuggestion`|callback_id: `String` \| `Pattern`|Dialogs: Responds to requests to load options for `"external"` typed select menus in dialogs.| -|`app.dialogCancellation`|callback_id `String` \| `Pattern`|Dialogs: Responds to the events where users close dialogs by clicking Cancel buttons.| -|`app.attachmentAction`|callback_id: `String` \| `Pattern`|Legacy Messaging: Responds to user actions in attachments. These events can be triggered in only messages.| +|`app.event`|event type: `Class\`|[Events API](/guides/events-api): Responds to any kinds of bot/user events you subscribe.| +| `app.function` | callback_id: `String` \| `Pattern` | [Custom steps](/guides/custom-steps): Defines a function that can be used as a custom step in [Workflow Builder](https://slack.com/help/articles/360035692513-Guide-to-Slack-Workflow-Builder). +|`app.globalShortcut`|callback_id: `String` \| `Pattern`|[Shortcuts](/guides/shortcuts): Responds to global shortcut invocations.| +|`app.message`|keyword: `String` \| `Pattern`|[Events API](/guides/events-api): Responds to messages posted by a user only when the text in messages matches the given keyword or regular expressions.| +|`app.messageShortcut`|callback_id: `String` \| `Pattern`|[Shortcuts](/guides/shortcuts): Responds to shortcut invocations in message menus.| +|`app.viewClosed`|callback_id: `String` \| `Pattern`|[Modals](/guides/modals): Responds to the events where users close modals by clicking Cancel buttons. The `notify_on_close` has to be `true` when opening/pushing the modal.| +|`app.viewSubmission`|callback_id: `String` \| `Pattern`|[Modals](/guides/modals): Responds to data submissions in modals.| --- ## Development Guides by Feature diff --git a/docs/content/guides/custom-steps.md b/docs/content/guides/custom-steps.md new file mode 100644 index 000000000..d14aaad5b --- /dev/null +++ b/docs/content/guides/custom-steps.md @@ -0,0 +1,77 @@ +--- +title: Custom Steps +lang: en +--- + +Your app can use the `function()` method to listen to incoming [custom step requests](https://docs.slack.dev/workflows/workflow-steps). 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://docs.slack.dev/reference/app-manifest#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 `getInputs()` method shown below. + +```java +app.function("sample_function", (req, ctx) -> { + app.executorService().submit(() -> { + try { + String userId = req.getEvent().getInputs().get("user_id").asString(); + ChatPostMessageResponse response = ctx.client().chatPostMessage(r -> r + .channel(userId) // sending a DM + .text("Hi! Thank you for submitting the request! We'll let you know once the processing completes.") + ); + Map outputs = new HashMap(); + outputs.put("channel_id", response.getChannel()); + outputs.put("ts", response.getTs()); + ctx.complete(outputs); + } catch (Exception e) { + ctx.logger.error(e.getMessage(), e); + try { + ctx.fail("Failed to handle 'sample_function' custom step execution (error: " + e.getMessage() + ")"); + } catch (Exception ex) { + ctx.logger.error(e.getMessage(), e); + } + } + }); + return ctx.ack(); +}); +``` + +The corresponding function definition section of the app manifest for the preceding function might look like this: + +```json +... +"functions": { + "sample_function": { + "title": "Send a request", + "description": "Send some request to the backend", + "input_parameters": { + "user_id": { + "type": "slack#/types/user_id", + "title": "User", + "description": "Who to send it", + "is_required": true, + "hint": "Select a user in the workspace", + "name": "user_id" + } + }, + "output_parameters": { + "channel_id": { + "type": "slack#/types/channel_id", + "title": "DM ID", + "description": "The DM ID", + "is_required": true, + "name": "channel_id" + }, + "ts": { + "type": "string", + "title": "Message timestamp", + "description": "Sent message timestamp", + "is_required": true, + "name": "ts" + } + } + } +} +``` + +Once your custom step is defined in your app's manifest and implemented in code, it is discoverable in Workflow Builder when you **Add Step** and search for the title of your step or name of your app. \ No newline at end of file diff --git a/docs/sidebars.js b/docs/sidebars.js index dc7f90506..52390a925 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -36,6 +36,7 @@ const sidebars = { items: ['guides/interactive-components', 'guides/modals', 'guides/app-home',], }, 'guides/ai-apps', + 'guides/custom-steps', 'guides/shortcuts', 'guides/slash-commands', {