Universal actions

Universal actions are menu item elements that allow a user to open a new web page, display new UI cards, or run a specific Apps Script function when selected. In operation they are very similar to card actions , except that universal actions are always placed on every card in your add-on, regardless of the current add-on context.

By using universal actions, you can make sure the user always has access to certain functionality, regardless of which part of your add-on they interact with. Here are some example use cases for universal actions:

  • Open a settings web page (or display a settings card).
  • Show help information to the user.
  • Start a new workflow, such as 'Add new customer'.
  • Display a card that lets a user send feedback about the add-on.

Whenever you have an action that does not depend on the current context, you should consider making it a universal action.

Using universal actions

Universal actions are configured in your add-on's project manifest . Once you've configured a universal action, it is always available to users of your add-on. If the user is viewing a card, the set of universal actions you've defined always appears in the card menu, after any card actions you've defined for that card. Universal actions appear in the card menus in the same order in which they are defined in the add-on's manifest.

Configuring universal actions

You configure universal actions in your add-on's manifest; see Manifests for more details.

For each action, you specify the text that should appear in the menu for that action. You can then specify an openLink field indicating that the action should directly open a web page in a new tab. Alternatively, you can specify a runFunction field that specifies an Apps Script callback function to execute when the universal action is selected.

When runFunction is used, the callback function specified usually does one of the following:

  • Builds UI cards to display immediately by returning a built UniversalActionResponse object.
  • Opens a URL, perhaps after doing other tasks, by returning a built UniversalActionResponse object.
  • Conducts background tasks that do not switch to a new card or open a URL. In this case the callback function returns nothing.

When called, the callback function is passed an event object containing information about the open card and add-on context.

Example

The following code snippet shows an example manifest excerpt for a Google Workspace add-on that uses universal actions while extending Gmail. The code explicitly sets a metadata scope so that the add-on can determine who sent the open message.

 "oauthScopes": [
    "https://www.googleapis.com/auth/gmail.addons.current.message.metadata"
  ],
  "addOns": {
    "common": {
      "name": "Universal Actions Only Addon",
      "logoUrl": "https://www.example.com/hosted/images/2x/my-icon.png",
      "openLinkUrlPrefixes": [
        "https://www.google.com",
        "https://www.example.com/urlbase"
      ],
      "universalActions": [{
          "label": "Open google.com",
          "openLink": "https://www.google.com"
        }, {
          "label": "Open contact URL",
          "runFunction": "openContactURL"
        }, {
          "label": "Open settings",
          "runFunction": "createSettingsResponse"
        }, {
          "label": "Run background sync",
          "runFunction": "runBackgroundSync"
      }],
      ...
    },
    "gmail": {
      "contextualTriggers": [
        {
          "unconditional": {},
          "onTriggerFunction": "getContextualAddOn"
        }
      ]
    },
    ...
  },
  ... 

The three universal actions defined in preceding example do the following:

  • Open google.com opens https://www.google.com in a new tab.
  • Open contact URL runs a function that determines what URL to open and then opens it in a new tab using an OpenLink object. The code builds the URL using the sender's email address.
  • Open settings runs the createSettingsCards() function defined in the add-on script project. This function returns a valid UniversalActionResponse object containing a set of cards with add-on setting and other information. After the function finishes building this object, the UI displays the list of cards (see Returning multiple cards ).
  • Run background sync runs the runBackgroundSync() function defined in the add-on script project. This function does not build cards; instead it performs some other background tasks that do not change the UI. Since the function doesn't return a UniversalActionResponse , the UI does not display a new card when the function finishes. Instead the UI displays a loading indicator spinner while the function is running.

