# Connections

A connection is where a task sends its work when it becomes ready. There are two
kinds:

- **A connected app**, like Slack. You connect it once, then any task can send a
  message to a channel or to a person.
- **A custom webhook**, which is a URL of your own. This app sends it a JSON
  request. Use this for Zapier, Pipedream, n8n, an internal service, or an
  agent.

Find both under **Settings**, on the **Connections** card. You need to be an
organization admin to connect an app or to add a webhook. Anybody can then point
a task at one.

## Connect Slack

1. Open **Settings**, then select **Manage apps**.
2. Under **Apps**, select **Add to Slack**.
3. Select the workspace, then approve the permissions Slack lists.

Slack sends you back and the workspace appears under **Apps**. Its actions are
now available on every task in the builder.

You can also do this without leaving the builder. Open a task, select **Add an
action**, and select **Add to Slack** there. When you come back, the task is
still as you left it.

### What Slack can do

| Action | What it does |
|---|---|
| Send a message to a channel | Posts to the channel you pick. |
| Send a direct message | Sends to the one person you pick. |

Each message carries a link back to the task, so nobody has to search for it.

**Public channels work immediately.** For a private channel, invite the
Flightplan app to that channel first. If you do not, the message fails and the
task says so.

Connecting Slack also lets Flightplan send each person a direct message when a
task becomes theirs, with no action to set up on any task. Those messages are
off until somebody turns them on, and an admin can turn them on for the whole
workspace under **Settings**. Read [notifications](/docs/notifications) for how
an account is matched and how a person turns their own messages off.

The two are for different jobs. A **Send a direct message** action tells one
named person, whoever the task belongs to -- useful for telling somebody who is
not assigned. Notifications tell whoever the task is actually assigned to, and
they follow the assignment when it changes.

## Send a message when a task becomes ready

1. Open the workflow in the builder.
2. Select the task.
3. Under **When ready**, select **Add an action**.
4. Select the action, such as **Slack -- Send a message to a channel**.
5. Pick the channel or the person.
6. Write the message, or keep the one that is already there.

A task can have more than one action. "Post to #ops and send the owner a direct
message" is two actions on the same task.

### Words that fill themselves in

A message can carry details of the task. Write one of these and this app
replaces it when the message is sent:

| Write this | You get |
|---|---|
| `{{step.title}}` | The task's title |
| `{{step.key}}` | The task's key |
| `{{step.url}}` | A link straight to the task |
| `{{step.instructions}}` | The task's instructions |
| `{{run.label}}` | The checklist's name |
| `{{run.url}}` | A link to the checklist |
| `{{template.name}}` | The workflow's name |

If you write a word this app does not know, the workflow does not save. The
builder names the word.

## Custom webhooks

A webhook is a URL this app sends a JSON request to. Add one on the connections
page, then point a task at it the same way.

When you add a webhook, this app shows a signing secret one time. Copy it then,
because no page shows it again. Every request carries an
`X-Flightplan-Signature` header, which is an HMAC-SHA256 of the timestamp and
the body, keyed with that secret. Verify this header before you act on a
request. The URL is the only other thing that protects your receiver.

Each request also carries `callback.url` and `callback.token`. That token
completes one task of one checklist, and it expires in seven days. Give it to an
agent or to a Zap. Nothing else in your workspace is reachable with it.

## When something does not arrive

A message is never lost because Slack is slow or your service is down. This app
writes the delivery to a queue in the same step that completes the task. It then
tries six times in all, and waits longer before each attempt.

Some failures cannot be fixed by trying again. This app stops after the first
attempt and writes the reason on the delivery:

- The channel does not exist, or it is archived.
- The Flightplan app is not in that private channel.
- The connection or the app was disconnected.

If Slack rejects the token, this app disconnects the workspace and shows the
reason on the **Connections** card in **Settings**. Select **Manage apps**, then
select **Reconnect**. Every task that used it starts working again, because a
reconnect returns to the same record.

**Note:** A webhook request carries an `Idempotency-Key` header, so your
receiver can recognize a repeat. Slack has no equivalent, so a reply lost on the
network can produce a second message.

## Disconnect an app

Open **Settings**, select **Manage apps**, then select **Disconnect**. Nothing
is deleted. Tasks that point at it keep their settings, and they start working
again if you reconnect.

A workflow that sends to a disconnected app still saves. The builder shows a
warning on the task, because a disconnected app means that task notifies
nobody.
