Represent complex data with a custom resource Stay organized with collections Save and categorize content based on your preferences.
This guide explains how to define custom resources for Google Workspace Studio.
Custom resources are custom data structures that you can define to groupmultiple variables together. When a step's output has a static structure,represent it with a custom resource.For example, to create a CRM lead, your output requires multiple variables:
- Email address
- Street address
- Name
To ensure the presence of all data required to create aCRM lead, output a custom resource containing an email address, street address,and name.
Output a custom resource as a reference
By outputting a custom resource as a reference, you can return the customresource by its ID instead of the full custom resource object. If a customresource is large or complex, passing only the ID improves performance byreducing the data transferred between steps.
To output a custom resource as a reference, edit the step's manifest file andcode.
Edit the manifest file
In the manifest file:
Specify a
workflowResourceDefinitionsand assign it anid, afields[]array, and aproviderFunction. TheworkflowResourceDefinitionsis astructure that defines data types and contents of the custom resource.Within the
fields[]array, you specify the individual fields that make upthe custom resource, in this example calledfield_1andfield_2.The
providerFunction's value must match the name of a function in thestep's code. TheproviderFunctionretrieves actual custom resource contentwhen 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 ofoutput 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":"Custom Resource (as reference)","logoUrl":"https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png","useLocaleFromApp":true},"flows":{"workflowElements":[{"id":"getResourceDataReference","state":"ACTIVE","name":"Custom Resource (as reference)","description":"Output a custom resource as a reference","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()inthis example, which retrieves custom resource content when needed. It takesthe inputewhich is the step'sevent object JSON payload, andfrom it sets the custom resource ID.Apps Script
functiononMessageResourceFunction(e){console.log("Payload in onMessageResourceFunction: "+JSON.stringify(e));varresource_id=e.workflow.resourceRetrieval.resourceReference.resourceId;letfieldValue_1;letfieldValue_2;// Using a if-condition to mock a database call.if(resource_id=="sample_resource_reference_id"){fieldValue_1=AddOnsResponseService.newVariableData().addStringValue("value1");fieldValue_2=AddOnsResponseService.newVariableData().addStringValue("value2");}else{fieldValue_1=AddOnsResponseService.newVariableData().addStringValue("field_1 value not found");fieldValue_2=AddOnsResponseService.newVariableData().addStringValue("field_2 value not found");}letresourceData=AddOnsResponseService.newResourceData().addVariableData("field_1",fieldValue_1).addVariableData("field_2",fieldValue_2)letworkflowAction=AddOnsResponseService.newResourceRetrievedAction().setResourceData(resourceData)lethostAppAction=AddOnsResponseService.newHostAppAction().setWorkflowAction(workflowAction);returnAddOnsResponseService.newRenderActionBuilder().setHostAppAction(hostAppAction).build();}The provider function must return the value of the custom resource byretrieving it with an appropriate mechanism, like calling an API or readinga database.
To retrieve and return a custom resource by its ID, return it as
returnOutputVariablesAction, as shown inonExecuteResourceFunction().Apps Script
functiononExecuteResourceFunction(e){console.log("Payload in onExecuteResourceFunction: "+JSON.stringify(e));letoutputVariables=AddOnsResponseService.newVariableData().addResourceReference("sample_resource_reference_id");letworkflowAction=AddOnsResponseService.newReturnOutputVariablesAction().addVariableData("resource_data",outputVariables);lethostAppAction=AddOnsResponseService.newHostAppAction().setWorkflowAction(workflowAction);returnAddOnsResponseService.newRenderActionBuilder().setHostAppAction(hostAppAction).build();}
Here's a complete example:
Apps Script
functiononConfigResourceFunction(){letsection=CardService.newCardSection().addWidget(CardService.newTextParagraph().setText("This is the Custom Resource Demo card"));constcard=CardService.newCardBuilder().addSection(section).build();returncard;}functiononMessageResourceFunction(e){console.log("Payload in onMessageResourceFunction: "+JSON.stringify(e));varresource_id=e.workflow.resourceRetrieval.resourceReference.resourceId;letfieldValue_1;letfieldValue_2;// Using a if-condition to mock a database call.if(resource_id=="sample_resource_reference_id"){fieldValue_1=AddOnsResponseService.newVariableData().addStringValue("value1");fieldValue_2=AddOnsResponseService.newVariableData().addStringValue("value2");}else{fieldValue_1=AddOnsResponseService.newVariableData().addStringValue("field_1 value not found");fieldValue_2=AddOnsResponseService.newVariableData().addStringValue("field_2 value not found");}letresourceData=AddOnsResponseService.newResourceData().addVariableData("field_1",fieldValue_1).addVariableData("field_2",fieldValue_2)letworkflowAction=AddOnsResponseService.newResourceRetrievedAction().setResourceData(resourceData)lethostAppAction=AddOnsResponseService.newHostAppAction().setWorkflowAction(workflowAction);returnAddOnsResponseService.newRenderActionBuilder().setHostAppAction(hostAppAction).build();}functiononExecuteResourceFunction(e){console.log("Payload in onExecuteResourceFunction: "+JSON.stringify(e));letoutputVariables=AddOnsResponseService.newVariableData().addResourceReference("sample_resource_reference_id");letworkflowAction=AddOnsResponseService.newReturnOutputVariablesAction().addVariableData("resource_data",outputVariables);lethostAppAction=AddOnsResponseService.newHostAppAction().setWorkflowAction(workflowAction);returnAddOnsResponseService.newRenderActionBuilder().setHostAppAction(hostAppAction).build();}Related topics
- Input variables
- Validate an input variable
- Output variables
- Log activity and errors
- Workspace Studio event objects
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-11 UTC.