Workflow templates
  • 06 Oct 2025
  • 3 Minutes to read
  • Contributors
  • Dark
    Light

Workflow templates

  • Dark
    Light

Article summary

Bare minimum

The following template shows the minimum required code to execute a workflow.

export function run() {
  console.log("Hello World");
  return Promise.resolve(true);
}

Parameters

This template combines all different kind of parameters and console outputs.

import { isEnabled, count, articleName, bundle, file } from '@workflow/parameters'

export function run() {
  try {
    console.group();
    console.debug("Print all parameters...");
    console.info("isEnabled: " + isEnabled);
    console.log("count: " + count);
    console.warn("articleName: " + articleName);
    console.debug("bundle: " + bundle);
    console.info("file: " + file);
    console.groupEnd();
  } catch (e) {
    console.error("Unexpected error: " + e);
  }
  return Promise.resolve(true);
}

Update assets

It is possible to update file or datasource assets within a workflow.

Keep in mind

If a file asset is linked to data sources, then all data sources are also updated automatically.

The update of a datasource and a subsequent publish of the corresponding asset bundle is shown in this template.
Following steps are performed:

  1. create a new asset bundle draft
  2. get an existing data source
  3. update the data source
  4. publish the asset bundle
  5. update related configurators
import { bundle, file } from "@workflow/parameters";

// ATTENTION: NEVER forget to return Promises
export function run() {
  // 1. create a new asset bundle draft based on the asset bundle parameter
  return bundle.createDraft().then((draft) => {
    // 2. get the data source asset which should be updated
    const dataSourceName = "articles";
    const folderName = "data";
    const dataSourceAsset = draft.getAsset(dataSourceName, folderName);

    // 3. update the data source asset
    return dataSourceAsset.update(file).then((_) => {
      // 4. publish the asset bundle draft
      return draft.publish((configurator) => {
        // In this block you can decide what should happen to each configurator (or draft) which is using this asset bundle version
        // you have to return an object with the following format: { update: true|false, publish: true|false } for each configurator

        // 5.a) We can, for instance, choose to update but not publish a specific configurator.
        // the 'configurator' argument contains details about the current configurator, such as its name or version, or whether it is a draft
        if (configurator.name === "MyOtherConfigurator") {
          return { update: true, publish: false };
        }

        // 5.b) We can also return a bool value as a shorthand; returning 'true' is the same as returning { update: true, publish: true }
        return true;
      });
    });
  });
}

Triggers + workflow argument

As mentioned here the workflow run argument provides different data depending on the trigger type. This is shown in the example below. Quote and configuration data properties may change in the future—please contact us if you require additional properties.

export function run(arg) {
    // Argument always contains the workflow run type
    console.debug("Trigger Type: " + arg.type); // manual, scheduled, api, checkout, ...
    
    // check for the type to see which trigger started the workflow run
    if(arg.type == "manual") {
      console.debug("A manual run triggered by a user - no additional information available");
    } else if(arg.type == "scheduled") {
      console.debug("A scheduled run - no additional information available");
    } else if(arg.type == "api") {
      console.debug("An api call - not supported currently, will be released soon");
    } else if(arg.type == "checkout") {
      // checkout triggered upon a successful checkout of the configurator      
      arg.configurator; // name of the configurator
      arg.stage; // stage name of the configurator      
      var cfgnJson = JSON.parse(arg.configuration.raw); // configuration data needs to parsed to be process in the workflow
      console.debug("configuration (id): " + cfgnJson.id);
      console.debug("configuration (cfgr name): " + cfgnJson.cfgrName);
      console.debug("configuration (created at): " + cfgnJson.createdAt);
    } else if (arg.type == "quoteStateChanged") {
      // quote change can be triggered if the state of a quote has changed
      arg.hubName; // hub name of the quote
      arg.quoteId; // id of the quote
      arg.quoteNumber; // quote number of the quote   
      var quoteJson = JSON.parse(arg.quote.raw); // quote data needs to parsed to be process in the workflow
      console.debug("quote (lineItems): " + quoteJson.lineItems.length);
      quoteJson.lineItems.forEach(item => {
        if (item.type === "item") {
          console.log(" * " + item.quantity.value + item.quantity.unit + " '" + item.name + "' - " + item.priceNet + quoteJson.currency);
        } else if (item.type === "section") {
          console.log(" * Section '" + item.name + "'");
        } else {
          console.log("Unknown type:", item.type);
        }
      });
    } else {
      console.debug("Unkown workflow run type");
    }
    return Promise.resolve(true);
}

Was this article helpful?