Files
warmbly/docs/content/docs/automations.mdx
T
Matthew Meszaros 3236ffc459 feat: expand product docs and automation references
Restructure the docs navigation into product-focused pages, add automation expression reference content, and refresh related template and personalization surfaces.
2026-06-09 09:07:56 +02:00

166 lines
9.4 KiB
Plaintext

---
title: Automations
description: "A visual flow builder: a trigger event connected to action steps across your integrations."
---
# Automations
An automation is a small flow you build on a canvas. It starts with one **trigger** (something that happens in Warmbly, like a reply coming in or a meeting being booked) and runs one or more **action steps** in response (post to Slack, push to your CRM, tag a contact, and more). Between the trigger and the actions you can add **IF conditions** to branch the flow, so different events take different paths.
You build this visually. There is no code to write, though an optional advanced mode lets you write a free-form condition when you need one.
## Where to find it
Open the **Automations** tab. Each automation has a name, an on/off toggle, and a canvas. Toggle an automation to **Active** to let it run, or leave it **Off** while you build. An automation that is **Off** never fires, even from a campaign step.
## The visual builder
The canvas works like the campaign sequence editor:
- The **Trigger** node sits at the top. You can't delete it.
- Drag from a node's dot to draw a connection to another node.
- Drag from a dot onto empty canvas to drop a **new action** already connected to that node.
- Click any node to open its editor panel on the right.
- Click a connection line, then press `Delete` or `Backspace`, to remove it.
- Use **Add action** and **Add condition** (top-left) to place new nodes, and **Tidy up** to auto-arrange the layout.
<Callout type="info" title="Save before it runs">
The canvas is edited locally. Your changes only take effect after you press **Save**. **Test** also saves first, then dry-runs the saved flow.
</Callout>
## Triggers
A trigger is the event that starts the flow. Pick one in the trigger node's editor. The available triggers are:
| Trigger | Fires when |
| --- | --- |
| Reply received | A contact replies to a campaign email |
| Meeting booked | A meeting is booked (Calendly / Cal.com) |
| Meeting rescheduled | A booked meeting is rescheduled |
| Meeting canceled | A booked meeting is canceled |
| Email bounced | A campaign email bounces |
| Unsubscribed | A contact unsubscribes |
| Warmup health changed | A mailbox's warmup health state changes |
| Deliverability complaint | A spam complaint is recorded |
| Campaign action | Launched on demand from a campaign step, not from a real event |
The **Campaign action** trigger is special: it never fires by itself. It only runs when a campaign sequence reaches a "Run automation" step, which lets you trigger an automation as part of a campaign flow. (A campaign-launched run still evaluates your conditions, and an automation that is **Off** is a no-op.)
Each trigger carries its own event data (for example, a reply carries the contact email, the reply intent, and a classifier confidence). Those values are what your conditions test and what your action text can insert. See [Personalization & expressions](/expressions) for the full list of variables per trigger.
## IF conditions (branching)
An **IF** node splits the flow into a **yes** path and a **no** path. Add one with **Add condition**, then connect:
- the node's **right** dot to the steps that should run when the condition is **true** (the "yes" path)
- the node's **bottom** dot to the steps that should run when the condition is **false** (the "no" path)
At run time the flow follows only the branch that matches the outcome. A branch you leave unconnected simply ends there.
### Building a condition
In the condition editor you pick a **field**, an **operator**, and a **value**. The fields offered depend on the trigger, so they are always meaningful. For a reply, for example, you can branch on **Reply intent**, **Classifier confidence**, **Contact email**, **Subject**, or whether a contact was matched. Meeting, bounce, complaint, unsubscribe, warmup, and campaign-action triggers each expose their own fields.
Operators depend on the field's type:
| Field type | Operators |
| --- | --- |
| Text | `is`, `is not`, `contains`, `is present` |
| Number | `≥`, `≤`, `is`, `is present` |
| Choice (enum) | `is`, `is not`, `is present` |
Two special conditions are available for any trigger:
- **Random split** sends a set percentage down the "yes" path (between `1%` and `99%`). The split is deterministic per event, so the same event always takes the same branch and re-deliveries don't flip it.
- **Advanced expression** is the escape hatch described next.
### Advanced expression mode
When the field/operator picker can't express what you want, choose **Advanced expression** and write a free-form condition. The "yes" branch is taken when the expression is truthy.
Reference trigger fields with a leading dot, and use the helper functions Warmbly provides:
```
and (gtf .confidence 0.8) (eq .intent "positive")
```
This passes only when the classifier confidence is at least `0.8` and the reply intent is `positive`. You can use comparisons (`eq`, `gt`, `lt`), numeric-coercing comparisons (`gtf`, `ltf`, `add`, `sub`, `mul`, `div`), boolean logic (`and`, `or`, `not`), and text helpers (`contains`, `lower`). A broken or empty expression is treated as **false**, so a malformed condition never silently passes. The expression is validated when you save.
The full language, every variable, and more examples are in [Personalization & expressions](/expressions).
## Action steps
An action is what the automation does when the flow reaches it. Each action node has two parts: **Run** (which integration, or Warmbly's built-in actions) and **Action** (what to do).
### Integration actions
Connect an action to one of your integrations to push data out. Available actions depend on the connected provider:
| Action | What it does |
| --- | --- |
| Send a Slack message | Posts to a Slack channel |
| Send a Discord message | Posts to a Discord channel |
| Send a webhook | Sends an HTTP request to a URL you provide |
| Create / update HubSpot contact | Upserts a contact in HubSpot |
| Create / update Pipedrive person | Upserts a person in Pipedrive |
| Create / update Salesforce contact | Upserts a contact in Salesforce |
| Create / update Close lead | Upserts a lead in Close |
A Slack action needs a **channel** (for example `#sales`). A webhook action needs a **URL**. Slack, Discord, and webhook actions also accept an optional **message** template.
### Native (built-in) actions
These act directly on the event's contact and need no external connection. Pick **Warmbly (built-in)** under **Run**:
| Action | What it does |
| --- | --- |
| Add a tag | Adds a contact category (tag) |
| Remove a tag | Removes a contact category (tag) |
| Create a task | Creates a task assigned to the workspace owner |
| Create a deal | Creates a CRM deal in a chosen pipeline and stage |
| Move the deal stage | Moves the contact's most recent open deal in a pipeline |
| Unsubscribe the contact | Unsubscribes the contact (works when the event carries a campaign) |
**Move the deal stage** acts on the contact's most recent open deal in the chosen pipeline. If they have no open deal there, nothing happens. **Unsubscribe the contact** only applies when the triggering event carries a campaign, such as a reply, bounce, or unsubscribe.
### Templating action text
Text fields in an action (a Slack or Discord message, a webhook URL, a deal name, a task title) support variable fields drawn from the trigger. The builder shows clickable chips that insert the available variables for you. Reference each with standard dotted Go-template field access, `{{.key}}`:
```
New reply from {{.contact_email}} on {{.campaign_name}}
```
Tokens are filled in when the automation runs. An unknown token renders empty rather than failing. See [Personalization & expressions](/expressions) for the rules and the per-trigger variable list.
## Templates
You don't have to build every flow from scratch. Templates give you a ready-made trigger plus a starter set of conditions and actions that you can edit before saving. They're a fast way to set up common patterns, like notifying a channel on a positive reply or creating a deal when a meeting is booked.
## Testing and run history
Two tools in the builder header help you confirm a flow behaves the way you expect.
### Test (dry run)
Press **Test** to save the current canvas and then **dry-run** it against sample event data. A dry run is safe: **no messages are sent and no records change.** The panel shows the exact path the flow takes (which IF branches it follows) and a preview of what each action would send. If no actions ran, check your conditions, the panel will tell you so.
### History
Press **History** to see recent real runs of this automation. Each run shows whether it succeeded or errored, when it started, and the result of each action step (including the error text when a step fails). Run history updates live as the automation fires, so you can watch it work without refreshing.
<Callout type="info" title="Best-effort by design">
Automation runs are best-effort and bounded against loops, so one failing step won't block the rest of the flow. The run is still recorded as errored in History so you can see what went wrong.
</Callout>
## Related guides
<Cards>
<Card title="Personalization & expressions" href="/expressions">
The condition and templating language shared by automations and campaigns.
</Card>
<Card title="Deliverability" href="/deliverability">
Warmup health and complaint signals that several automation triggers fire on.
</Card>
</Cards>