This guide explains how to define custom resources for Google Workspace Flows.
Custom resources are custom data structures that you can define to group multiple variables together. For example, to create a CRM lead, pass a custom resource containing an email address, street address, and name.
These are the two ways to define custom resources:
- As a reference: When you output a custom resource as a reference, you return the custom resource by its ID instead of the full custom resource object. This improves performance by reducing the data transferred between flow steps. When data requires secondary lookups, returning its ID is useful for performing those lookups.
- As a value: Use this method when the data must be retrieved during execution, or when the custom resource is small and doesn't contain sensitive data.
Output a custom resource as a reference
By outputting a custom resource as a reference, you can return the custom resource by its ID instead of the full custom resource object. If a custom resource is large or complex, passing only the ID improves performance by reducing the data transferred between flow steps.
To output a custom resource as a reference, edit the step's manifest file and code.
Edit the manifest file
In the manifest file:
Specify a
workflowResourceDefinitionsand assign it anid, afields[]array, and aproviderFunction. TheworkflowResourceDefinitionsis a structure that defines data types and contents of the custom resource.Within the
fields[]array, you specify the individual fields that make up the custom resource, in this example calledfield_1andfield_2.The
providerFunction's value must match the name of a function in the step's code. TheproviderFunctionretrieves actual custom resource content when needed.JSON
{ "workflowResourceDefinitions": [ { "id": "resource_id", "name": "Custom Resource", "fields": [ { "selector": "field_1", "name": "Field 1", "dataType": { "basicType": "STRING" } }, { "selector": "field_2", "name": "Field 2", "dataType": { "basicType": "STRING" } } ], "providerFunction": "onMessageResourceFunction" } ] }In
outputs[], specify an output variable that returns a dynamic set of output variables. The output variable has adataTypewith the propertyresourceType. The value ofcardinalitymust beSINGLE.JSON
"outputs": [{ "id": "resource_data", "description": "Resource Data", "cardinality": "SINGLE", "dataType": { "resourceType": { "workflowResourceDefinitionId": "resource_id" } } }]
Here's a complete manifest file that defines a custom resource:
JSON
{
"timeZone": "America/Los_Angeles",
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"addOns": {
"common": {
"name": "Calculator",
"logoUrl": "https://www.gstatic.com/images/branding/productlogos/calculator_search/v1/web-24dp/logo_calculator_search_color_1x_web_24dp.png",
"useLocaleFromApp": true
},
"flows": {
"workflowElements": [
{
"id": "getResourceData",
"state": "ACTIVE",
"name": "Get Resource by ID",
"description": "Get Resource by ID",
"workflowAction": {
"outputs": [
{
"id": "resource_data",
"description": "Resource Data",
"cardinality": "SINGLE",
"dataType": {
"resourceType": {
"workflowResourceDefinitionId": "resource_id"
}
}
}
],
"onConfigFunction": "onConfigResourceFunction",
"onExecuteFunction": "onExecuteResourceFunction"
}
}
],
"workflowResourceDefinitions": [
{
"id": "resource_id",
"name": "Custom Resource",
"fields": [
{
"selector": "field_1",
"name": "Field 1",
"dataType": {
"basicType": "STRING"
}
},
{
"selector": "field_2",
"name": "Field 2",
"dataType": {
"basicType": "STRING"
}
}
],
"providerFunction": "onMessageResourceFunction"
}
]
}
}
}
Edit the code
In the application code:
Implement the
providerFunction, calledonMessageResourceFunction()in this example, which retrieves custom resource content when needed. It takes the inputewhich is the step's event object JSON payload, and from it sets the custom resource ID.Apps Script
function onMessageResourceFunction(e) { var resource_id = e.workflow.resourceRetrieval.resourceReference.resourceId; var field_1 = ...; var field_2 = ...; return { "hostAppAction": { "workflowAction": { "resourceRetrievedAction": { "resourceJson": JSON.stringify({ "field_1": field_1, "field_2": field_2, }) } } } }; }The provider function must return the value of the custom resource by retrieving it with an appropriate mechanism, like calling an API or reading a database.
To retrieve and return a custom resource by its ID, return it as
returnOutputVariablesAction, as shown inonExecuteResourceFunction().Apps Script
function onExecuteResourceFunction(e) { var resource_id = e.workflow.resourceRetrieval.resourceReference.resourceId; return { "hostAppAction": { "workflowAction": { "returnOutputVariablesAction": { "variableValues": [{ "variableId": "resource_data", "variableData": { "resourceReferences" : [ resource_id ] } }] } } } }; }
Here's a complete example:
Apps Script
function onMessageResourceFunction(e) {
var resource_id = e.workflow.resourceRetrieval.resourceReference.resourceId;
var field_1 = ...;
var field_2 = ...;
return {
"hostAppAction": {
"workflowAction": {
"resourceRetrievedAction": {
"resourceJson": JSON.stringify({
"field_1": field_1,
"field_2": field_2,
})
}
}
}
};
}
function onExecuteResourceFunction(e) {
var resource_id = e.workflow.resourceRetrieval.resourceReference.resourceId;
return {
"hostAppAction": {
"workflowAction": {
"returnOutputVariablesAction": {
"variableValues": [{
"variableId": "resource_data",
"variableData": {
"resourceReferences" : [ resource_id ]
}
}]
}
}
}
};
}
Output a custom resource as a value
When you output a custom resource as a reference, you return the custom resource
by its ID instead of the full custom resource object. If you need to pass the
entire resource object, you can with resourceValues.
In resourceValues, you define the output of a step.
To output a custom resource as a value, edit the step's manifest file and code.
Edit the manifest file
In the manifest file:
Specify a
workflowResourceDefinitionsand assign it an id.TheworkflowResourceDefinitionsis a structure that defines data types and contents of the custom resource. WithinworkflowResourceDefinitions, you specify the individual fields that make up the custom resource, in this example calledfield_1andfield_2.Specify a
providerFunctionwhose value is the name of a function in the step's code. TheproviderFunctionretrieves actual custom resource content when needed.JSON
{ "workflowResourceDefinitions": [ { "id": "resource_id", "name": "Custom Resource", "fields": [ { "selector": "field_1", "name": "Field 1", "dataType": { "basicType": "STRING" } }, { "selector": "field_2", "name": "Field 2", "dataType": { "basicType": "STRING" } } ], "providerFunction": "onExecuteResourceAsValuesFunction" } ] }In
outputs[], specify an output variable that returnsresourceValues. The value ofcardinalitymust beSINGLE.JSON
{ "outputs": [ { "id": "resource_data", "description": "Resource Data", "cardinality": "SINGLE", "dataType": { "resourceValues": { "value1": "value one" } } } ] }
Here's a complete manifest file which defines a custom resource:
JSON
{
"timeZone": "America/Los_Angeles",
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"addOns": {
"common": {
"name": "Calculator",
"logoUrl": "https://www.gstatic.com/images/branding/productlogos/calculator_search/v1/web-24dp/logo_calculator_search_color_1x_web_24dp.png",
"useLocaleFromApp": true
},
"flows": {
"workflowElements": [
{
"id": "getResourceData",
"state": "ACTIVE",
"name": "Get Resource by ID",
"description": "Get Resource by ID",
"workflowAction": {
"outputs": [
{
"id": "resource_data",
"description": "Resource Data",
"cardinality": "SINGLE",
"dataType": {
"resourceValues": {
"value1": "value one"
}
}
}
],
"onConfigFunction": "onConfigResourceFunction",
"onExecuteFunction": "onExecuteResourceFunction"
}
}
],
"workflowResourceDefinitions": [
{
"id": "resource_id",
"name": "Custom Resource",
"fields": [
{
"selector": "field_1",
"name": "Field 1",
"dataType": {
"basicType": "STRING"
}
},
{
"selector": "field_2",
"name": "Field 2",
"dataType": {
"basicType": "STRING"
}
}
],
"providerFunction": "onExecuteResourceAsValuesFunction"
}
]
}
}
}
Edit the code
In the application code, implement the providerFunction, called
onExecuteResourceAsValuesFunction() in this example, which defines and returns
the custom resource as JSON, here abstracted as resourceJSON:
Apps Script
function onExecuteResourceAsValuesFunction() {
var field_1 = "value 1";
var field_2 = "value 2";
var resourceJSON = JSON.stringify({
"field_1": field_1,
"field_2": field_2,
});
return {
"hostAppAction": {
"workflowAction": {
"returnOutputVariablesAction": {
"variableValues": [{
"variableId": "resource_data",
"variableData": {
"resourceValues" : [ resourceJSON ]
}
}]
}
}
}
};
}
Related topics
- Input variables
- Validate an input variable
- Output variables
- Log activity and errors
- Flow event object