The Automation module is the central orchestrator of AppEngine. Every endpoint lives under /automation/*. A workflow is a directed graph of steps — triggers fire, conditions branch, actions run side effects. The same engine powers IVR call flows, lead scoring, and timed campaigns.
What it does
- Workflows — Triggers respond to events; conditions branch the path; actions perform side effects (create records, send notifications, call webhooks, move pipeline stages, etc.).
- IVR orchestration — Twilio voice calls route through automation flows. The
IVRFlowOrchestratorconverts step results into TwiML so a single editor designs both marketing automations and phone trees. - Lead scoring — A
check_engagement_scorecondition pulls a lead's score from CRM, compares it against thresholds, and branches. Score updates happen via lead actions. - AI-generated workflows — Describe an automation in plain English; the engine returns a workflow JSON ready to save and run.
How a workflow is shaped
An automation is a BaseModel<AutomationModel> record stored under the automation collection. The data payload looks like:
{
"name": "Welcome new contacts",
"status": "active",
"enabled": true,
"triggers": [
{ "id": "t1", "type": "contact_created", "config": { "tags": ["newsletter"] }, "enabled": true }
],
"steps": [
{ "id": "s1", "type": "action", "config": { "actionType": "delay", "duration": 1, "unit": "hours" }, "nextStepId": "s2" },
{ "id": "s2", "type": "action", "config": { "actionType": "send_notification", "deliveryType": "email", "templateId": "welcome" } }
],
"settings": { "circularPrevention": { "enabled": true, "maxDepth": 5 } }
}
triggers register with the trigger registry on start. The runner traverses steps by nextStepId. Conditions can return multiple branch IDs. Actions can pause execution (delay, wait-for-reply) and resume via the queue.
Module surface
/automationJWT/automationJWT/automation/:automationIdJWT/automation/:automationIdJWT/automation/:automationIdJWT/automation/start/:automationIdJWT/automation/stop/:automationIdJWT/automation/:automationId/executeJWT/automation/dashboard/statsJWT/automation/execution/historyJWT/automation/ai/generateJWTWhere each piece lives
| Concept | Page |
|---|---|
| Build & store flows | Flow builder |
| What kicks them off | Triggers reference |
| How branching works | Conditions reference |
| Side effects | Actions reference |
| Natural-language flows | AI-generated workflows |
| Pre-built recipes | Templates |
| Dry runs and logs | Testing and debugging |
| Lead scoring rules | Lead scoring |
Cross-module wiring
The engine is event-driven. CRM, Storefront, Phone, Broadcast and Sync all emit events that the AutomationEventListener translates into trigger evaluations. Conditions can call into DynamicQuery for filter-style segmentation. Actions reach into Sync (notifications), Upstream (vendor calls), Phone (place a call), and the Repository module (create/update/delete records).
A circular-prevention guard (TriggerGuardService) blocks self-triggering and runaway chains. Defaults: max depth 5, same-record retrigger blocked. Configure under settings.circularPrevention per workflow.
Trigger registration is per-org and lives in memory plus a registry collection. Always call POST /automation/start/:automationId after enabling a workflow — saving alone does not register triggers.