定义动态变量

本指南介绍了如何创建动态变量。

如果可能,应在清单文件中将变量静态定义为输入变量或输出变量。不过,在某些情况下,需要使用只能在用户配置流程时定义的变量,因为输入的性质各不相同。例如,在流程配置期间选择特定表单之前,无法确定 Google 表单的问题和答案(及其内容)的数量。

动态变量允许您定义一个输入,该输入可在清单文件和相应步骤的代码中生成一组动态输出,从而应对这些情况。

在清单文件中定义输出变量

在清单文件中,按以下步骤操作:

  • inputs[] 中,指定一个接受动态输入值的输入变量。

  • outputs[] 中,指定一个输出变量,该变量会返回一组动态的输出变量。为该输出提供 "workflowResourceDefinitionId": "dynamic_resource_id"dataType

  • 定义用于处理动态变量的自定义资源。使用 "resourceType": "DYNAMIC""providerFunction": "onDynamicProviderFunction" 指定 workflowResourceDefinitionsid 必须与 outputs[] 中设置的 workflowResourceDefinitionId 一致。如需详细了解自定义资源,请参阅定义自定义资源

  • dynamicResourceDefinitionProvider 设置为相应函数(在本例中为 onDynamicDefinitionFunction())的名称,该函数在步骤的代码中定义并返回一个配置卡,该配置卡接受动态输入值并返回自定义资源。

JSON

{
  "timeZone": "America/Toronto",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Dynamic Variable Demo",
      "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
      "useLocaleFromApp": true
    },
    "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": "INTEGER"
                }
              }
            ],
            "outputs": [
              {
                "id": "dynamic_resource_output",
                "description": "Dynamic Data",
                "cardinality": "SINGLE",
                "dataType": {
                  "resourceType": {
                    "workflowResourceDefinitionId": "resource_definition_1"
                  }
                }
              }
            ],
            "onConfigFunction": "onDynamicVariableConfigFunction",
            "onExecuteFunction": "onDynamicVariableExecuteFunction"
          }
        }
      ],
      "workflowResourceDefinitions": [
        {
          "id": "resource_definition_1",
          "name": "Dynamic Resource",
          "providerFunction": "onDynamicProviderFunction",
          "resourceType": "DYNAMIC"
        }
      ],
      "dynamicResourceDefinitionProvider": "onDynamicDefinitionFunction"
    }
  }
}

在代码中定义输出变量

相应步骤的代码包含以下函数:

  • onDynamicVariableConfigFunction(),用于构建并返回包含动态输入 widget 的配置卡片。此函数的名称必须与清单文件中的 onConfigFunction() 值一致。动态输入 widget 的名称必须与清单文件中设置的 id 匹配。借助此动态输入 widget,用户可以在配置流程时设置动态变量,例如选择 Google 表单。
  • onDynamicVariableExecuteFunction(),该变量会在相应步骤运行时返回动态变量数据作为输出。此函数的名称必须与清单文件中的 onExecuteFunction() 值一致。returnOutputVariablesActionvariableId 必须与清单文件中设置的输出变量的 id 相匹配。动态资源位于流事件对象的 e.workflow.resourceFieldsDefinitionRetrieval 中。输入不能引用变量,因为动态资源的所有输入都必须在配置时可用。
  • onDynamicDefinitionFunction(),用于从流程事件对象(具体为 resourceFieldsDefinitionRetrieval)中检索动态变量数据,并返回 resourceFieldsDefinitionRetrievedAction,后者以可用的 JSON 格式提供数据,作为后续步骤的输出。resourceId 必须与清单文件中设置的 workflowResourceDefinitions[] 数组中某个项的 id 相匹配。
  • onDynamicProviderFunction(),用于从 e.workflow.resourceRetrieval.resourceReference.resourceId 的流程事件对象中检索动态变量,并返回 JSON 作为后续步骤的输出。

Apps 脚本

function onDynamicVariableConfigFunction() {
  let section = CardService.newCardSection()
    .addWidget(
      CardService.newTextInput()
        .setFieldName("dynamic_resource_input")
        .setTitle("Dynamic Resource Input")
        .setHint("Input a Integer value between 1 and 3\(inclusive\) for corresponding number of output variables")
    );

  const card = CardService.newCardBuilder()
    .addSection(section)
    .build();

  return card;
}

function onDynamicDefinitionFunction(e) {
  console.log("Payload in onDynamicDefinitionFunction: ", JSON.stringify(e));
  var input_value = e.workflow.resourceFieldsDefinitionRetrieval.inputs.dynamic_resource_input.integerValues[0];

  let resourceDefinitions = AddOnsResponseService.newDynamicResourceDefinition()
    .setResourceId("resource_definition_1")
    .addResourceField(
      AddOnsResponseService.newResourceField()
        .setSelector("question_1")
        .setDisplayText("Question 1")
    );

  if (input_value == 2 || input_value == 3) {
    resourceDefinitions = resourceDefinitions
      .addResourceField(
        AddOnsResponseService.newResourceField()
          .setSelector("question_2")
          .setDisplayText("Question 2")
      );
  }
  if (input_value == 3) {
    resourceDefinitions = resourceDefinitions
      .addResourceField(
        AddOnsResponseService.newResourceField()
          .setSelector("question_3")
          .setDisplayText("Question 3")
      );
  }

  let workflowAction = AddOnsResponseService.newResourceFieldsDefinitionRetrievedAction()
    .addDynamicResourceDefinition(resourceDefinitions);

  let hostAppAction = AddOnsResponseService.newHostAppAction()
    .setWorkflowAction(workflowAction);

  let renderAction = AddOnsResponseService.newRenderActionBuilder()
    .setHostAppAction(hostAppAction)
    .build();

  return renderAction;
}

function onDynamicVariableExecuteFunction(e) {
  console.log("Payload in onDynamicVariableExecuteFunction: ", JSON.stringify(e));

  let workflowAction = AddOnsResponseService.newReturnOutputVariablesAction()
    .setVariableDataMap({
      "dynamic_resource_output": AddOnsResponseService.newVariableData()
        .addResourceReference("my_dynamic_resource_id")
    });

  let hostAppAction = AddOnsResponseService.newHostAppAction()
    .setWorkflowAction(workflowAction);

  let renderAction = AddOnsResponseService.newRenderActionBuilder()
    .setHostAppAction(hostAppAction)
    .build();

  return renderAction;
}

function onDynamicProviderFunction(e) {
  console.log("Payload in onDynamicProviderFunction: ", JSON.stringify(e));

  // resourceId == "my_dynamic_resource_id"
  var resourceId = e.workflow.resourceRetrieval.resourceReference.resourceId;
  // workflowResourceDefinitionId == "resource_definition_1"
  var workflowResourceDefinitionId = e.workflow.resourceRetrieval.resourceReference.resourceType.workflowResourceDefinitionId;

  const workflowAction = AddOnsResponseService.newResourceRetrievedAction()
    .setResourceData(
      AddOnsResponseService.newResourceData()
        .addVariableData("question_1", AddOnsResponseService.newVariableData().addStringValue("Answer 1"))
        .addVariableData("question_2", AddOnsResponseService.newVariableData().addStringValue("Answer 2"))
        .addVariableData("question_3", AddOnsResponseService.newVariableData().addStringValue("Answer 3"))
    );

  const hostAppAction = AddOnsResponseService.newHostAppAction()
    .setWorkflowAction(workflowAction);

  const renderAction = AddOnsResponseService.newRenderActionBuilder()
    .setHostAppAction(hostAppAction)
    .build();

  return renderAction;
}