This guide explains how to build a configuration card that lets users customize and provide inputs for a step in Google Workspace Flows.
In general, to build a configuration card, you build a card interface like you would for any other Google Workspace add-on. For help building configuration card interfaces, see the following:
- The Card Builder, an interactive tool that helps you build and define cards.
- Card in the Google Workspace add-ons API reference documentation.
- Card Service, an Apps Script service that lets scripts configure and build cards.
- Card-based interfaces in the Google Workspace add-ons developer documentation.
Some card widgets have special Workspace Flows-specific functionality and features, detailed in this guide.
Define a configuration card
Define a configuration card in both the Apps Script manifest and in code.
The following example shows how to build a configuration card that asks users to select a Google Chat space.
Edit the manifest file
In the manifest file, define workflowElements.
JSON
{
"timeZone": "America/Los_Angeles",
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"addOns": {
"common": {
"name": "Sample add-on",
"logoUrl": "https://www.gstatic.com/images/branding/productlogos/gsuite_addons/v6/web-24dp/logo_gsuite_addons_color_1x_web_24dp.png",
"useLocaleFromApp": true
},
"flows": {
"workflowElements": [
{
"id": "actionElement",
"state": "ACTIVE",
"name": "Chat space selector",
"description": "Lets the user select a space from Google Chat",
"workflowAction": {
"inputs": [
{
"id": "chooseSpace",
"description": "Choose a Chat space",
"cardinality": "SINGLE",
"dataType": {
"basicType": "STRING"
}
}
],
"onConfigFunction": "onConfigSpacePicker",
"onExecuteFunction": "onExecuteCalculate"
}
}
]
}
}
}
Edit the code
In the application code, return a card.
Apps Script
/**
* Generates and displays a configuration card to choose a Chat space
*/
function onConfigSpacePicker() {
var card = {
"sections": [
{
"header": "Choose a Chat space",
"widgets": [
{
"selectionInput": {
"name": "value1",
"label": "First value",
"type": "MULTI_SELECT",
"platformDataSource": {
"hostAppDataSource": {
"workflowDataSource": {
"includeVariables": true,
"type": "SPACE"
}
}
}
}
}
]
}
]
};
return {
"action": {
"navigations": [{
"push_card": card
}]
}
};
}
Set up autocomplete for input widgets
You can configure autocomplete for
SelectionInput widgets to help users select from a list of options. For
example, if a user starts typing Atl for a menu that populates cities in the
United States, your element can autosuggest Atlanta before the user finishes
typing. You can autocomplete up to 100 items.
Autocomplete suggestions can come from the following data sources:
- Server-side autocomplete: Suggestions are populated from a third-party or external data source that you define.
- Google Workspace data: Suggestions are populated from Google Workspace sources, such as Google Workspace users or Google Chat spaces.
Server-side autocomplete
You can configure a
SelectionInput widget to autocomplete suggestions from an external data
source. For example, you can help users select from a list of sales leads from a
customer relationship management (CRM) system.
To implement server-side autocomplete, you need to:
- Define the data source: In the
SelectionInputwidget, add aDataSourceConfigthat specifies aRemoteDataSource. This configuration points to an Apps Script function that fetches autocomplete suggestions. - Implement the autocomplete function: This function is triggered when the user types in the input field. The function should query your external data source based on the user's input and return a list of suggestions.
The following example shows how to configure a
SelectionInput
widget for server-side autocomplete:
Apps Script
// In your onConfig function:
var multiSelect1 =
CardService.newSelectionInput()
.setFieldName("value1")
.setTitle("Server Autocomplete")
.setType(CardService.SelectionInputType.MULTI_SELECT)
.setMultiSelectMaxSelectedItems(3)
.addDataSourceConfig(
CardService.newDataSourceConfig()
.setRemoteDataSource(
CardService.newAction().setFunctionName('getAutocompleteResults')
)
)
.addDataSourceConfig(
CardService.newDataSourceConfig()
.setPlatformDataSource(
CardService.newPlatformDataSource()
.setHostAppDataSource(
CardService.newHostAppDataSource()
.setWorkflowDataSource(
CardService.newWorkflowDataSource()
.setIncludeVariables(true)
))
)
);
// ... add widget to card ...
Handle the autocomplete request
The function specified in
setFunctionName (e.g., getAutocompleteResults) receives an
event object when the user types in the field. This function must:
- Check the
event.workflow.elementUiAutocomplete.invokedFunctionto make sure it matches the expected function name. - Get the user's input from
event.workflow.elementUiAutocomplete.query. - Query the external data source using the query.
- Return up to 100 suggestions in the required format.
The following example shows how to implement the handleAutocompleteRequest()
function to return suggestions based on the user's query:
Apps Script
function handleAutocompleteRequest(event) {
var invokedFunction = event.workflow.elementUiAutocomplete.invokedFunction;
var query = event.workflow.elementUiAutocomplete.query;
if (invokedFunction != "getAutocompleteResults" || query == undefined || query == "") {
return {};
}
// Query your data source to get results based on the query
var autocompleteResponse = [
{
"text": query + " option 1",
"value": query + "_option1",
"start_icon_uri": "https://developers.google.com/workspace/add-ons/images/person-icon.png"
},
{
"text": query + " option 2",
"value": query + "_option2",
"start_icon_uri": "https://developers.google.com/workspace/add-ons/images/person-icon.png",
"bottom_text": "subtitle of option 2"
},
{
"text": query + " option 3",
"value": query + "_option3",
"start_icon_uri": "https://developers.google.com/workspace/add-ons/images/person-icon.png"
}
];
var response = {
"action": {
"modify_operations": [
{
"update_widget": {
"selection_input_widget_suggestions": {
"suggestions": autocompleteResponse
}
}
}
]
}
};
return response;
}
// In your onConfig function, handle the autocomplete event
function onConfigAutocompleteTest(event) {
// Handle autocomplete request
if (event.workflow && event.workflow.elementUiAutocomplete) {
return handleAutocompleteRequest(event);
}
// ... rest of your card building logic ...
}
Google Workspace data autocomplete
You can also populate autocomplete suggestions from data within the user's Google Workspace environment:
- Google Workspace users: Populate users within the same Google Workspace organization.
- Google Chat spaces: Populate Google Chat spaces that the user is a member of.
To configure this, set the
PlatformDataSource
in the
SelectionInput
widget, specifying the
WorkflowDataSourceType
as either USER or SPACE.
Apps Script
// User Autocomplete
var multiSelect2 =
CardService.newSelectionInput()
.setFieldName("value2")
.setTitle("User Autocomplete")
.setType(CardService.SelectionInputType.MULTI_SELECT)
.setMultiSelectMaxSelectedItems(3)
.setPlatformDataSource(
CardService.newPlatformDataSource()
.setHostAppDataSource(
CardService.newHostAppDataSource()
.setWorkflowDataSource(
CardService.newWorkflowDataSource()
.setIncludeVariables(true)
.setType(CardService.WorkflowDataSourceType.USER)
))
);
// Chat Space Autocomplete
var multiSelect3 =
CardService.newSelectionInput()
.setFieldName("value3")
.setTitle("Chat Space Autocomplete")
.setType(CardService.SelectionInputType.MULTI_SELECT)
.setMultiSelectMaxSelectedItems(3)
.setPlatformDataSource(
CardService.newPlatformDataSource()
.setHostAppDataSource(
CardService.newHostAppDataSource()
.setWorkflowDataSource(
CardService.newWorkflowDataSource()
.setIncludeVariables(true)
.setType(CardService.WorkflowDataSourceType.SPACE)
))
);
Example: Combining autocomplete types
The following example shows an onConfig function that creates a card with
three SelectionInput
widgets, demonstrating server-side, user, and space autocomplete:
Apps Script
function onConfigAutocompleteTest(event) {
// Handle autocomplete request
if (event.workflow && event.workflow.elementUiAutocomplete) {
return handleAutocompleteRequest(event);
}
// Server-side autocomplete widget
var multiSelect1 =
CardService.newSelectionInput()
.setFieldName("value1")
.setTitle("Server Autocomplete")
.setType(CardService.SelectionInputType.MULTI_SELECT)
.setMultiSelectMaxSelectedItems(3)
.addDataSourceConfig(
CardService.newDataSourceConfig()
.setRemoteDataSource(
CardService.newAction().setFunctionName('getAutocompleteResults')
)
)
.addDataSourceConfig(
CardService.newDataSourceConfig()
.setPlatformDataSource(
CardService.newPlatformDataSource()
.setHostAppDataSource(
CardService.newHostAppDataSource()
.setWorkflowDataSource(
CardService.newWorkflowDataSource()
.setIncludeVariables(true)
))
)
);
// User autocomplete widget
var multiSelect2 =
CardService.newSelectionInput()
.setFieldName("value2")
.setTitle("User Autocomplete")
.setType(CardService.SelectionInputType.MULTI_SELECT)
.setMultiSelectMaxSelectedItems(3)
.setPlatformDataSource(
CardService.newPlatformDataSource()
.setHostAppDataSource(
CardService.newHostAppDataSource()
.setWorkflowDataSource(
CardService.newWorkflowDataSource()
.setIncludeVariables(true)
.setType(CardService.WorkflowDataSourceType.USER)
))
);
// Space autocomplete widget
var multiSelect3 =
CardService.newSelectionInput()
.setFieldName("value3")
.setTitle("Chat Space Autocomplete")
.setType(CardService.SelectionInputType.MULTI_SELECT)
.setMultiSelectMaxSelectedItems(3)
.setPlatformDataSource(
CardService.newPlatformDataSource()
.setHostAppDataSource(
CardService.newHostAppDataSource()
.setWorkflowDataSource(
CardService.newWorkflowDataSource()
.setIncludeVariables(true)
.setType(CardService.WorkflowDataSourceType.SPACE)
))
);
var sectionBuilder =
CardService.newCardSection()
.addWidget(multiSelect1)
.addWidget(multiSelect2)
.addWidget(multiSelect3);
var card =
CardService.newCardBuilder()
.addSection(sectionBuilder)
.build();
return card;
}
function handleAutocompleteRequest(event) {
var invokedFunction = event.workflow.elementUiAutocomplete.invokedFunction;
var query = event.workflow.elementUiAutocomplete.query;
if (invokedFunction != "getAutocompleteResults" || query == undefined || query == "") {
return {};
}
// Query your data source to get results
var autocompleteResponse = [
{
"text": query + " option 1",
"value": query + "_option1",
"start_icon_uri": "https://developers.google.com/workspace/add-ons/images/person-icon.png"
},
{
"text": query + " option 2",
"value": query + "_option2",
"start_icon_uri": "https://developers.google.com/workspace/add-ons/images/person-icon.png",
"bottom_text": "subtitle of option 2"
},
{
"text": query + " option 3",
"value": query + "_option3",
"start_icon_uri": "https://developers.google.com/workspace/add-ons/images/person-icon.png"
}
];
var response = {
"action": {
"modify_operations": [
{
"update_widget": {
"selection_input_widget_suggestions": {
"suggestions": autocompleteResponse
}
}
}
]
}
};
return response;
}
Workspace Flows-specific features
Some card widgets have special Workspace Flows-specific functionality and features, detailed here.
TextInput and SelectionInput
The TextInput and SelectionInput widgets have these
Workspace Flows-specific features:
includeVariables: A boolean property that lets users select variables from prior steps.type: An enumerated value that autocompletes suggestions. Supported values include:USER: Provides autocomplete suggestions for people in the user's contacts.SPACE: Provides autocomplete suggestions for Google Chat spaces the user is a member of.
When both includeVariables and type are set, the input field combines their
experiences. Users can select a variable of the matching type from a drop-down
menu, and see autocomplete suggestions for it.
-
Figure 1: A user reviews autocomplete suggestions when choosing a space. -
Figure 2: A user selects the output variable of a prior step from the ➕Variables drop-down.
Card considerations and limitations
Card navigation like
popCard(),pushCard(), andupdateCard()aren't supported in add-ons that extend Flows.When
SelectionInputis used in a variable picker, widgets only support"type": "MULTI_SELECT". Elsewhere in configuration cards,SelectionInputsupports all values ofSelectionType.
Related topics
- Build a step
- Input variables
- Validate an input variable
- Output variables
- Log activity and errors
- Flows event object