Define a dynamic variable

This guide explains how to create a dynamic variable.

When possible, a variable should be statically defined in the manifest file as either an input or an output variable. However, some situations require a variable that can only be defined when the user configures the flow because the nature of the input varies. For example, the number of questions and answers (and their content) for a Google Forms can't be determined until a specific form is selected during flow configuration.

Dynamic variables account for these cases by letting you define an input that produces a dynamic set of outputs in the manifest file and in the step's code.

Define the output variable in the manifest file

In the manifest file, follow these steps:

  • In inputs[], specify an input variable that accepts a dynamic input value.

  • In outputs[], specify an output variable that returns a dynamic set of output variables. Give this output a dataType of "workflowResourceDefinitionId": "dynamic_resource_id".

  • Define a custom resource to handle the dynamic variable. Specify workflowResourceDefinitions with "resourceType": "DYNAMIC" and "providerFunction": "onDynamicProviderFunction". The id must match the workflowResourceDefinitionId set in outputs[]. To learn more about custom resources, see Define a custom resource.

  • Set dynamicResourceDefinitionProvider to the name of a corresponding function in the step's code, in this example onDynamicDefinitionFunction(), that defines and returns a configuration card that accepts a dynamic input value and returns a custom resource.

JSON

"flows": {
  "workflowElements" : [{
    "id": "getDynamicVariable",
    "state": "ACTIVE",
    "name": "Get Dynamic Variable",
    "description": "Get Dynamic Variable",
    "workflowAction": {
    "inputs": [
      {
          "id": "dynamic_resource_input",
          "description": "Dynamic Resource Input",
          "cardinality": "SINGLE",
          "dataType": {
            "basicType": "STRING"
          }
       }
      ],
      "outputs": [
        {
          "id": "dynamic_resource_output",
          "description": "Dynamic Data",
          "cardinality": "SINGLE",
          "dataType": {
            "resourceType": {
              "workflowResourceDefinitionId": "dynamic_resource_id"
            }
          }
        }
      ],
      "onConfigFunction": "onDynamicVariableConfigFunction",
      "onExecuteFunction": "onDynamicVariableExecuteFunction"
    }
  }],
  "workflowResourceDefinitions": [{
    "id": "dynamic_resource_id",
    "name": "Dynamic Resource",
    "providerFunction": "onDynamicProviderFunction",
    "resourceType" : "DYNAMIC"
  }],
  "dynamicResourceDefinitionProvider" : "onDynamicDefinitionFunction",
}

Define the output variable in code

The step's code includes these functions:

  • onDynamicVariableConfigFunction(), which builds and returns a configuration card with a dynamic input widget. The name of this function must match the value of onConfigFunction() in the manifest file. The dynamic input widget's name must match the id set in the manifest file. This dynamic input widget lets users set a dynamic variable when configuring their flow, like choosing a Google Form.
  • onDynamicVariableExecuteFunction(), which returns the dynamic variable data as output when the step runs. The name of this function must match the value of onExecuteFunction() in the manifest file. The variableId of returnOutputVariablesAction must match the output variable's id set in the manifest file. The dynamic resource is found on the flow event object at e.workflow.resourceFieldsDefinitionRetrieval. The input can't reference variables because all the inputs for a dynamic resource must be available at config time.
  • onDynamicDefinitionFunction(), which retrieves the dynamic variable data from the flow event object, specifically resourceFieldsDefinitionRetrieval, and returns resourceFieldsDefinitionRetrievedAction which provides the data in usable JSON as output for later steps. The resourceId must match the id of an item in the workflowResourceDefinitions[] array set in the manifest file.
  • onDynamicProviderFunction(), which retrieves the dynamic variable from the flow event object at e.workflow.resourceRetrieval.resourceReference.resourceId and returns JSON as output for later steps.

Apps Script

function onDynamicVariableConfigFunction() {
  var card = {
    "sections": [
      {
        "widgets": [
          {
            "textInput": {
              "name": "dynamic_resource_input",
              "label": "Dynamic Resource Input",
            }
          },
        ]
      }
    ]
  };
  return {
    "action": {
      "navigations": [{
        "push_card": card
      }]
    }
  };
}

function onDynamicVariableExecuteFunction(){
  var dynamic_resource_id = uuidv4();
  return {
    "hostAppAction": {
      "workflowAction": {
        "returnOutputVariablesAction": {
          "variableValues": [{
            "variableId": "dynamic_resource_output",
            "variableData": {
              "resourceReferences" : [ dynamic_resource_id ]
            }
          }]
        }
      }
    }
  };
}

function onDynamicDefinitionFunction(e) {
  var input_value = e.workflow.resourceFieldsDefinitionRetrieval.inputs.dynamic_resource_input.stringValues[0];
  // input_value == "dynamic_resource_input"

  return {
    "hostAppAction": {
      "workflowAction": {
        "resourceFieldsDefinitionRetrievedAction": {
          "dynamicResourceDefinitions": [{
            "resourceId": "dynamic_resource_id",
            "fields": [{
                "selector":  "question_1",
                "displayText": "Question 1"
            },{
                "selector":  "question_2",
                "displayText": "Question 2"
            },{
                "selector":  "question_3",
                "displayText": "Question 3"
            }]
          }]
        }
      }
    }
  };
}

function onDynamicProviderFunction(e) {
  var resourceId = e.workflow.resourceRetrieval.resourceReference.resourceId;
  // resourceId == uuidv4();

  var workflowResourceDefinitionId = e.workflow.resourceRetrieval.resourceReference.resourceType.workflowResourceDefinitionId;
  // workflowResourceDefinitionId == "dynamic_resource_id"

  return {
    "hostAppAction": {
      "workflowAction": {
        "resourceRetrievedAction": {
          "resourceJson": JSON.stringify({
            "question_1": "Answer 1",
            "question_2": "Answer 2",
            "question_3": "Answer 3",
          })
        }
      }
    }
  };
}