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.

