Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions content/integrations/chat/slack/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,31 @@ section: Integrations > Slack
layout: integrations
---

This page covers how to use Knock to send notifications to Slack. Depending on your use case, there are a few different ways to approach this integration. This documentation serves as a starting point and will cover the basics of setting up a Slack integration with Knock regardless of your use case.
This page covers how to use Knock to send notifications to Slack. You can use Knock's Slack extension to message your own team's workspace, or connect your own Slack app to build a customer-facing integration.

## What can I do with Knock's Slack integration?

Knock's Slack integration enables you to send notifications to [Slack channels](https://docs.knock.app/integrations/chat/slack/sending-a-message-to-channels) and [direct messages](https://docs.knock.app/integrations/chat/slack/sending-a-direct-message) to users via an authenticated Slack app, or via [webhooks for internal workspaces](https://docs.knock.app/integrations/chat/slack/sending-an-internal-message). You can create rich message templates using [markdown](#markdown-templates) or [Slack's block kit framework](#block-based-templates), and build integrations where customers connect your Slack app to their Slack workspaces.
Knock's Slack integration enables you to:

- [Send messages to your team's Slack workspace](/integrations/chat/slack/sending-an-internal-message) using a managed Internal Slack channel.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the comment in standup this morning, just want to be sure that "Internal Slack" is how we want to refer to this? I think this was the update from (Internal) but just wanted to be sure that this is the phrasing we landed on

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the changelog is using "internal Slack" (i.e. not a proper noun Internal), so maybe we can use that across the board and reference the Internal badge in particular with code syntax?

- [Send messages to channels in your customers' workspaces](/integrations/chat/slack/sending-a-message-to-channels) using your own Slack app.
- [Send direct messages to users in your customers' workspaces](/integrations/chat/slack/sending-a-direct-message) using your own Slack app.

You can create rich message templates using [markdown](#markdown-templates) or [Slack's Block Kit framework](#block-based-templates).

This integration does not support Slack modals, slash commands, shortcuts, or interactive dialogs.

## How to connect Slack to Knock
## Connect your own Slack app

The steps below apply when you are building a customer-facing Slack integration with your own Slack app. To send workflow messages to your own team's workspace without creating a Slack app, [create an Internal Slack channel](/integrations/chat/slack/sending-an-internal-message) instead.

Knock supports multiples ways to create a Slack integration depending on your technical requirements:
Knock supports multiple ways to connect your own Slack app depending on your technical requirements:

- Using Knock's managed approach with our [SlackKit components](/in-app-ui/react/slack-kit)
- Using Knock's [Slack-related React hooks](https://docs.knock.app/in-app-ui/react/slack-kit#using-slackkit-headless) with your own components
- Building the UI and OAuth flow entirely yourself

Regardless of your approach, you'll need a Slack app to send notifications from Knock to a Slack workspace. If you haven’t built a Slack app yet, you can get started in <a href="https://api.slack.com/start/quickstart#creating" target="_blank">Slack’s app documentation</a>.
If you haven’t built a Slack app yet, you can get started in <a href="https://api.slack.com/start/quickstart#creating" target="_blank">Slack’s app documentation</a>.

Once you create your Slack app, you’ll be routed to its app management page within the Slack dashboard. It looks like this.

Expand Down
180 changes: 94 additions & 86 deletions content/integrations/chat/slack/sending-an-internal-message.mdx
Original file line number Diff line number Diff line change
@@ -1,120 +1,128 @@
---
title: Sending a message to an internal Slack workspace
description: How to send a message to an internal Slack workspace using Knock.
title: Sending messages to your team's Slack workspace
description: Use an Internal Slack channel to send Knock workflow messages to channels and people in your team's Slack workspace.
tags: ["slack", "chat"]
section: Integrations > Slack
layout: integrations
---

In this documentation we'll cover how to send a message to an internal Slack workspace using Knock. It assumes that you have already created a Slack app and created a Slack channel in Knock as outlined in the [Slack integration](/integrations/chat/slack/overview) documentation.

## Slack channels are connections on Objects

In Knock, we model channels in a Slack workspace as connections on Objects. [Objects](/concepts/objects) allow you to model any resource in your system within Knock, and while their primary purpose is to act as non-user recipients, they are very flexible abstractions.
Knock's Internal Slack channel gives your team a managed way to send workflow messages to your own Slack workspace. Connect the Knock Slack extension once, then choose a Slack channel or person as the destination for each workflow step.

You don't need to create a Slack app, manage bot tokens, or store Slack `channel_data` on your workflow recipients.

<Callout
type="info"
title="Knock channels and Slack destinations are different."
text={
<>
The <strong>Internal Slack channel</strong> is a managed Knock channel
backed by the Knock Slack extension. A <strong>Slack destination</strong>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're missing a space or a {" "} here after "Slack destination"

Image

is the channel or person in your workspace that you select on a workflow step.
One Internal Slack channel can be used by many workflow steps, each with its
own destination.
</>
}
/>

### An overview of Objects
## Before you begin

Individual Objects exist within [a collection](/concepts/objects#collection-naming) and always have [a unique ID](/concepts/objects#the-object-identifier) or key within that collection. The Object itself can store any number and type of properties as key-value pairs. You can see some examples of possible Object structures in [the official documentation on setting Object data](/concepts/objects#sending-object-data-to-knock).
To create an Internal Slack channel, you need a Knock role with permission to manage both channels and extensions. After it is created, team members with permission to edit workflows can use it in workflow steps.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To create an Internal Slack channel, you need a Knock role with permission to manage both channels and extensions. After it is created, team members with permission to edit workflows can use it in workflow steps.
To create an Internal Slack channel, you need a Knock [role](/manage-your-account/roles-and-permissions) with permission to manage both channels and extensions. After it is created, team members with permission to edit workflows can use it in workflow steps.


Let’s say you are building a devtool product like GitHub and want to set up Slack notifications whenever someone comments on an issue within a repository. First, you’ll want to create an Object to model your repository as part of the `repositories` collection:
The Knock Slack app can send to:

```javascript
import Knock from "@knocklabs/node";
const knockClient = new Knock({ apiKey: process.env.KNOCK_API_KEY });
- Public channels in your workspace.
- Private channels where the Knock Slack app is a member. Invite `@Knock` to a private channel before selecting it.
- Active people in your workspace via direct message.

await knockClient.objects.set("repositories", "repo-1", {
name: "My repo",
});
```
## Create an Internal Slack channel

Once you have a repository object created, you can add the channel data for Slack as a connection on the object.
<Steps titleSize="h3">
<Step title="Choose Internal Slack">

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<Step title="Choose Internal Slack">
<Step title="Create a new channel">

In the Knock dashboard, open **Settings > Channels and sources** and click

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In the Knock dashboard, open **Settings > Channels and sources** and click
In the Knock dashboard, open <a href="https://dashboard.knock.app/~/settings/integrations/channels" target="_blank">**Settings > Channels and sources**</a> and click

Now that we can link straight to the dashboard, nice to add

**Create channel**. Select **Chat**, then choose **Slack** with the
**Internal** badge.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
**Internal** badge.
`Internal` badge.

(if we like my suggestion about lowercase in other places and indicating the badge with code syntax; not necessary)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would look like this

Image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whatever we decide on the above suggestion, I think we should also say "Click next."

</Step>

## Objects as workflow recipients
<Step title="Connect your Slack workspace">
If your project is already connected to Slack through the [Knock Slack
extension](/integrations/extensions/slack) with the required permissions,
Knock uses that connection to create the Internal Slack channel.

To add channel data, we’ll set up an <a href="https://api.slack.com/messaging/webhooks" target="_blank">incoming webhook in Slack</a>. To get this URL from Slack, you can go to “Incoming Webhooks” within your dashboard and toggle the "Activate Incoming Webhooks" feature. If you’ve already installed your app into a workspace, you will be asked to reinstall it and select a channel the app will post messages to.
If Slack is not connected, or if the existing connection needs additional
permissions, Knock opens the Slack authorization flow. Choose your workspace
and approve the requested permissions. After you return to Knock, the
Internal Slack channel is created automatically.

<Image
src="/images/integrations/chat/slack/activate-incoming-webhooks.png"
className="rounded-md mx-auto border border-gray-200"
alt="activating incoming webhooks in Slack"
width={2000}
height={1130}
/>
To generate a new webhook, scroll to the bottom of the page where you see the “Add
New Webhook to Workspace” button. If you connected an initial channel, you can copy
your webhook, or you can connect another channel and then copy the webhook URL:

<Image
src="/images/integrations/chat/slack/copy-webhook.png"
className="rounded-md mx-auto border border-gray-200"
alt="creating a Slack channel in Knock dashboard"
width={2000}
height={1734}
/>
</Step>

### Set the webhook as channel data
<Step title="Confirm the connection">
The channel configuration shows the Slack workspace managed by the Knock
Slack extension. Its credentials apply across your Knock environments and
cannot be edited from the channel configuration.

Now that you have the webhook URL, we’ll store that webhook as a special property on the repository Object called channel data. [Channel data is both channel and recipient-specific data](https://docs.knock.app/managing-recipients/setting-channel-data) stored for use with particular channels, like a token used for push notifications or webhooks stored for chat apps like Slack, Teams, and Discord. Both Users and Objects can store channel data.
You can create one Internal Slack channel per Knock project. The same

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can create one Internal Slack channel per Knock project. The same
You can create one Internal Slack channel per Knock account. The same

channel can be reused across any number of workflows.

In the code example below, we’ll use the `knockClient.objects.setChannelData` method to update the channel data for our repository Object.
</Step>
</Steps>

```javascript
import Knock from "@knocklabs/node";
const knockClient = new Knock({ apiKey: process.env.KNOCK_API_KEY });

await knockClient.objects.setChannelData(
"repositories",
repository.id,
process.env.KNOCK_SLACK_CHANNEL_ID,
{
data: {
connections: [
{
incoming_webhook: { url: "url-from-slack" },
},
],
},
},
);
```
## Add Internal Slack to a workflow

Here, you’ll also need your `KNOCK_SLACK_CHANNEL_ID` as the third parameter, which is the channel ID of your Slack integration within Knock, so that Knock can reference that channel when it processes workflows that use it. The last parameter is an object of a specific format that varies based on [the type of message provider](/managing-recipients/setting-channel-data#provider-data-requirements). In this case, it is a `SlackConnection` object with an `incoming_webhook` property that contains the URL you copied from Slack.
<Steps titleSize="h3">
<Step title="Add a channel step">
Open a workflow and add a channel step using your Internal Slack channel.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Open a workflow and add a channel step using your Internal Slack channel.
Open a workflow and add a chat app channel step. Select your internal Slack channel.

(note: also updated capitalization on Internal while I was here)

</Step>

### Trigger a workflow with an object recipient
<Step title="Choose where to send the message">
Use the **Send to** field to search the connected workspace. Choose a
destination from either the **Channels** or **People** tab.

With the channel data in place, you can add Slack as a workflow step in any workflow. For this example, we’ll create a `new-issue` workflow that pings users in our connected Slack channel whenever someone adds a new issue.
The destination is stored on this workflow step. Other steps using the same
Internal Slack channel can send somewhere else.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Internal Slack channel can send somewhere else.
internal Slack channel can be configured to send elsewhere.

(ditto on the internal capitalization note)


<Image
src="/images/integrations/chat/slack/workflow-with-slack-step-new.png"
className="rounded-md mx-auto border border-gray-200"
alt="workflow with a Slack step"
width={2202}
height={1922}
/>
</Step>

As you create your message template, remember that in this case the repository Object is the recipient of your workflow. That means any properties you reference on your Liquid template tags need to exist as properties of the Object as well:
<Step title="Design and commit the message">
Write the Slack message using Knock's markdown or Block Kit editor, then
commit the workflow. You do not need to configure a recipient connection in
the template settings; Knock supplies the Slack destination and credentials
for you.
</Step>
</Steps>

```markdown
There was an issue opened on the following repo: **{{ recipient.name }}**
```
## Trigger the workflow

Finally, we’ll add the workflow trigger to our code with the repository Object as a recipient.
Trigger a workflow that uses Internal Slack the same way you trigger any other Knock workflow. A recipient is still required for the workflow run, but that recipient does not need Slack channel data.

```javascript
```javascript title="Trigger a workflow that sends to Internal Slack"
import Knock from "@knocklabs/node";

const knock = new Knock({ apiKey: process.env.KNOCK_API_KEY });

await knock.workflows.trigger("new-issue", {
recipients: [{ collection: "repositories", id: "repo-1" }],
await knock.workflows.trigger("support-alert", {
recipients: ["user-1"],
data: {
summary: "A customer needs help with a failed import.",
},
});
```

With that, you should see a message in your selected Slack channel:
The workflow recipient still provides the `recipient` variables used in Liquid templates, step conditions, and the rest of the workflow. The destination selected in **Send to** only changes where that Internal Slack step is delivered.

<Image
src="/images/integrations/chat/slack/slack-message.png"
className="rounded-md mx-auto border border-gray-200"
alt="A Slack message"
width={2000}
height={552}
/>
## How recipient preferences work

Internal Slack sends bypass the workflow recipient's notification preferences because the message is going to a team destination, not to a Slack connection owned by that recipient. Channel and step conditions still evaluate normally against the workflow recipient.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Internal Slack sends bypass the workflow recipient's notification preferences because the message is going to a team destination, not to a Slack connection owned by that recipient. Channel and step conditions still evaluate normally against the workflow recipient.
Internal Slack sends bypass the workflow recipient's notification [preferences](/preferences/overview) because the message is delivered to a configured destination, not to a Slack connection owned by that recipient. Channel and step [conditions](/concepts/conditions) still evaluate normally against the workflow `recipient`, if set.


Each Internal Slack step sends exactly one message to its selected destination. In workflow runs and message details, **Delivered to** shows the Slack channel or person that received the message while the message's recipient remains the workflow recipient.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Each Internal Slack step sends exactly one message to its selected destination. In workflow runs and message details, **Delivered to** shows the Slack channel or person that received the message while the message's recipient remains the workflow recipient.
Each Internal Slack step sends exactly one message to its selected destination. In workflow runs and message details, **Delivered to** shows the Slack channel or person that received the message, while the recipient associated with the message remains the workflow `recipient`.


## Manage or reconnect Slack

The Knock Slack extension owns the workspace connection and credentials used by the Internal Slack channel. Manage the connection from **Settings > Extensions**, not from the channel's provider settings.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The Knock Slack extension owns the workspace connection and credentials used by the Internal Slack channel. Manage the connection from **Settings > Extensions**, not from the channel's provider settings.
The Knock Slack extension owns the workspace connection and credentials used by the Internal Slack channel. Manage the connection from <a href="https://dashboard.knock.app/~/settings/integrations/extensions" target="_blank">**Settings > Extensions**</a>, not from the channel's provider settings.


If the extension is disconnected or needs to be authorized again, Knock preserves the Internal Slack channel and its workflow references but skips affected Slack steps until the workspace is reconnected. The workflow run log identifies the disconnected Slack connection as the reason. Open **Settings > Extensions** and reconnect Slack to resume delivery.

## When to use a different Slack setup

Use an Internal Slack channel when you want Knock to message your own team's workspace through the Knock Slack app.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Use an Internal Slack channel when you want Knock to message your own team's workspace through the Knock Slack app.
An internal Slack channel should only be used when you want Knock to message your own team's workspace through the Knock Slack app.

I think this is clearer, I found it confusing that the heading said when to use a different setup and then the paragraph started with use an internal one


If you are building a customer-facing Slack integration, use [your own Slack app and SlackKit](/integrations/chat/slack/sending-a-message-to-channels). If you need to supply a custom bot token, incoming webhook, or Liquid-based destination, use a customer-configured Slack channel with a [recipient connection override](/integrations/chat/slack/overriding-recipient-connections).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you are building a customer-facing Slack integration, use [your own Slack app and SlackKit](/integrations/chat/slack/sending-a-message-to-channels). If you need to supply a custom bot token, incoming webhook, or Liquid-based destination, use a customer-configured Slack channel with a [recipient connection override](/integrations/chat/slack/overriding-recipient-connections).
If you are building a customer-facing Slack integration, use [your own Slack app and SlackKit](/integrations/chat/slack/sending-a-message-to-channels).

I think we should consider cutting this. It's enough of an edge case that someone on this page might not have any context for what "custom bot tokens, incoming webhooks, or Liquid-based destination" even means and I think calling it out explicitly here might confuse more people than it helps.

Loading
Loading