From de43298d4dcc24fab7c0cce2870bdc7c6b4b2f6f Mon Sep 17 00:00:00 2001 From: Ashley Huynh Date: Tue, 27 Sep 2022 16:19:35 -0400 Subject: [PATCH 1/3] Add in Hello World example across docs --- docs/_future/app_manifests.md | 47 +++++++++++++++-------- docs/_future/built_in_functions.md | 15 ++++---- docs/_future/custom_functions.md | 36 ++++++++++------- docs/_future/getting_started_future.md | 4 +- docs/_future/request_time_off_tutorial.md | 2 +- docs/_future/triggers.md | 6 ++- 6 files changed, 66 insertions(+), 44 deletions(-) diff --git a/docs/_future/app_manifests.md b/docs/_future/app_manifests.md index 4b4700ad6..d3bff50e0 100644 --- a/docs/_future/app_manifests.md +++ b/docs/_future/app_manifests.md @@ -9,7 +9,7 @@ permalink: /future/app-manifests # App manifests BETA
-An app's manifest is where you can configure its name and scopes, declare the functions your app will use, and more. +An app's manifest is where you can configure its name and scopes, declare the functions your app will use, and more.
--- @@ -18,40 +18,53 @@ An app's manifest is where you can configure its name and scopes, declare the fu Locate the file named `manifest.js` within your application. This will likely be in your project's root directory or a `manifest` folder. -Inside the manifest file, you will find an `module.exports = Manifest({})` block that defines the app's configuration: +Inside the manifest file, you will find an `module.exports = Manifest({})` block that defines the app's configuration. For the [Hello World application](https://github.com/slack-samples/bolt-js-starter-template/tree/future) in the Bolt for JavaScript Starter Template, it will look something like this: ```javascript // manifest/manifest.js const { Manifest } = require('@slack/bolt'); -const { TimeOffWorkflow } = require('./workflows/approval'); +const { SampleWorkflow } = require('./workflow/sample-workflow'); +/** + * The app manifest contains the app's configuration. This + * file defines attributes like app name and description. + * https://api.slack.com/future/manifest + */ module.exports = Manifest({ runOnSlack: false, - // This is the internal name for your app. - // It can contain spaces (e.g., "My App") - name: 'take-your-time', - displayName: 'Take Your Time', - // A description of your app that will help users decide whether to use it. - description: 'Request and take time off.', - longDescription: 'Take your time off by using this application to request and take time off from your manager. Launch the workflow, put in your manager, requested PTO start and end date, and receive updates on your PTO request!', - botScopes: ['chat:write'], - tokenManagementEnabled: true, + name: 'Bolt Template App TEST', + displayName: 'Bolt Template App TEST', + description: 'A starter app template built with Bolt JS', + botScopes: ['channels:history', 'chat:write', 'commands', 'chat:write.public'], + eventSubscriptions: { bot_events: ['app_home_opened', 'message.channels'] }, socketModeEnabled: true, - // A list of all workflows your app will use. - workflows: [TimeOffWorkflow], + workflows: [SampleWorkflow], features: { appHome: { homeTabEnabled: true, - messagesTabEnabled: true, + messagesTabEnabled: false, messagesTabReadOnlyEnabled: true, }, + botUser: { + always_online: false, + }, + shortcuts: [{ + name: 'Run sample shortcut', + type: 'global', + callback_id: 'sample_shortcut_id', + description: 'Runs a sample shortcut', + }], + slashCommands: [{ + command: '/sample-command', + description: 'Runs a sample command', + should_escape: false, + }], }, settings: { interactivity: { is_enabled: true, }, }, - tokenRotationEnabled: false, }); ``` --- @@ -84,4 +97,4 @@ You will come back to the Manifest every time you create a new workflow, since a ### Next steps {#next-steps} -Now that you're acquainted with the Manifest, you can now dive into the world of [built-in functions](/bolt-js/future/built-in-functions) and [custom functions](/bolt-js/future/custom-functions)! +Now that you're acquainted with the Manifest, you can dive into the world of [built-in functions](/bolt-js/future/built-in-functions) and [custom functions](/bolt-js/future/custom-functions)! diff --git a/docs/_future/built_in_functions.md b/docs/_future/built_in_functions.md index 3e725df97..10a9876e6 100644 --- a/docs/_future/built_in_functions.md +++ b/docs/_future/built_in_functions.md @@ -23,20 +23,19 @@ Built-in functions need to be imported from the standard library built into the Built-in functions define their own inputs and outputs, as detailed for each built-in below. -Here's an example of a Workflow that creates a new Slack channel using the `CreateChannel` built-in function: +Here's an example of a Workflow that sends a message using the `SendMessage` built-in function: ```javascript const { DefineWorkflow, Schema } = require('@slack/bolt'); ... -const createChannelStep = myWorkflow.addStep( - Schema.slack.functions.CreateChannel, - { - channel_name: myWorkflow.inputs.channel_name, - is_private: false, - }, -); +SampleWorkflow.addStep(Schema.slack.functions.SendMessage, { + channel_id: inputForm.outputs.fields.channel, + message: greetingFunctionStep.outputs.greeting, +}); + +module.exports = { SampleWorkflow }; ``` Read the full documentation for [Workflows](/bolt-js/future/workflows) to learn how to build out Workflows. diff --git a/docs/_future/custom_functions.md b/docs/_future/custom_functions.md index cc5b6f351..5d8c78438 100644 --- a/docs/_future/custom_functions.md +++ b/docs/_future/custom_functions.md @@ -29,16 +29,13 @@ const SampleFunctionDefinition = DefineFunction({ callback_id: 'sample_function_id', title: 'Send a greeting', description: 'Send greeting to channel', + source_file: 'functions/sample-function.ts', input_parameters: { properties: { recipient: { type: Schema.slack.types.user_id, description: 'Send greeting to this recipient', }, - channel: { - type: Schema.slack.types.channel_id, - description: 'Channel to send message to', - }, message: { type: Schema.types.string, description: 'Message to the recipient', @@ -46,6 +43,15 @@ const SampleFunctionDefinition = DefineFunction({ }, required: ['message'], }, + output_parameters: { + properties: { + greeting: { + type: Schema.types.string, + description: 'Greeting for the recipient', + }, + }, + required: ['greeting'], + }, }); module.exports = { SampleFunctionDefinition }; @@ -69,7 +75,7 @@ The value for properties in `input_parameters` and `output_parameters` needs to * `type`: The type of the input parameter. This can be a [Built-in type](https://api.slack.com/future/types) or a [Custom type](https://api.slack.com/future/types/custom) that you define. * `description`: A string description of the parameter. -If you want to set a property as required, list its name in its respective input or output properties `required` property. +If you want to set a property as required, list its name in its respective input or output properties as a `required` property. For example, if you have an input parameter named `customer_id` that you want to be required, you can do so like this: @@ -113,22 +119,20 @@ To do this, create a file in `listeners/functions` directory for your function l ```js // listeners/functions/hello-world.js // For more information about functions: https://api.slack.com/future/functions +// For more information about functions: https://api.slack.com/future/functions const { SlackFunction } = require('@slack/bolt'); // Get our Function Definition from the manifest! -const { SampleFunctionDefinition } = require('../../manifest/functions/sample-function'); +const { SampleFunctionDefinition } = require('../../manifest/function/sample-function'); // Here is the work we want to do! -const helloWorld = async ({ event, client, complete }) => { - const { recipient, channel, message } = event.inputs; +const helloWorld = async ({ event, complete }) => { + const { recipient, message } = event.inputs; const salutations = ['Hello', 'Hi', 'Howdy', 'Hola', 'Salut']; const salutation = salutations[Math.floor(Math.random() * salutations.length)]; try { - await client.chat.postMessage({ - channel, - text: `${salutation}, <@${recipient}>! :wave: Someone sent the following greeting: \n\n>${message}`, - }); - complete(); + const greeting = `${salutation}, <@${recipient}>! :wave: Someone sent the following greeting: \n\n>${message}`; + complete({ outputs: { greeting } }); } catch (err) { // Complete function with an error await complete({ error: `There was an issue: ${err}` }); @@ -141,7 +145,7 @@ const helloWorldFunc = new SlackFunction(SampleFunctionDefinition.id, helloWorld module.exports = { helloWorldFunc }; ``` -The `hello-world.js` file declares a function handler, `helloWorld`, that takes in inputs from the `event`, which is the payload received when your function is being executed. It executes logic within the handler to send a message with a random greeting to the specified recipient in the desired channel. Then, a new `SlackFunction` instance is declared that actually links the `helloWorld` handler to `SampleFunctionDefinition` through the function's ID: +The `hello-world.js` file declares a function handler, `helloWorld`, that takes in inputs from the `event`, which is the payload received when your function is being executed. It executes logic within the handler to return a message with a random greeting. This message is the function's output. In addition to the function handler, a new `SlackFunction` instance is declared that actually links the `helloWorld` handler to `SampleFunctionDefinition` through the function's ID: ```js // Let's create a new Slack Function with helloWorld as its handler const helloWorldFunc = new SlackFunction(SampleFunctionDefinition.id, helloWorld); @@ -171,3 +175,7 @@ module.exports.registerListeners = (app) => { ``` #### 3. Add the function as a step in your workflow To actually call the defined function, `SampleFunctionDefinition`, don't forget to add your function to a workflow! When you're finished defining and implementing your functions, the next step is to add them to [Workflows](/bolt-js/future/workflows). Once added as a step in a Workflow, your Function will run when that Workflow is invoked by a [Trigger](/bolt-js/future/triggers). + +--- +### Next steps +You've learned about built-in and custom functions - now it's time to jump into [Workflows](/bolt-js/future/workflows) and learn about how they work with Functions. 🎉 diff --git a/docs/_future/getting_started_future.md b/docs/_future/getting_started_future.md index f7afae871..7f8dd4853 100644 --- a/docs/_future/getting_started_future.md +++ b/docs/_future/getting_started_future.md @@ -130,13 +130,13 @@ Once the app is successfully run, you'll see output in your Terminal to indicate With your app running, access your workspace and paste the URL from the Trigger you created in the previous step into a message in a public channel. -> 💡 To make the trigger URL more widely accessible, we recommend saving the Trigger as a channel bookmark for easy access. +> 💡 The Trigger will automatically be saved as a channel bookmark under "Workflows" for easy access. Send the message and click the "Run" button that appears. A modal will appear prompting you to enter information to greet someone in your Slack workspace. Fill out the requested information. ![Hello World modal](../assets/hello-world-modal.png "Hello World modal") -Then, submit the form. In the specified channel submitted in the form, you should receive a message from the app tagging the submitted user. The message will also contain a randomly generated greeting and the message you wrote in the form.. +Then, submit the form. In the specified channel submitted in the form, you should receive a message from the app tagging the submitted user. The message will also contain a randomly generated greeting and the message you wrote in the form. The full app flow can be seen here: ![Hello World app](../assets/hello-world-demo.gif "Hello World app") diff --git a/docs/_future/request_time_off_tutorial.md b/docs/_future/request_time_off_tutorial.md index 7e340dc4b..58a9c938b 100644 --- a/docs/_future/request_time_off_tutorial.md +++ b/docs/_future/request_time_off_tutorial.md @@ -96,7 +96,7 @@ Once the app is successfully run, you'll see output in your Terminal to indicate With your app running, access your workspace and paste the URL from the Trigger you created in the previous step into a message in a public channel. -> 💡 To make the trigger URL more widely accessible, we recommend saving the Trigger as a channel bookmark for easy access. +> 💡 The Trigger will automatically be saved as a channel bookmark under "Workflows" for easy access. Send the message and click the "Run" button that appears. A modal will appear prompting you to enter information to request time off. To test your app properly, we recommend entering your own Slack username in the "Manager" field. diff --git a/docs/_future/triggers.md b/docs/_future/triggers.md index 28fe026de..cb72c3ed7 100644 --- a/docs/_future/triggers.md +++ b/docs/_future/triggers.md @@ -39,6 +39,8 @@ Triggers created with the CLI are designed using Trigger Files. The Trigger File The specifics of the Trigger File's structure will depend on what [type of Trigger](#types) you want to use. +The Hello World app from the Bolt for JavaScript starter template uses a Link Trigger, which is one of the [Trigger types](#types). You can view its Trigger File [here](https://github.com/slack-samples/bolt-js-starter-template/blob/future/triggers/hello-world-trigger.json). + **2. Run the** `trigger create` **command** Use the `trigger create` command to create your desired Trigger by pointing to a Trigger File. @@ -75,7 +77,7 @@ const triggerResponse = await client.workflows.triggers.create({ The response will have a property called `ok`. If `true`, then the Trigger was created, and the `trigger` property will be populated. -Your response will include a `trigger.id`; be sure to store it! You use that to `update` or `delete` the Trigger if need be. +Your response will include a `trigger.id`; be sure to store it! You will use that to `update` or `delete` the Trigger if need be. #### Development and production Triggers @@ -128,4 +130,4 @@ To learn more about this, visit the guide [here](https://api.slack.com/future/tr And that's the end of our triumphant trek learning about Triggers! -If you want to see Triggers in action with their pals, the Function and the Workflow, check out our sample [Request Time Off](https://github.com/slack-samples/bolt-js-request-time-off) app within our GitHub repository. +If you want to see Triggers in action with their pals, the Function and the Workflow, check out our sample [Hello World](https://github.com/slack-samples/bolt-js-starter-template/tree/future) app. For a more complex example, you can take a look at our [Request Time Off](https://github.com/slack-samples/bolt-js-request-time-off) app and its end-to-end [tutorial](/bolt-js/future/request-time-off-tutorial). From 8956aacb70193888f638bcea4a4d5c00df336de7 Mon Sep 17 00:00:00 2001 From: Ashley Huynh Date: Mon, 3 Oct 2022 14:58:50 -0400 Subject: [PATCH 2/3] Get rid of duplicate comment --- docs/_future/custom_functions.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/_future/custom_functions.md b/docs/_future/custom_functions.md index 5d8c78438..7fbfaadf9 100644 --- a/docs/_future/custom_functions.md +++ b/docs/_future/custom_functions.md @@ -119,7 +119,6 @@ To do this, create a file in `listeners/functions` directory for your function l ```js // listeners/functions/hello-world.js // For more information about functions: https://api.slack.com/future/functions -// For more information about functions: https://api.slack.com/future/functions const { SlackFunction } = require('@slack/bolt'); // Get our Function Definition from the manifest! From d51f86a2520b034866eaef52e85cd83dec7caf01 Mon Sep 17 00:00:00 2001 From: Ashley Huynh Date: Mon, 3 Oct 2022 16:45:45 -0400 Subject: [PATCH 3/3] Add in updates from feedback --- docs/_future/custom_functions.md | 7 +++---- docs/_future/getting_started_future.md | 2 +- docs/_future/request_time_off_tutorial.md | 2 +- docs/_future/triggers.md | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/_future/custom_functions.md b/docs/_future/custom_functions.md index 7fbfaadf9..8b30c470f 100644 --- a/docs/_future/custom_functions.md +++ b/docs/_future/custom_functions.md @@ -21,7 +21,7 @@ To create a function, we need to do the following: ### Defining a function {#define} Functions are defined in your app via the `DefineFunction` method, which is part of the SDK that gets included with every newly created project. These function definitions are stored under the `manifest/functions/` directory. -Let's go ahead and create a new function definition file under `manifest/functions` directory. Name it something related to what the function does. In our [Bolt for JavaScript Starter Template](https://github.com/slack-samples/bolt-js-starter-template/blob/future/manifest/function/sample-function.js), we name the file `sample-function.js`. Let's take a peek at it: +Let's go ahead and create a new function definition file under `manifest/functions` directory. Name it something related to what the function does. In our [Bolt for JavaScript Starter Template](https://github.com/slack-samples/bolt-js-starter-template/blob/future/manifest/functions/sample-function.js), we name the file `sample-function.js`. Let's take a peek at it: ```js const { DefineFunction, Schema } = require('@slack/bolt'); @@ -29,7 +29,6 @@ const SampleFunctionDefinition = DefineFunction({ callback_id: 'sample_function_id', title: 'Send a greeting', description: 'Send greeting to channel', - source_file: 'functions/sample-function.ts', input_parameters: { properties: { recipient: { @@ -108,7 +107,7 @@ Once your function is defined in its own file in `manifest/functions`, the next Implement functions in just a few steps: #### 1. Create the function definition file in the `manifest/functions` directory -If you haven't done so already, create a file for your function definition to live in and name it something that makes sense for your function. In the [Bolt for JavaScript Starter Template](https://github.com/slack-samples/bolt-js-starter-template/blob/future/manifest/function/sample-function.js), we named this file `sample-function.js` +If you haven't done so already, create a file for your function definition to live in and name it something that makes sense for your function. In the [Bolt for JavaScript Starter Template](https://github.com/slack-samples/bolt-js-starter-template/blob/future/manifest/functions/sample-function.js), we named this file `sample-function.js` #### 2. Add function listener and handler(s) @@ -122,7 +121,7 @@ To do this, create a file in `listeners/functions` directory for your function l const { SlackFunction } = require('@slack/bolt'); // Get our Function Definition from the manifest! -const { SampleFunctionDefinition } = require('../../manifest/function/sample-function'); +const { SampleFunctionDefinition } = require('../../manifest/functions/sample-function'); // Here is the work we want to do! const helloWorld = async ({ event, complete }) => { diff --git a/docs/_future/getting_started_future.md b/docs/_future/getting_started_future.md index 7f8dd4853..51f4beb67 100644 --- a/docs/_future/getting_started_future.md +++ b/docs/_future/getting_started_future.md @@ -130,7 +130,7 @@ Once the app is successfully run, you'll see output in your Terminal to indicate With your app running, access your workspace and paste the URL from the Trigger you created in the previous step into a message in a public channel. -> 💡 The Trigger will automatically be saved as a channel bookmark under "Workflows" for easy access. +> 💡 App Triggers are automatically saved as a channel bookmark under "Workflows" for easy access. Send the message and click the "Run" button that appears. A modal will appear prompting you to enter information to greet someone in your Slack workspace. Fill out the requested information. diff --git a/docs/_future/request_time_off_tutorial.md b/docs/_future/request_time_off_tutorial.md index 58a9c938b..3aca17a3e 100644 --- a/docs/_future/request_time_off_tutorial.md +++ b/docs/_future/request_time_off_tutorial.md @@ -96,7 +96,7 @@ Once the app is successfully run, you'll see output in your Terminal to indicate With your app running, access your workspace and paste the URL from the Trigger you created in the previous step into a message in a public channel. -> 💡 The Trigger will automatically be saved as a channel bookmark under "Workflows" for easy access. +> 💡 App Triggers are automatically saved as a channel bookmark under "Workflows" for easy access. Send the message and click the "Run" button that appears. A modal will appear prompting you to enter information to request time off. To test your app properly, we recommend entering your own Slack username in the "Manager" field. diff --git a/docs/_future/triggers.md b/docs/_future/triggers.md index cb72c3ed7..b61c47a43 100644 --- a/docs/_future/triggers.md +++ b/docs/_future/triggers.md @@ -39,7 +39,7 @@ Triggers created with the CLI are designed using Trigger Files. The Trigger File The specifics of the Trigger File's structure will depend on what [type of Trigger](#types) you want to use. -The Hello World app from the Bolt for JavaScript starter template uses a Link Trigger, which is one of the [Trigger types](#types). You can view its Trigger File [here](https://github.com/slack-samples/bolt-js-starter-template/blob/future/triggers/hello-world-trigger.json). +The Hello World app from the Bolt for JavaScript starter template uses a Link Trigger, which is one of several [Trigger types](#types). You can view its Trigger File [here](https://github.com/slack-samples/bolt-js-starter-template/blob/future/triggers/hello-world-trigger.json). **2. Run the** `trigger create` **command**