Actions universelles

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Les actions universelles sont des éléments d'élément de menu qui permettent à un utilisateur d'ouvrir une nouvelle page Web, d'afficher de nouvelles fiches d'interface utilisateur ou d'exécuter une fonction Apps Script spécifique lorsqu'il est sélectionné. En fonctionnement, elles sont très semblables aux actions des fiches, à ceci près que les actions universelles sont toujours placées sur chaque carte de votre module complémentaire, quel que soit le contexte actuel du module.

Grâce aux actions universelles, vous pouvez vous assurer que l'utilisateur a toujours accès à certaines fonctionnalités, quelle que soit la partie de votre module complémentaire avec laquelle il interagit. Voici quelques exemples d'utilisation des actions universelles:

  • Ouvrez la page Web des paramètres (ou affichez une fiche de paramètres).
  • Montrez des informations d'aide à l'utilisateur.
  • Lancez un nouveau workflow, par exemple "Ajouter un nouveau client".
  • Afficher une fiche qui permet à un utilisateur d'envoyer des commentaires sur le module complémentaire.

Chaque fois que vous avez une action qui ne dépend pas du contexte actuel, vous devez envisager de la transformer en action universelle.

Utiliser des actions universelles

Les actions universelles sont configurées dans le fichier manifeste du projet de votre module complémentaire. Une fois que vous avez configuré une action universelle, elle reste disponible pour les utilisateurs de votre module complémentaire. Si l'utilisateur affiche une fiche, l'ensemble des actions universelles que vous avez définies s'affiche toujours dans le menu de la fiche, après toutes les actions associées à cette fiche. Les actions universelles apparaissent dans les menus de la carte dans l'ordre dans lequel elles sont définies dans le fichier manifeste du module complémentaire.

Configurer des actions universelles

Vous configurez les actions universelles dans le fichier manifeste de votre module complémentaire. Pour en savoir plus, consultez la section Fichiers manifestes.

Pour chaque action, vous spécifiez le texte qui doit apparaître dans le menu de cette action. Vous pouvez ensuite spécifier un champ openLink indiquant que l'action doit ouvrir directement une page Web dans un nouvel onglet. Vous pouvez également spécifier un champ runFunction qui spécifie une fonction de rappel Apps Script à exécuter lorsque l'action universelle est sélectionnée.

Lorsque runFunction est utilisé, la fonction de rappel spécifiée effectue généralement l'une des opérations suivantes:

  • Compile des fiches d'interface utilisateur à afficher immédiatement en renvoyant un objet UniversalActionResponse compilé.
  • Ouvre une URL, éventuellement après d'autres tâches, en renvoyant un objet UniversalActionResponse compilé.
  • effectue des tâches en arrière-plan qui ne basculent pas vers une nouvelle fiche ou n'ouvrent pas d'URL. Dans ce cas, la fonction de rappel ne renvoie rien.

Lorsqu'elle est appelée, la fonction de rappel reçoit un objet d'événement contenant des informations sur la carte ouverte et le contexte du module complémentaire.

Exemple

L'extrait de code suivant présente un exemple de fichier manifeste pour un module complémentaire Google Workspace qui utilise des actions universelles tout en étendant Gmail. Le code définit explicitement un champ d'application des métadonnées afin que le module complémentaire puisse déterminer qui a envoyé le message ouvert.

  "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"
        }
      ]
    },
    ...
  },
  ...

Voici les trois actions universelles définies dans l'exemple précédent:

  • Ouvrir google.com ouvre https://www.google.com dans un nouvel onglet.
  • L'option Ouvrir l'URL du contact exécute une fonction qui détermine l'URL à ouvrir, puis l'ouvre dans un nouvel onglet à l'aide d'un objet OpenLink. Le code crée l'URL à l'aide de l'adresse e-mail de l'expéditeur.
  • L'option Ouvrir les paramètres exécute la fonction createSettingsCards() définie dans le projet de script du module complémentaire. Cette fonction affiche un objet UniversalActionResponse valide contenant un ensemble de fiches avec un paramètre de module complémentaire et d'autres informations. Une fois que l'objet a été créé, l'interface utilisateur affiche la liste des cartes (voir Renvoyer plusieurs cartes).
  • L'option Exécuter la synchronisation en arrière-plan exécute la fonction runBackgroundSync() définie dans le projet de script du module complémentaire. Cette fonction ne crée pas de fiches. Elle effectue d'autres tâches en arrière-plan qui ne modifient pas l'interface utilisateur. Comme la fonction ne renvoie pas de UniversalActionResponse, l'interface utilisateur n'affiche pas de nouvelle carte une fois la fonction terminée. Au lieu de cela, l'interface utilisateur affiche une icône de chargement lorsque la fonction est en cours d'exécution.

Voici un exemple de création des fonctions openContactURL(), createSettingsResponse() et runBackgroundSync():

/**
 * 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.
}