Creating Tasks & Triggers

Tasks are the bits of the framework which do stuff, like making a clip on twitch, writing text to a file or sending a message to chat.

Triggers are the bits that notify a flow to execute, like when a chat message is sent, or every 10 seconds etc.

The two elements are quite similar for the most part but mainly they differ in how they are used, but both contain Data, Task/Trigger and Component aspects, all are required to function, and all are needed for them to function in the system.

Task/Trigger Data

While they both differ in term of the interface they both represent the same notion which is purely the DATA required for a task/trigger to run, these classes will be what get persisted to the file system that describe a task.

// Its IFlowTaskData for Tasks and IFlowTriggerData for triggers
public class WriteToLogTaskData : IFlowTaskData
{
    // This is the contract between the data class and the logic class
    public static readonly string TaskCode = "write-to-log";
    // This is the version of your data, which should increment as you change it
    public static readonly string TaskVersion = "1.0.0";
    
    // The unique id for the INSTANCE of the task data
    public Guid Id { get; set; } = Guid.NewGuid();
    // This is the code but at instance level
    public string Code => TaskCode;
    // This is the instances version (could be different to the static version)
    public string Version { get; set; } = TaskVersion;
    
    // These are the properties you want for your task logic to use
    public string Text { get; set; }
}

As you can see there isnt much too it, the TaskCode and TaskVersion are static because we reference them within the relevant task or trigger, the id, code, version instance properties are there to describe the task/trigger in the system, then finally the last section (the Text property in this example) can contain any fields of data you need to persist for this to work.

You can have as many or little properties as you need, but NO LOGIC should exist within here as that lives in the ACTUAL task/trigger, ultimately anything in here just gets serialized into json into the flow data file.

Creating Task Logic

While there is a bit of stuff there its not that complex really, you just put whatever you want to do into the Execute method and whenever a flow uses this task it will run that execute method with its given flow state.

There will only ever be one instance of the task in the app at once, so each flow will call Execute with its own state, so keep that in mind that ALL state needed to execute needs to be included in the data object or flow variables.

Creating Trigger Logic

As you can see its VERY similar to a task, its just our Execute returns an IObservable which contains the variables for the flow.

If you are unsure what an IObservable is, go look into Reactive Extensions online.

Task/Trigger Components

These are basically just Blazor components inheriting from an abstract class, this keeps things consistent in terms of what data and properties will be expected, it also helps the app work out what components need to be hosted within the app.

You cannot provide any [Parameter] properties to task/trigger components as they are loaded dynamically at runtime and get their data through the abstract class initialization. This being said you can @inject ISomeDependency Dependency as much as you want to access other objects registered within the DI configuration.

Last updated