Extending Flow

Build Powerful Flow Extensions for Your Platform

Transform your application into a workflow powerhouse by creating custom Flow Actions and Triggers. Our extensible Flow system empowers developers to build sophisticated automation components that integrate seamlessly with existing workflows.

Workflow Triggers

  • Trigger Workflows directly from your own modules.
  • Automatic Discovery and Managment of 3rd party triggers.
  • Bridge the gap between Oqtane modules
  • Deveoper friendly API's

Workfow Actions

  • Define actions that call directly into your module.
  • Automatic Discovery and Managment of 3rd party actions.
  • Complete control over action properties.
  • Integrate with internal Oqtane APIs, external APIs, databases, and services.

Getting Started


The easiest way to get started is to install the latest Dev1.Module.Templates extension from the Oqtane Marketplace.

This will add the necessary Flow.Core nuget package, wire up the Flow registration, and create an example Flow Action and Flow Trigger. These instruction will assume this is the path you have taken.

NOTE: These inustructions assume you already have the Dev1.Module.Flow module installed on your Oqtane installation. If not, this can be installed directly from the Oqtane Marketplace.

If you would rather get your hands dirty and roll your own module, you can install the Dev1.Flow.Core nuget package from HERE (You will still need the Flow module installed on your system).

Dependancies

The Dev1.Flow.Core package is autmatically installed for you.

NOTE (Gotcha!): You may need to update your AspNetCore versions to match those used by your version of Oqtane.

Flow Registration

Your FlowInfo (more on this below) is registered in the DI container on the Server. Flow then scans for, and manages these, for use.

Custom Flow Triggers


Triggers are what create Workflows from Flows. You can think of Flows as the blueprint for a Workflow. Once a Flow is triggered, a Workflow is created with all of the active Flow actions. For details on creating Flows, see: Flow Designer.

Creating a Module using the Dev1.Module.Template creates the following example FlowInfo.

public class FlowInfo : IFlowInfo

{

public FlowDefinition FlowDefinition { get; set; }

    public FlowInfo()

    {

      FlowDefinition = new FlowDefinition

      {

        FriendlyModuleName = "FlowExtensions",

          },

        CustomFlowEvents = new List<string> { "Record Created" },

      };

    }

}


  • FriendlyModuleName: This is displayed through Flow and beats using the type name of your module. Keep it short and simple.
  • AvailableSystemTriggers: The available options are: Create, Update, and Delete.
  • CustomFlowEvents: This is a list of the actual trigger's you want to create for your module. Again, keep it simple, short, and obvious. This name will be used later when we actually raise a trigger event.

Triggering a Flow

Please refer to the ServerService's 'Add...' method created as part of the Flow.Template scaffolding as it has lots of useful information.

The first thing we do is create a ProcessingContext which holds a list of ContextItems. 

Although the call to createWorkflow (an example is below) has all of the parameters required for actions to be executed, you may also save some data that you might want to be displayed to the person processing the workflow generated by your trigger. There is also the opportunity to read and manage the process context in your actions. This allows you to create trigger-and action-specific data, which may be of use to other custom actions. You may also wish to publish the context items that your triggers and actions generate for other custom action developers to use. The ProcessContext is a powerful way of passing and managing data throughout the workflow pipeline. In this example, we will create a simple context item purely for demonstration purposes.

var context = new ProcessingContext();

Flow.Core.Helpers.FlowActionHelpers.UpsertContextItem(context, _flowInfo.FlowDefinition.FriendlyModuleName, "TriggerTime", DateTime.Now.ToShortTimeString(), false);

THIS NEXT LINE IS THE SIGNATURE OF THE METHOD THAT RAISES A TRIGGER EVENT:

CreateWorkflow(ISyncManager syncManager, ILogManager logger, Alias alias, int moduleId, int recordId, string DataPage, string flowEntityName, string triggerAction, string userName, string userEmail, ProcessingContext processingContext)

As you can see, Flow leverages Oqtane's built in SyncManager and logger. Most of these parameters are self explanatory but let's look at few that need some explanation.

DataPage: When a user is processing a Workflow, it may be helpful for them if they can view the record that was responsible for triggering the Flow. You can set DataPage to PageState.Page.Path. Flow builds the navlink as $"{DataPage}?Id={RecordId}" which, for instance, may end up looking something like /mypage?Id=1. Feel free to leave this blank if not needed.

flowEntityName: Usually you would set this to the FriendlyMouleName set in your FlowDefinition (IFlowInfo).

TriggerAction: This must match one of the CustomFlowEvents that you have defined in your FlowDefinition (IFlowInfo).

userName and userEmail: This is important. Some Flow Actions may require a UserName and/or UserEmail to process. An example of this is the built-in Flow action 'Notification'. As the designer of a custom Flow Action, you will never know what actions are on a Flow that is triggered from your Custom trigger. For the most part, you should set these values to the user who is logged in at the time the Trigger event is raised, although you may set these to whatever suits your needs; You may, for instance, be raising a trigger event after someone has filled in a form of your own creation and which holds username and email fields. If an action on a Flow requires either of these, and they aren't present, the action will fail.

 

Custom Flow Actions


Please refer to the Flow Action that was created as part of the Dev1.Module.Templates scaffolding as it has lots of useful information.

Alternatively, please see the public Dev1.Module.GoogleAdmin repo which can be found HERE and which has some great examples of Custom Actions.

For details regarding Action Properties, see: Flow Designer

Some details & considerations:

Flow actions are little pieces of code that are injected into a Workflow. They have properties which can be set when a user is designing a Flow, or when a user is processing a workflow (depending on how the property has been defined). We have tried to design Actions in a way that is agnostic regarding your use-cases and we have attempted to focus on flexibility above all.

Action's are Processor's: Each action has a GetActionDataAsync method, and a ExecuteActionAsync.

GetActionDataAsync

This method is for retreiving data (usually in the form of a list) for a particular Action Property. It receives a propertyName and can be used to call an external API, one of Oqtane's API's, or any other data source to retrieve property data. This may occur from the Flow designer or from a Workflow depending on how the property has been defined.

ExecutActionAsync

This call is made from either the Worflow processing module, or the user Tasks module when processing a Worfklow Item. The call is made when a user clicks the 'process' button for the current workflow item. This is where the magic happens. You could, for example, subscribe a user to a mailchimp campaign or, as is the case with one of the Custom Flow Actions in the Dev1.Module.GoogleAdmin module, add the user to a Google Group.

When designing your Custom Flow Action, keep in mind that the above methods are called while someone is actively designing a Flow, or processing a Workflow. Try to keep them lean and mean so that the UX isn't hampered. But, also, ignore that and do whatever floats your boat.