# Feedback automations

Rules that run on new threads, new comments, and status changes — set a field, assign an owner, or ping the team.

Source: https://docs.annot8.app/docs/feedback/automations



An automation is a rule on a project: *when this happens, and these conditions
hold, do these things.* Manage them in **Project → Automations**.

The rule builder reads as a sentence — **When** (the trigger), **If** (the
conditions), **Then** (the actions) — and offers starter templates such as
"Triage reports with console errors", "Route one page to its owner",
"Acknowledge every report", and "Send critical bugs to the Agent". Each rule
shows when it last fired.

## Anatomy of a rule [#anatomy-of-a-rule]

<Steps>
  <Step>
    ### Trigger [#trigger]

    Exactly one of:

    | Trigger                               | Fires when                  |
    | ------------------------------------- | --------------------------- |
    | **New feedback** (`thread_created`)   | New feedback arrives        |
    | **New comment** (`comment_created`)   | Someone replies on a thread |
    | **Status changes** (`status_changed`) | A thread's status moves     |
  </Step>

  <Step>
    ### Conditions [#conditions]

    All optional; every one you set has to hold for the rule to run.

    | Condition           | Matches on                                      |
    | ------------------- | ----------------------------------------------- |
    | Environment         | The environment the thread was filed into       |
    | Type                | The thread's issue type                         |
    | Priority            | The thread's priority                           |
    | Status              | The thread's status                             |
    | Label               | The thread has a given label                    |
    | Sentiment           | Positive, neutral, or negative (from AI triage) |
    | Device              | Desktop, tablet, or mobile                      |
    | Source              | A widget pin or a feedback form                 |
    | Has console errors  | The report captured console errors              |
    | Has failed requests | The report captured failed network requests     |
    | Page path           | Substring of the page path                      |
    | Title               | Substring of the thread title                   |
    | Latest comment      | Substring of the most recent comment            |

    Text matches ignore case.

    Leave everything blank and the rule runs on every event of that trigger.
  </Step>

  <Step>
    ### Actions [#actions]

    Any combination of:

    * **Set priority**, **Set type**, **Set status**
    * **Assign to** a workspace member
    * **Add labels** — merged onto the thread's existing labels
    * **Post a comment** — posted as `Automation · <rule name>`; `{title}`,
      `{path}`, and `{url}` fill in from the thread
    * **Notify** Slack, email, Discord, Teams, or a webhook — through the
      integrations you've connected
    * **Open a ticket** in Linear, Jira, or GitHub, with the thread's context
    * **Run the Agent** on the thread — needs a paid plan and an available
      Agent credit; without one the action is skipped

    There's no action to unassign or remove labels — rules only add.
  </Step>
</Steps>

## Recipes [#recipes]

**Route critical production bugs to the on-call engineer.**
Trigger `thread_created`; conditions environment = Production, priority =
Critical; actions assign to that person, notify Slack.

**Catch checkout problems wherever they're reported.**
Trigger `thread_created`; condition URL path contains `/checkout`; actions set
priority High, notify Slack.

**Acknowledge a reopened thread.**
Trigger `status_changed`; condition status = Open; action notify email.

**Send everything from the client's staging link to one owner.**
Trigger `thread_created`; condition environment = Staging; action assign to the
account lead.

## Behaviour worth knowing [#behaviour-worth-knowing]

* **Every matching rule runs.** Rules aren't ordered and there's no
  first-match-wins. If two rules both set priority, the last one to apply wins —
  so prefer conditions specific enough that two rules don't fight.
* **Rules don't re-trigger each other.** A rule that changes status does not
  fire your `status_changed` rules, so you can't build a loop by accident.
* **Failures are contained.** A rule whose Slack webhook is broken doesn't stop
  the other rules or the rule's other actions, and never blocks the thread from
  being created.
* **Only the most recent comment is matched.** "Comment contains" looks at the
  latest comment on the thread, not the whole history.
* **Rules are per project.** Copy a rule into each project that needs it.

## Automations or integrations? [#automations-or-integrations]

They overlap, and it's worth being deliberate:

| Want                                       | Use                                                                                     |
| ------------------------------------------ | --------------------------------------------------------------------------------------- |
| Every new thread posted to a channel       | An [integration](/docs/integrations/overview)                                           |
| *Some* threads posted, based on conditions | An automation with **Notify Slack**                                                     |
| A ticket created in Jira / Linear / GitHub | The thread's right-click **Create issue** menu, or an automation with **Open a ticket** |
| Feedback pushed into your own system       | An [outbound webhook](/docs/integrations/webhooks)                                      |

Automations need the matching integration — Slack, email, Discord, Teams, a
webhook, or the tracker — already connected before their notify and ticket
actions can deliver anything.
