Skip to content

Workflow Actions

Actions are functions that execute when a transition fires. They allow workflows to trigger side effects — sending notifications, assigning users, updating records, or calling external services.

Built-in Actions

The following actions are available out of the box:

NameTitleTypeDescription
assign_responsibleAssign responsibleSyncAssigns the site's responsible person to the event and sends an email notification
send_emission_notificationSend emission notificationAsyncQueues a notification for the event record (used to notify users of new emissions)

How Actions Work

When a transition fires, the system executes each action in the transition's action list in order:

  • Synchronous actions run inline during the workflow manager cycle.
  • Asynchronous actions are dispatched to Celery using .delay(). The workflow manager does not wait for them to complete.

Actions receive the Event instance and the Transition that fired. They can read event data, update related records, send emails, or call any other service.

Registering a New Action

Actions are registered using the @workflow_action() decorator. Place the decorator in any actions.py or tasks.py file inside an app listed in OUR_APPS — the registry auto-discovers decorated functions on startup.

Synchronous Action

python
from workflows.actions import workflow_action

@workflow_action(
    name="my_action",
    title="My Action",
)
def my_action(event, transition):
    # perform work here
    pass

Asynchronous Action

Async actions must be Celery shared_task functions. The @workflow_action decorator must be placed above @shared_task.

python
from celery import shared_task
from workflows.actions import workflow_action

@workflow_action(
    name="my_async_action",
    title="My Async Action",
    is_async=True,
)
@shared_task(queue="longrunning")
def my_async_action(event_id, transition_id):
    # perform async work here
    pass

Important: The decorator order matters. @workflow_action must come before @shared_task in the source file (i.e., listed first, applied last).

Action Parameters

ParameterRequiredDescription
nameYesUnique identifier for this action. Used in transition configuration
titleYesHuman-readable display name shown in Django Admin
owner_nameNoRestrict this action to a specific company by company name. If omitted, the action is available to all companies
is_asyncNoSet to True if the function is a Celery task. Default: False

Company-Specific Actions

If owner_name is set, the action only appears in the transition editor for that company's workflow definition. Use this to implement custom logic that applies to a single operator.

Action Registry

The action registry is discovered lazily on first use by scanning all actions.py and tasks.py modules in OUR_APPS. Duplicate action names raise a WorkflowException at startup.

To see all registered actions and their company assignments, go to Django Admin → WorkflowsWorkflow Action Registry.

From there you can also assign or remove company access to individual actions.

Adding an Action to a Transition

  1. Open the Workflow Definition in Django Admin.
  2. In the transition inline, find the Actions field.
  3. Select one or more actions from the list.
  4. Save the workflow definition.

Only actions available to the workflow's company are shown in the selector.