Automation rules
How a rule works
Section titled “How a rule works”A rule is one sentence: when trigger, if conditions, then actions. Open Rules in the sidebar (under Automate, next to Flows and AI Agents), pick New rule or Start from a template, and fill in the three parts.
- Trigger — what the rule listens for. Some triggers take a filter (a keyword, a label name, an emoji, a flag name, a number of minutes).
- Conditions — every one must hold, or the rule is skipped and the run log says why.
- Actions — up to 10 per rule, run in order. Each can be delayed by up to 30 days; a delayed action is queued and runs on the minute. A failed action is recorded and the next one still runs.
Every evaluation that matched — and, for event triggers, every one that did not
— is logged with the reason and each action’s outcome (ok, skipped + why,
failed + why). Click Runs & test under a rule to see its Recent runs
(the last 20). Test on a conversation (admins) runs the rule against a chat
you name — by contact name, W-code or conversation id — as a dry run: nothing
is sent, created or changed.
Loop guard
Section titled “Loop guard”A rule’s actions can raise the very events other rules listen for (a ticket is created or updated, a flag is set). A rule’s own tag changes are the exception: they never raise the label triggers. Each such event carries the depth it was raised at, and the engine refuses anything raised deeper than two steps — so a rule can start a chain, but a chain cannot run forever. A flag action also never re-triggers the rule that raised it with the same flag.
Triggers
Section titled “Triggers”| Trigger | Fires when | Filter |
|---|---|---|
| A new conversation starts | the first message of a chat is stored | — |
| A message is received | a customer message arrives | keywords (any of), only outside business hours |
| A label is added / removed | a tag is added to / removed from the chat | the label |
| Someone reacts to a message | someone reacts to a message | the emoji; by agent, customer or any |
| A ticket is created / updated / closed | a ticket changes | updated: the statuses |
| A message is flagged | an agent or a rule flags a message | the flag name |
| A task is assigned to someone | a task’s owner changes | — |
| A customer has waited N minutes for a reply | timed: an open chat’s last customer message has had no reply for N minutes | minutes (1 minute to 7 days); only inside business hours (on by default) |
| A ticket passes its due date | timed: a ticket that is not closed passed its due date | — |
The two timed triggers are checked every minute. “Nobody has replied” means no person has replied — the out-of-hours auto-reply, a broadcast, an API send, a flow, an AI agent or a rule’s own message do not end a customer’s wait. Each wait fires a rule once; a new customer message starts a new wait, and a rule never fires for waits that began before the rule existed. Likewise an overdue ticket fires once per due date (moving the due date re-arms it), and due dates that passed before the rule existed are ignored.
Conditions
Section titled “Conditions”| Condition | Holds when |
|---|---|
| It is inside / outside business hours | by the org’s business hours and timezone |
| The conversation has / does not have the tag | the chat carries the tag |
| The conversation is assigned to | anyone (holds for every chat, assigned or not) / unassigned / a specific agent |
| The conversation status is | open / closed |
| The message contains | the message text contains the words |
| The ticket priority is | low / medium / high / urgent |
| The conversation is flagged | the chat carries a flag (any, or a named one) |
A flag is a lightweight mark an agent puts on a message from the thread
(hover → Flag this message), or that a rule sets with the Flag the
message action. Two things happen: the event
A message is flagged fires, and the conversation gets the tag
flag:<name> — which is what The conversation is flagged reads, and what
you remove to clear the flag. That is how “flagged and still unanswered after
10 minutes → open a ticket” is expressible.
Actions
Section titled “Actions”| Action | Params | Notes |
|---|---|---|
| Send a text reply | text | only inside the 24-hour customer-service window; skipped otherwise |
| Send a template | template name, language | works outside the window |
| Add / remove a tag | tag | a rule’s tag change does not raise the label triggers |
| Assign to the next available agent | target: the conversation or the ticket on this event | the least-busy available agent; ties go round-robin |
| Assign to a specific agent | agent | skipped if that agent is no longer active |
| Give the ticket to the chat’s owner | — | skipped when the chat is unassigned or the ticket already has that owner |
| Close the conversation | — | the full close: drops the assignment, ends AI sessions, cancels parked flows |
| Create a ticket | title, priority, owner | title defaults to the message |
| Close the ticket | — | the ticket on this event |
| Add the message to the open ticket (or open one) | title, priority | “create-or-append”: the chat’s newest open ticket, else a new one |
| Flag the message | flag, reason | sets flag:<name> and fires A message is flagged |
| Send a push notification | people (or “the assignee”), title, body | “the assignee” is the chat’s assignee |
| Send an email | to, subject, body | from no-reply@whatbot.in; customer text is escaped |
| Call a URL | url | POST with the event and placeholders; private and internal addresses are refused |
Placeholders
Section titled “Placeholders”Reply text, ticket titles, flag reasons, and push and email text take {{ }}
placeholders:
{{contact_name}} {{message}} {{label}} {{emoji}} {{agent_name}}
{{ticket_title}} {{ticket_status}} {{ticket_priority}} {{waiting_minutes}}
{{flag}} {{flag_reason}} {{task_title}} {{event}}
Unknown placeholders become empty.
Recipes (Start from a template)
Section titled “Recipes (Start from a template)”| Template | When | Then |
|---|---|---|
| Reply to a keyword | message contains price / pricing / cost | send a text |
| Out-of-hours reply | message received outside business hours | send a text |
| Keyword → ticket | message contains refund / money back | create a high-priority ticket |
| New chat → next agent | a new conversation starts, unassigned | assign round-robin |
| New ticket → next agent | a ticket is created | assign the ticket round-robin |
| Ticket → the chat’s owner | a ticket is created | give the ticket to the chat’s owner |
| Unanswered 15 min → assign + push | waiting 15 min inside hours, unassigned | assign round-robin, push the assignee |
| Ticket overdue → push the owner | a ticket is overdue | push the chat’s assignee |
| Keyword → flag | message contains invoice / gst / refund / chargeback | flag as billing |
| Flagged “billing” and unanswered → ticket | waiting 10 min and the chat carries flag:billing | create a high-priority ticket, then clear flag:billing so the flag escalates once |
| Every message → the open ticket | every customer message | add to the open ticket, or open one (ships disabled) |
Pick a template, change what you like — the name, the words, the minutes — and save. Nothing is created until you save.
Business hours
Section titled “Business hours”Settings → Business Hours (or the Business hours button on the Rules page; only admins can change them): timezone, per-day ranges, and an optional out-of-hours reply sent at most once per chat every four hours while you are closed. It is not a rule: it runs on every incoming message alongside your rules, flows and AI agents. The reply is not an answer: a customer who writes at night still counts as waiting at 09:15.
With no business hours saved, the workspace counts as always open, so “outside business hours” never holds.