Custom workflow actions

Add your own action type to workflows in C#.

Custom actions implement IWorkflowAction: an ActionType name and ExecuteAsync(ActionContext). The workflow engine runs them through the code executor, alongside the 26 built-in actions, and passes their output to later actions.

Use a custom action when a step needs logic the built-in actions cannot express, such as calculating a value from several records or calling a system with a custom protocol. Actions can use the platform's .NET SDKs and HttpClient.

Workflow actions in C#

A custom workflow action implements IWorkflowAction. Its ActionType names it, and must match the script's name on the platform. The workflow engine runs a workflow's steps in order; when a step uses your action, the platform compiles and runs your code and passes the result on.

Custom workflow action
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using TAF.Infra.WorkflowAction.Interfaces;
using TAF.Infra.WorkflowAction.Models;

public class ApplyDiscountAction : IWorkflowAction
{
    // Must match the script's name on the platform.
    public string ActionType => "ApplyDiscount";

    public async Task<ActionResult> ExecuteAsync(ActionContext context, CancellationToken cancellationToken)
    {
        // Inputs come from the step's configuration in the workflow.
        var rate = context.GetInput<decimal>("Rate", 0.1m);
        if (rate < 0 || rate > 1)
            return ActionResult.FailureResult("Rate must be between 0 and 1.");

        // Outputs are available to later steps in the chain.
        return ActionResult.SuccessResult(new Dictionary<string, object?>
        {
            ["DiscountRate"] = rate,
        });
    }
}

What an action receives and returns

  • context.Config holds the step's configured inputs; GetInput reads one with a default.
  • context.PreviousOutputs and context.Variables carry values from earlier steps; for a record-triggered workflow, context.OldRecordData holds the record before the change.
  • Return ActionResult.SuccessResult(data) to pass outputs on, FailureResult(message) to fail the step, or StopChainResult() to end the workflow successfully at this step.