Skip to content

Automation

A Callora plugin does more than answer HTTP requests. It runs work on its own schedule, reacts to platform events, lets operators compose low-code rules and flows, and pushes events to external systems. This section is the map of those four automation surfaces — what each one is, when to reach for it, and how to build it.

All four share one delivery backbone: the durable job queue, which runs work with at-least-once delivery, leases, crash recovery, and a bounded retry budget. Understanding that backbone once (Background jobs) pays off across every page here.

What you'll learn

  • The four ways a plugin automates work, and the one-line difference between them
  • A decision table for picking the right tool for a given task
  • How automation (asynchronous) differs from a business-event listener (synchronous reaction)
  • A suggested learning path through this section

The four automation surfaces

SurfaceContractWhat it doesPage
Background jobsIBackgroundJobHandlerRun async work once, off the request thread, with retries and crash recoveryBackground jobs
Recurring jobsIRecurringJobProviderRun work on a fixed interval (nightly cleanup, periodic sync)Recurring jobs
Rules & flowsIRuleConditionEvaluator + IFlowActionHandlerContribute conditions and actions that operators compose into low-code automationRules, Flows
WebhooksIWebhookEventPublisher + WebhookSubscriptionPush platform events to external systems as signed HTTP POSTsWebhooks

Each contract is a Callora extension point: you implement it and context.Export<T>(...) your instance from your plugin's StartAsync — see Exporting extensions. The host discovers the export and wires it in.

When to use each

You want to…UseWhy
Do slow/external work without blocking an HTTP responseBackground jobAsync, durable, retried; survives a restart
Run the same work every night / every 15 minutesRecurring jobThe scheduler enqueues a job for you on the interval
Let an operator say "when a call rings from an unknown number, reject it"Rule + flowYou ship the call.direction condition and call.reject action; the operator wires them
Notify a CRM/Slack/webhook endpoint that "a call ended"WebhookDelivered as a signed, retried HTTP POST outside the platform
React synchronously to an event, possibly to veto it before it commitsBusiness-event listenerIn-process, ordered, cancelable — see below

Automation vs. business-event listeners

There are two families of "react to something happening," and mixing them up is the most common early mistake.

A business-event listener (IBusinessEventListener) is synchronous and in-process: the publisher calls every listener in priority order and waits for them, and a listener of a MutableBusinessEvent can call Cancel() to veto the operation before it commits. Use it when you must influence the outcome now — validate, enrich, or block. It is covered in Backend extensions and Events & jobs.

Everything in this section is asynchronous: the work runs later, on a worker thread, durably. A job cannot veto the operation that scheduled it — it has already happened.

The two families connect

Flows and webhooks are driven by the business-event bus. When any business event fires, FlowBusinessEventListener matches active flows and enqueues a flow.execute job; the webhook dispatcher matches subscriptions and enqueues a webhook.deliver job. So an event (synchronous) fans out into automation (asynchronous). You publish the event; the host does the fan-out.

Learning path

  1. Background jobs — the foundation. Every other page builds on the queue's at-least-once + idempotency contract.
  2. Recurring jobs — schedule a job on an interval.
  3. Rules — contribute a condition operators can test in a flow.
  4. Flows — contribute an action, and see how operators compose it via /api/flows.
  5. Webhooks — emit events to the outside world with signing and data minimization.

Next steps