Use
dispatch(trigger_key, payload) from any backend code to fire a trigger. The engine matches it against user-defined rules and enqueues the action chain — your code doesn’t need to know which rules exist.Building a rule
In the UI, an automation rule has four sections:- Trigger — pick from 15 trigger types. The form re-renders to show the trigger’s config schema (e.g.,
note.status_changedshows “from status” / “to status” pickers;schedule.weeklyshows day-of-week selectors). - Filters — additional payload-match conditions. The trigger may already filter (e.g.,
note.createdcan pre-filter by category); filters here are arbitrary expressions on the payload. - Actions — one or more, ordered. Each action has its own config schema. Actions can reference any field on the trigger payload via Jinja-style templates:
{{ payload.note_id }}. - Settings — rate limit (e.g., max once per hour per
client_id), dedup key, enabled/disabled, owner.
Automation row plus (for schedule triggers) a corresponding django_celery_beat.PeriodicTask so the schedule registers with the beat.
Trigger reference
Note triggers
Note triggers
Knowledge base triggers
Knowledge base triggers
Creative triggers
Creative triggers
Agent run triggers
Agent run triggers
Schedule triggers
Schedule triggers
Each registers a
PeriodicTask row in django-celery-beat. Cancelling the rule deletes the periodic task too.Webhook triggers
Webhook triggers
Action reference
Communication
Communication
Note management
Note management
Knowledge base
Knowledge base
External
External
Agent invocation
Agent invocation
Run history
Every dispatch produces anAutomationRun row:
The Run History view (
/automations/history) is server-side paginated, filterable by trigger / action / status / date range / client. Click a row → see the original payload and per-step logs.
Replay
POST /api/automations/runs/<run_id>/replay/ re-dispatches the original payload through the rule’s current configuration. Useful when a rule’s action set changes and you want to retroactively apply the new chain.
The replayed run is tagged with replayed_from=<original_run_id> for audit.
Cancel
POST /api/automations/runs/<run_id>/cancel/ revokes any queued actions in the chain. In-flight actions complete; downstream actions are skipped. The run finishes with status='cancelled'.
Slack alerts on failure
Pattern: chainagent.run_failed → send_slack:
automation.run_failed (which is implicit — failed automation runs auto-emit agent.run_failed if a run_agent action was the failing step).
Idempotency + dedup
Each rule has an optionaldedup_key template. The engine hashes the rendered key + the rule id and skips dispatch if a run with that hash exists in the last 30 minutes. Useful for noisy triggers — for example, note.status_changed can fire many times during bulk imports.
Rate limiting
Per-rule rate limits (e.g., “max 5 dispatches per minute perclient_id”) are stored on the rule and enforced in automations.engine.dispatch before queuing. Slack actions additionally honor a per-workspace token-bucket so we don’t get rate-limited by Slack itself.
.png?fit=max&auto=format&n=Frm2GFbmok4D-yJA&q=85&s=93c3ebd47542af65d1cd06d8563a7f6e)