Here is an example of how you might construct the openContactURL() , createSettingsResponse() , and runBackgroundSync() functions:

  /** 
  
 * 
  
 Open 
  
 a 
  
 contact 
  
 URL 
 . 
  
 * 
  
 @ 
 param 
  
 { 
 Object 
 } 
  
 e 
  
 an 
  
 event 
  
 object 
  
 * 
  
 @ 
 return 
  
 { 
 UniversalActionResponse 
 } 
  
 */ 
 function 
  
 openContactURL 
 ( 
 e 
 ) 
  
 { 
  
 // 
  
 Activate 
  
 temporary 
  
 Gmail 
  
 scopes 
 , 
  
 in 
  
 this 
  
 case 
  
 so 
  
 that 
  
 the 
  
 // 
  
 open 
  
 message 
  
 metadata 
  
 can 
  
 be 
  
 read 
 . 
  
 var 
  
 accessToken 
  
 = 
  
 e 
 . 
 gmail 
 . 
 accessToken 
 ; 
  
 GmailApp 
 . 
 setCurrentMessageAccessToken 
 ( 
 accessToken 
 ); 
  
 // 
  
 Build 
  
 URL 
  
 to 
  
 open 
  
 based 
  
 on 
  
 a 
  
 base 
  
 URL 
  
 and 
  
 the 
  
 sender 
 's email. 
  
 // 
  
 This 
  
 URL 
  
 must 
  
 be 
  
 included 
  
 in 
  
 the 
  
 openLinkUrlPrefixes 
  
 whitelist 
 . 
  
 var 
  
 messageId 
  
 = 
  
 e 
 . 
 gmail 
 . 
 messageId 
 ; 
  
 var 
  
 message 
  
 = 
  
 GmailApp 
 . 
 getMessageById 
 ( 
 messageId 
 ); 
  
 var 
  
 sender 
  
 = 
  
 message 
 . 
 getFrom 
 (); 
  
 var 
  
 url 
  
 = 
  
 "https://www.example.com/urlbase/" 
  
 + 
  
 sender 
 ; 
  
 return 
  
 CardService 
 . 
 newUniversalActionResponseBuilder 
 () 
  
 . 
 setOpenLink 
 ( 
 CardService 
 . 
 newOpenLink 
 () 
  
 . 
 setUrl 
 ( 
 url 
 )) 
  
 . 
 build 
 (); 
 } 
 /** 
  
 * 
  
 Create 
  
 a 
  
 collection 
  
 of 
  
 cards 
  
 to 
  
 control 
  
 the 
  
 add 
 - 
 on 
  
 settings 
  
 and 
  
 * 
  
 present 
  
 other 
  
 information 
 . 
  
 These 
  
 cards 
  
 are 
  
 displayed 
  
 in 
  
 a 
  
 list 
  
 when 
  
 * 
  
 the 
  
 user 
  
 selects 
  
 the 
  
 associated 
  
 "Open settings" 
  
 universal 
  
 action 
 . 
  
 * 
  
 * 
  
 @ 
 param 
  
 { 
 Object 
 } 
  
 e 
  
 an 
  
 event 
  
 object 
  
 * 
  
 @ 
 return 
  
 { 
 UniversalActionResponse 
 } 
  
 */ 
 function 
  
 createSettingsResponse 
 ( 
 e 
 ) 
  
 { 
  
 return 
  
 CardService 
 . 
 newUniversalActionResponseBuilder 
 () 
  
 . 
 displayAddOnCards 
 ( 
  
 [ 
 createSettingCard 
 (), 
  
 createAboutCard 
 ()]) 
  
 . 
 build 
 (); 
 } 
 /** 
  
 * 
  
 Create 
  
 and 
  
 return 
  
 a 
  
 built 
  
 settings 
  
 card 
 . 
  
 * 
  
 @ 
 return 
  
 { 
 Card 
 } 
  
 */ 
 function 
  
 createSettingCard 
 () 
  
 { 
  
 return 
  
 CardService 
 . 
 newCardBuilder 
 () 
  
 . 
 setHeader 
 ( 
 CardService 
 . 
 newCardHeader 
 () 
 . 
 setTitle 
 ( 
 'Settings' 
 )) 
  
 . 
 addSection 
 ( 
 CardService 
 . 
 newCardSection 
 () 
  
 . 
 addWidget 
 ( 
 CardService 
 . 
 newSelectionInput 
 () 
  
 . 
 setType 
 ( 
 CardService 
 . 
 SelectionInputType 
 . 
 CHECK_BOX 
 ) 
  
 . 
 addItem 
 ( 
 "Ask before deleting contact" 
 , 
  
 "contact" 
 , 
  
 false 
 ) 
  
 . 
 addItem 
 ( 
 "Ask before deleting cache" 
 , 
  
 "cache" 
 , 
  
 false 
 ) 
  
 . 
 addItem 
 ( 
 "Preserve contact ID after deletion" 
 , 
  
 "contactId" 
 , 
  
 false 
 )) 
  
 // 
  
 ... 
  
 continue 
  
 adding 
  
 widgets 
  
 or 
  
 other 
  
 sections 
  
 here 
  
 ... 
  
 ) 
 . 
 build 
 (); 
  
 // 
  
 Don 
 't forget to build the card! 
 } 
 /** 
  
 * 
  
 Create 
  
 and 
  
 return 
  
 a 
  
 built 
  
 'About' 
  
 informational 
  
 card 
 . 
  
 * 
  
 @ 
 return 
  
 { 
 Card 
 } 
  
 */ 
 function 
  
 createAboutCard 
 () 
  
 { 
  
 return 
  
 CardService 
 . 
 newCardBuilder 
 () 
  
 . 
 setHeader 
 ( 
 CardService 
 . 
 newCardHeader 
 () 
 . 
 setTitle 
 ( 
 'About' 
 )) 
  
 . 
 addSection 
 ( 
 CardService 
 . 
 newCardSection 
 () 
  
 . 
 addWidget 
 ( 
 CardService 
 . 
 newTextParagraph 
 () 
  
 . 
 setText 
 ( 
 'This add-on manages contact information. For more ' 
  
 + 
  
 'details see the <a href="https://www.example.com/help">' 
  
 + 
  
 'help page</a>.' 
 )) 
  
 // 
  
 ... 
  
 add 
  
 other 
  
 information 
  
 widgets 
  
 or 
  
 sections 
  
 here 
  
 ... 
  
 ) 
 . 
 build 
 (); 
  
 // 
  
 Don 
 't forget to build the card! 
 } 
 /** 
  
 * 
  
 Run 
  
 background 
  
 tasks 
 , 
  
 none 
  
 of 
  
 which 
  
 should 
  
 alter 
  
 the 
  
 UI 
 . 
  
 * 
  
 Also 
  
 records 
  
 the 
  
 time 
  
 of 
  
 sync 
  
 in 
  
 the 
  
 script 
  
 properties 
 . 
  
 * 
  
 * 
  
 @ 
 param 
  
 { 
 Object 
 } 
  
 e 
  
 an 
  
 event 
  
 object 
  
 */ 
 function 
  
 runBackgroundSync 
 ( 
 e 
 ) 
  
 { 
  
 var 
  
 props 
  
 = 
  
 PropertiesService 
 . 
 getUserProperties 
 (); 
  
 props 
 . 
 setProperty 
 ( 
 "syncTime" 
 , 
  
 new 
  
 Date 
 () 
 . 
 toString 
 ()); 
  
 syncWithContacts 
 (); 
  
 // 
  
 Not 
  
 shown 
 . 
  
 updateCache 
 (); 
  
 // 
  
 Not 
  
 shown 
 . 
  
 validate 
 (); 
  
 // 
  
 Not 
  
 shown 
 . 
  
 // 
  
 no 
  
 return 
  
 value 
  
 tells 
  
 the 
  
 UI 
  
 to 
  
 keep 
  
 showing 
  
 the 
  
 current 
  
 card 
 . 
 } 
 
Create a Mobile Website
View Site in Mobile | Classic
Share by: