Skip to content

Commit

Permalink
Update README (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
misscoded authored Apr 21, 2023
1 parent 1d8a72a commit 3f39fa5
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 103 deletions.
187 changes: 97 additions & 90 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,29 @@ CLI.
- [Setup](#setup)
- [Install the Slack CLI](#install-the-slack-cli)
- [Clone the Template](#clone-the-template)
- [Create a Link Trigger](#create-a-link-trigger)
- [Running Your Project Locally](#running-your-project-locally)
- [Creating Triggers](#creating-triggers)
- [Datastores](#datastores)
- [Testing](#testing)
- [Deploying Your App](#deploying-your-app)
- [Viewing Activity Logs](#viewing-activity-logs)
- [Viewing Activity Logs](#viewing-activity-logs)
- [Project Structure](#project-structure)
- [Resources](#resources)

---

## Setup

Before getting started, make sure you have a development workspace where you
have permissions to install apps. If you don’t have one set up, go ahead and
[create one](https://slack.com/create). Also, please note that the workspace
requires any of [the Slack paid plans](https://slack.com/pricing).
Before getting started, first make sure you have a development workspace where
you have permission to install apps. **Please note that the features in this
project require that the workspace be part of
[a Slack paid plan](https://slack.com/pricing).**

### Install the Slack CLI

To use this template, you first need to install and configure the Slack CLI.
To use this template, you need to install and configure the Slack CLI.
Step-by-step instructions can be found in our
[Quickstart Guide](https://api.slack.com/future/quickstart).
[Quickstart Guide](https://api.slack.com/automation/quickstart).

### Clone the Template

Expand All @@ -40,17 +40,45 @@ Start by cloning this repository:
# Clone this project onto your machine
$ slack create my-app -t slack-samples/deno-starter-template

# Change into this project directory
# Change into the project directory
$ cd my-app
```

## Create a Link Trigger
## Running Your Project Locally

While building your app, you can see your changes appear in your workspace in
real-time with `slack run`. You'll know an app is the development version if the
name has the string `(local)` appended.

```zsh
# Run app locally
$ slack run

Connected, awaiting events
```

To stop running locally, press `<CTRL> + C` to end the process.

[Triggers](https://api.slack.com/future/triggers) are what cause workflows to
run. These triggers can be invoked by a user, or automatically as a response to
an event within Slack.
## Creating Triggers

A [link trigger](https://api.slack.com/future/triggers/link) is a type of
[Triggers](https://api.slack.com/automation/triggers) are what cause workflows
to run. These triggers can be invoked by a user, or automatically as a response
to an event within Slack.

When you `run` or `deploy` your project for the first time, the CLI will prompt
you to create a trigger if one is found in the `triggers/` directory. For any
subsequent triggers added to the application, each must be
[manually added using the `trigger create` command](#manual-trigger-creation).

When creating triggers, you must select the workspace and environment that you'd
like to create the trigger in. Each workspace can have a local development
version (denoted by `(local)`), as well as a deployed version. _Triggers created
in a local environment will only be available to use when running the
application locally._

### Link Triggers

A [link trigger](https://api.slack.com/automation/triggers/link) is a type of
trigger that generates a **Shortcut URL** which, when posted in a channel or
added as a bookmark, becomes a link. When clicked, the link trigger will run the
associated workflow.
Expand All @@ -60,52 +88,28 @@ that Shortcut URLs will be different across each workspace, as well as between
[locally run](#running-your-project-locally) and
[deployed apps](#deploying-your-app).

When creating a trigger, you must select the workspace and environment that
you'd like to create the trigger in. Each workspace has a local development
version (denoted by `(dev)`), as well as a deployed version. Triggers created in
a local environment will only be available to use when running the application
locally.
With link triggers, after selecting a workspace and environment, the output
provided will include a Shortcut URL. Copy and paste this URL into a channel as
a message, or add it as a bookmark in a channel of the workspace you selected.
Interacting with this link will run the associated workflow.

To create a link trigger for the workflow in this template, run the following
command:
**Note: triggers won't run the workflow unless the app is either running locally
or deployed!**

```zsh
$ slack trigger create --trigger-def triggers/sample_trigger.ts
```

After selecting a workspace and environment, the output provided will include
the link trigger Shortcut URL. Copy and paste this URL into a channel as a
message, or add it as a bookmark in a channel of the workspace you selected.

**Note: this link won't run the workflow until the app is either running locally
or deployed!** Read on to learn how to run your app locally and eventually
deploy it to Slack hosting.

## Running Your Project Locally
### Manual Trigger Creation

While building your app, you can see your changes propagated to your workspace
in real-time with `slack run`. In both the CLI and in Slack, you'll know an app
is the development version if the name has the string `(dev)` appended.
To manually create a trigger, use the following command:

```zsh
# Run app locally
$ slack run

Connected, awaiting events
$ slack trigger create --trigger-def triggers/sample_trigger.ts
```

Once running, click the
[previously created Shortcut URL](#create-a-link-trigger) associated with the
`(dev)` version of your app. This should start the included sample workflow.

To stop running locally, press `<CTRL> + C` to end the process.

## Datastores

If your app needs to store any data, a datastore would be the right place for
that. For an example of a datastore, see `datastores/sample_datastore.ts`. Using
a datastore also requires the `datastore:write`/`datastore:read` scopes to be
present in your manifest.
For storing data related to your app, datastores offer secure storage on Slack
infrastructure. For an example of a datastore, see
`datastores/sample_datastore.ts`. The use of a datastore requires the
`datastore:write`/`datastore:read` scopes to be present in your manifest.

## Testing

Expand All @@ -121,72 +125,75 @@ $ deno test

## Deploying Your App

Once you're done with development, you can deploy the production version of your
app to Slack hosting using `slack deploy`:
Once development is complete, deploy the app to Slack infrastructure using
`slack deploy`:

```zsh
$ slack deploy
```

After deploying, [create a new link trigger](#create-a-link-trigger) for the
production version of your app (not appended with `(dev)`). Once the trigger is
invoked, the workflow should run just as it did in when developing locally.
When deploying for the first time, you'll be prompted to
[create a new link trigger](#creating-triggers) for the deployed version of your
app. When that trigger is invoked, the workflow should run just as it did when
developing locally (but without requiring your server to be running).

### Viewing Activity Logs
## Viewing Activity Logs

Activity logs for the production instance of your application can be viewed with
the `slack activity` command:
Activity logs of your application can be viewed live and as they occur with the
following command:

```zsh
$ slack activity
$ slack activity --tail
```

## Project Structure

### `manifest.ts`
### `.slack/`

The [app manifest](https://api.slack.com/future/manifest) contains the app's
configuration. This file defines attributes like app name and description.
Contains `apps.dev.json` and `apps.json`, which include installation details for
development and deployed apps.

### `slack.json`
### `datastores/`

Used by the CLI to interact with the project's SDK dependencies. It contains
script hooks that are executed by the CLI and implemented by the SDK.
[Datastores](https://api.slack.com/automation/datastores) securely store data
for your application on Slack infrastructure. Required scopes to use datastores
include `datastore:write` and `datastore:read`.

### `functions/`

### `/functions`
[Functions](https://api.slack.com/automation/functions) are reusable building
blocks of automation that accept inputs, perform calculations, and provide
outputs. Functions can be used independently or as steps in workflows.

[Functions](https://api.slack.com/future/functions) are reusable building blocks
of automation that accept inputs, perform calculations, and provide outputs.
Functions can be used independently or as steps in workflows.
### `triggers/`

### `/workflows`
[Triggers](https://api.slack.com/automation/triggers) determine when workflows
are run. A trigger file describes the scenario in which a workflow should be
run, such as a user pressing a button or when a specific event occurs.

A [workflow](https://api.slack.com/future/workflows) is a set of steps that are
executed in order. Each step in a workflow is a function.
### `workflows/`

A [workflow](https://api.slack.com/automation/workflows) is a set of steps
(functions) that are executed in order.

Workflows can be configured to run without user input or they can collect input
by beginning with a [form](https://api.slack.com/future/forms) before continuing
to the next step.
by beginning with a [form](https://api.slack.com/automation/forms) before
continuing to the next step.

### `/triggers`
### `manifest.ts`

[Triggers](https://api.slack.com/future/triggers) determine when workflows are
executed. A trigger file describes a scenario in which a workflow should be run,
such as a user pressing a button or when a specific event occurs.
The [app manifest](https://api.slack.com/automation/manifest) contains the app's
configuration. This file defines attributes like app name and description.

### `/datastores`
### `slack.json`

[Datastores](https://api.slack.com/future/datastores) can securely store and
retrieve data for your application. Required scopes to use datastores include
`datastore:write` and `datastore:read`.
Used by the CLI to interact with the project's SDK dependencies. It contains
script hooks that are executed by the CLI and implemented by the SDK.

## Resources

To learn more about developing with the CLI, you can visit the following guides:

- [Creating a new app with the CLI](https://api.slack.com/future/create)
- [Configuring your app](https://api.slack.com/future/manifest)
- [Developing locally](https://api.slack.com/future/run)
To learn more about developing automations on Slack, visit the following:

To view all documentation and guides available, visit the
[Overview page](https://api.slack.com/future/overview).
- [Automation Overview](https://api.slack.com/automation)
- [CLI Quick Reference](https://api.slack.com/automation/cli/quick-reference)
- [Samples and Templates](https://api.slack.com/automation/samples)
2 changes: 1 addition & 1 deletion datastores/sample_datastore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DefineDatastore, Schema } from "deno-slack-sdk/mod.ts";
/**
* Datastores are a Slack-hosted location to store
* and retrieve data for your app.
* https://api.slack.com/future/datastores
* https://api.slack.com/automation/datastores
*/
const SampleObjectDatastore = DefineDatastore({
name: "SampleObjects",
Expand Down
15 changes: 10 additions & 5 deletions functions/sample_function.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { DefineFunction, Schema, SlackFunction } from "deno-slack-sdk/mod.ts";
import SampleObjectDatastore from "../datastores/sample_datastore.ts";

/**
* Functions are reusable building blocks of automation that accept
* inputs, perform calculations, and provide outputs. Functions can
* be used independently or as steps in workflows.
* https://api.slack.com/future/functions/custom
* https://api.slack.com/automation/functions/custom
*/
export const SampleFunctionDefinition = DefineFunction({
callback_id: "sample_function",
Expand Down Expand Up @@ -35,15 +36,19 @@ export const SampleFunctionDefinition = DefineFunction({
},
});

// This function takes the input from the open form step, adds formatting, saves our
// updated object into the Slack hosted datastore, and returns the updated message.
/**
* SlackFunction takes in two arguments: the CustomFunction
* definition (see above), as well as a function that contains
* handler logic that's run when the function is executed.
* https://api.slack.com/automation/functions/custom
*/
export default SlackFunction(
SampleFunctionDefinition,
async ({ inputs, client }) => {
const uuid = crypto.randomUUID();

// inputs.user is set from the interactivity_context defined in sample_trigger.ts
// https://api.slack.com/future/forms#add-interactivity
// https://api.slack.com/automation/forms#add-interactivity
const updatedMsg = `:wave: ` + `<@${inputs.user}>` +
` submitted the following message: \n\n>${inputs.message}`;

Expand All @@ -54,7 +59,7 @@ export default SlackFunction(
};

// Save the sample object to the datastore
// https://api.slack.com/future/datastores
// https://api.slack.com/automation/datastores
await client.apps.datastore.put<typeof SampleObjectDatastore.definition>(
{
datastore: "SampleObjects",
Expand Down
4 changes: 2 additions & 2 deletions manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import SampleObjectDatastore from "./datastores/sample_datastore.ts";
/**
* The app manifest contains the app's configuration. This
* file defines attributes like app name and description.
* https://api.slack.com/future/manifest
* https://api.slack.com/automation/manifest
*/
export default Manifest({
name: "deno-starter-template",
name: "alissa-starter-template",
description: "A template for building Slack apps with Deno",
icon: "assets/default_new_app_icon.png",
workflows: [SampleWorkflow],
Expand Down
2 changes: 1 addition & 1 deletion triggers/sample_trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SampleWorkflow from "../workflows/sample_workflow.ts";
* Triggers determine when workflows are executed. A trigger
* file describes a scenario in which a workflow should be run,
* such as a user pressing a button or when a specific event occurs.
* https://api.slack.com/future/triggers
* https://api.slack.com/automation/triggers
*/
const sampleTrigger: Trigger<typeof SampleWorkflow.definition> = {
type: "shortcut",
Expand Down
21 changes: 17 additions & 4 deletions workflows/sample_workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { SampleFunctionDefinition } from "../functions/sample_function.ts";
/**
* A workflow is a set of steps that are executed in order.
* Each step in a workflow is a function.
* https://api.slack.com/future/workflows
* https://api.slack.com/automation/workflows
*
* This workflow uses interactivity. Learn more at:
* https://api.slack.com/future/forms#add-interactivity
* https://api.slack.com/automation/forms#add-interactivity
*/
const SampleWorkflow = DefineWorkflow({
callback_id: "sample_workflow",
Expand All @@ -31,8 +31,8 @@ const SampleWorkflow = DefineWorkflow({

/**
* For collecting input from users, we recommend the
* built-in OpenForm function as a first step.
* https://api.slack.com/future/functions#open-a-form
* OpenForm Slack function as a first step.
* https://api.slack.com/automation/functions#open-a-form
*/
const inputForm = SampleWorkflow.addStep(
Schema.slack.functions.OpenForm,
Expand All @@ -57,11 +57,24 @@ const inputForm = SampleWorkflow.addStep(
},
);

/**
* Custom functions are reusable building blocks
* of automation deployed to Slack infrastructure. They
* accept inputs, perform calculations, and provide
* outputs, just like typical programmatic functions.
* https://api.slack.com/automation/functions/custom
*/
const sampleFunctionStep = SampleWorkflow.addStep(SampleFunctionDefinition, {
message: inputForm.outputs.fields.message,
user: SampleWorkflow.inputs.user,
});

/**
* SendMessage is a Slack function. These are
* Slack-native actions, like creating a channel or sending
* a message and can be used alongside custom functions in a workflow.
* https://api.slack.com/automation/functions
*/
SampleWorkflow.addStep(Schema.slack.functions.SendMessage, {
channel_id: inputForm.outputs.fields.channel,
message: sampleFunctionStep.outputs.updatedMsg,
Expand Down

0 comments on commit 3f39fa5

Please sign in to comment.