Skip to main content

Automations

Overview

The Automations module provides a visual workflow automation engine with a node-based editor. Users create automations composed of trigger nodes, condition nodes, and action nodes connected by edges. Automations can be triggered by platform events (e.g., a new follower triggers a chat message) or manually. The module includes an execution engine that walks the node graph, evaluates conditions, executes actions via a dispatcher, and supports template variables. Execution history tracks completed steps for debugging.

Architecture

Backend

  • GraphQL (apps/api/src/graphql/automations.rs) -- Full CRUD for automations, nodes, and edges. Manual execution mutation that builds and runs the execution graph.
  • Database (apps/api/src/db/automations.rs) -- PostgreSQL operations for automations, automation_nodes, and automation_edges tables. Supports bulk replace for nodes and edges.
  • Execution Engine (crates/lo-automation/src/) -- ActionExecutor walks the execution graph from a trigger node, evaluates conditions, and dispatches actions. TemplateContext provides variable interpolation. NodeType enum defines available node types (triggers, conditions, actions).
  • Dispatcher (apps/api/src/dispatch/) -- RedisActionDispatcher sends action payloads via Redis pub/sub for real-time execution.

Frontend

  • Node-based visual editor (React Flow or similar) for creating and arranging nodes.
  • Edge connections define the execution flow between nodes.
  • Manual execution button triggers the automation from the UI.

API

GraphQL Queries

QueryPermissionDescription
automationsautomations:readList all automations for the account
automation(id: UUID)automations:readGet a single automation with all its nodes and edges

GraphQL Mutations

MutationPermissionDescription
createAutomation(input: CreateAutomationInput)automations:writeCreate a new automation with name and description
updateAutomation(input: UpdateAutomationInput)automations:writeUpdate automation name, description, or enabled state
deleteAutomation(id: UUID)automations:writeDelete an automation and all its nodes/edges
saveAutomationNodes(automationId: UUID, nodes: [AutomationNodeInput])automations:writeBulk replace all nodes for an automation
saveAutomationEdges(automationId: UUID, edges: [AutomationEdgeInput])automations:writeBulk replace all edges for an automation
executeAutomation(id: UUID)automations:executeManually execute an automation. Finds the manual_trigger node (or first trigger), builds the execution graph, and runs it.

Input Types

AutomationNodeInput:

FieldTypeDescription
idUUIDNode ID (client-generated)
nodeTypeStringNode type (trigger, condition, action)
positionXf64X position in the editor canvas
positionYf64Y position in the editor canvas
configJSONNode-specific configuration (default: {})

AutomationEdgeInput:

FieldTypeDescription
idUUIDEdge ID (client-generated)
sourceNodeIdUUIDSource node ID
targetNodeIdUUIDTarget node ID
sourceHandleStringSource handle name (default: "output")
targetHandleStringTarget handle name (default: "input")

REST Endpoints

Mirror the GraphQL surface. All paths live under /v1/automations.

MethodPathPermissionDescription
GET/v1/automationsautomations:readList automations
POST/v1/automationsautomations:writeCreate an automation
GET/v1/automations/{id}automations:readGet an automation (with nodes and edges)
PATCH/v1/automations/{id}automations:writeUpdate name/description/enabled
DELETE/v1/automations/{id}automations:writeDelete automation + nodes + edges
PUT/v1/automations/{id}/nodesautomations:writeBulk replace node list
PUT/v1/automations/{id}/edgesautomations:writeBulk replace edge list
POST/v1/automations/{id}/executeautomations:executeRun the automation manually

Request bodies are snake_case copies of the GraphQL CreateAutomationInput / UpdateAutomationInput / AutomationNodeInput / AutomationEdgeInput.

Permissions

PermissionDescription
automations:readView automations and their configuration
automations:writeCreate, edit, and delete automations
automations:executeManually trigger and start/stop automations
automations:historyView automation execution history and debug logs

Database

TableDatabaseDescription
automationsPostgreSQLid, account_id, name, description, enabled, created_at, updated_at
automation_nodesPostgreSQLid, automation_id (FK), node_type, position_x, position_y, config (JSONB), created_at
automation_edgesPostgreSQLid, automation_id (FK), source_node_id, target_node_id, source_handle, target_handle, created_at

Data Flow

  1. User creates an automation and adds nodes (triggers, conditions, actions) via the visual editor.
  2. Nodes are connected with edges that define execution flow.
  3. Nodes and edges are saved via bulk-replace mutations (saveAutomationNodes, saveAutomationEdges).
  4. When a platform event matches a trigger node, or the user clicks "Execute":
    • The execution graph is built from nodes and edges.
    • The executor starts at the trigger node and walks the graph.
    • Conditions are evaluated; actions are dispatched via RedisActionDispatcher.
    • Each step is recorded for the execution result.
  5. ExecutionResultGql returns whether the execution completed and how many steps ran.

Key Files

PathDescription
apps/api/src/graphql/automations.rsGraphQL queries and mutations
apps/api/src/db/automations.rsDatabase CRUD for automations, nodes, edges
crates/lo-automation/src/Execution engine, template context, node types
apps/api/src/dispatch/RedisActionDispatcher for action execution
apps/api/src/workers/automation.rsbuild_execution_graph helper