Créer un starter

Ce document explique comment créer un déclencheur qui permet à votre application ou à votre service d'envoyer une notification à Google Workspace Studio lorsqu'un événement se produit et de lancer l'exécution d'un flux. Dans l'API, les déclencheurs sont appelés workflowTriggers.

Un déclencheur lance un flux, tandis qu'une étape est une tâche unique dans la séquence de tâches qui composent un flux. En créant un déclencheur, vous permettez aux utilisateurs de configurer des flux automatisés qui réagissent aux événements en temps réel de votre application ou de votre service.

Pour créer un déclencheur, vous devez le déclarer dans le fichier manifeste du module complémentaire et implémenter des rappels de cycle de vie dans Google Apps Script, ou déclencher le déclencheur en publiant des charges utiles sur le point de terminaison de l'API Google Workspace Studio.

Prérequis

Activer l'API

Dans votre projet Google Cloud, activez l'API Google Workspace Studio :

Activer l'API

Passer à un projet Google Cloud standard (Google Apps Script uniquement)

Par défaut, les projets Apps Script utilisent un projet Cloud par défaut qui ne permet pas d'activer les API ni de configurer les écrans de consentement OAuth. Si vous créez votre déclencheur avec Apps Script, vous devez passer à un projet Google Cloud standard :

  1. Dans l'éditeur Apps Script, cliquez sur Paramètres du projet .
  2. Sous Projet Google Cloud Platform (GCP), cliquez sur Changer de projet.
  3. Saisissez le numéro de votre projet Cloud standard, puis cliquez sur Définir le projet.
  4. Après avoir changé de projet, réautorisez votre script en exécutant n'importe quelle fonction dans l'éditeur et en accordant les autorisations demandées.

Pour en savoir plus, consultez Passer à un projet Google Cloud standard.

Configurer l'écran de consentement OAuth

Pour communiquer avec le point de terminaison de l'API Workspace Studio, votre application ou votre service doit s'authentifier à l'aide d'OAuth 2.0. Configurez l'écran de consentement OAuth de votre projet et ajoutez le champ d'application OAuth dédié suivant :

https://www.googleapis.com/auth/workspace.studio.trigger

Ce champ d'application autorise l'application à appeler l'API Workspace Studio et à déclencher les flux que l'utilisateur a configurés pour ce déclencheur.

Pour en savoir plus, consultez Configurer l'écran de consentement OAuth et choisir des champs d'application.

Accès hors connexion et jetons d'actualisation

Étant donné que les déclencheurs envoient une notification asynchrone à Workspace Studio lorsqu'un événement se produit dans le service externe (ce qui peut se produire des heures, des jours ou des mois après qu'un utilisateur a configuré un flux), votre service doit fournir un jeton d'accès OAuth 2.0 valide lorsqu'il appelle le point de terminaison de l'API.

Le jeton d'accès fourni par Google dans l'objet d'événement du module complémentaire (par exemple, lors de la configuration du déclencheur ou des requêtes de rappel de cycle de vie) est temporaire et n'est valide que pendant une heure. Il ne suffit pas de déclencher des événements de déclencheur de manière asynchrone à l'avenir. Pour appeler l'API Workspace Studio au fil du temps, votre service nécessite un jeton d'actualisation hors connexion pour générer des jetons d'accès à la demande.

La façon dont vous gérez l'autorisation et obtenez un jeton d'actualisation dépend de l'environnement d'exécution de votre module complémentaire :

  • Modules complémentaires HTTP (autres environnements d'exécution) : pour les modules complémentaires HTTP, votre service de backend doit implémenter un flux d'autorisation OAuth 2.0 distinct de l'autorisation intégrée du module complémentaire afin de demander un accès hors connexion (access_type=offline) et de recevoir un jeton d'actualisation.

    Vous pouvez inviter les utilisateurs à autoriser cette connexion en affichant une carte de connexion ou d'autorisation lorsqu'ils configurent le déclencheur dans Workspace Studio. Pour en savoir plus sur le renvoi de cartes d'autorisation et la gestion du flux OAuth, consultez Associer votre module complémentaire Google Workspace à un service tiers (en traitant Google Workspace comme le service tiers auquel vous vous connectez).

    Votre service backend doit stocker le jeton d'actualisation de manière sécurisée (par exemple, dans la base de données de votre service à côté du triggerId) et l'utiliser pour récupérer un nouveau jeton d'accès chaque fois qu'un événement se produit avant d'envoyer des requêtes au notifyUri du déclencheur ou au point de terminaison de l'API triggers.fire.

  • Modules complémentaires Google Apps Script: les modules complémentaires basés sur Google Apps Script qui utilisent des déclencheurs planifiés (déclenchés par le temps) pour interroger les événements peuvent ignorer l'implémentation d'un flux OAuth indépendant. Étant donné que les déclencheurs planifiés s'exécutent directement dans l'environnement d'exécution Google Apps Script, Google Apps Script gère et actualise automatiquement les jetons OAuth à l'aide des champs d'application déclarés dans le fichier manifeste. Vous pouvez récupérer un jeton d'accès OAuth à l'aide de ScriptApp.getOAuthToken().

Définir le déclencheur dans le fichier manifeste

Pour définir un déclencheur, ajoutez-le au fichier manifeste de votre module complémentaire (appsscript.json) dans le bloc addOns.studio.flows.workflowElements. Cette configuration est requise pour les environnements d'exécution Apps Script et HTTP (autres environnements d'exécution). Configurez l'élément en tant que workflowTrigger au lieu de workflowAction (qui est utilisé lors de la définition d'une étape). Pour en savoir plus, consultez Structure du fichier manifeste pour les modules complémentaires Google Workspace.

Dans le bloc workflowTrigger, spécifiez les éléments suivants :

  • inputs: variables que l'utilisateur configure sur la carte de configuration (par exemple, nom du projet, filtre de ressources, etc.).
  • outputs: variables pouvant être renvoyées par le déclencheur aux étapes en aval du flux.
  • onConfigFunction: nom de la fonction de rappel qui affiche l'interface de configuration utilisateur.
  • onManageFunction: nom de la fonction de rappel appelée par Google pour gérer la création et la suppression d'abonnements de déclencheur.

L'exemple de code suivant montre un exemple de définition de fichier manifeste pour un déclencheur d'événement :

JSON

{
  "timeZone": "America/Los_Angeles",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/workspace.studio.trigger"
  ],
  "urlFetchWhitelist": [
    "https://workspacestudio.googleapis.com/"
  ],
  "addOns": {
    "common": {
      "name": "Trigger App",
      "logoUrl": "https://fonts.gstatic.com/s/i/short-term/release/googlesymbols/start/default/24px.svg",
      "useLocaleFromApp": true
    },
    "studio": {
      "flows": {
        "workflowElements": [
          {
            "id": "triggerDemo",
            "state": "ACTIVE",
            "name": "Event Trigger",
            "description": "Fires when a event occurs in the app.",
            "workflowTrigger": {
              "inputs": [
                {
                  "id": "projectId",
                  "description": "The project identifier to watch.",
                  "cardinality": "SINGLE",
                  "dataType": {
                    "basicType": "STRING"
                  }
                }
              ],
              "outputs": [
                {
                  "id": "eventName",
                  "description": "The name of the triggered event.",
                  "cardinality": "SINGLE",
                  "dataType": {
                    "basicType": "STRING"
                  }
                },
                {
                  "id": "eventMessage",
                  "description": "Detailed event message description.",
                  "cardinality": "SINGLE",
                  "dataType": {
                    "basicType": "STRING"
                  }
                }
              ],
              "onConfigFunction": "onConfigTrigger",
              "onManageFunction": "onManageTrigger"
            }
          }
        ]
      }
    }
  }
}

Gérer le cycle de vie de l'abonnement au déclencheur

Lorsqu'un utilisateur configure et active un flux contenant votre déclencheur, ou si le flux est désactivé ou supprimé, Google appelle votre module complémentaire à l'aide de la fonction de rappel onManageFunction déclarée dans le fichier manifeste.

Objet d'événement de cycle de vie

La fonction de rappel reçoit un WorkflowEventObject contenant le contexte de l'action. Pour les déclencheurs, cela inclut les éléments suivants :

  • Création de déclencheur (event.workflow.triggerCreation) : se déclenche lorsque le flux est publié ou activé.

    • triggerId: chaîne UUID unique identifiant cette instance d'enregistrement de déclencheur.

    • notifyUri : URL unique du point de terminaison de l'API REST associée à cet enregistrement de déclencheur (par exemple, https://workspacestudio.googleapis.com/v1/triggers/YOUR_TRIGGER_ID:fire). Si notifyUri est omis de la charge utile de l'événement, construisez directement l'URL du point de terminaison à l'aide de triggerId : https://workspacestudio.googleapis.com/v1/triggers/{triggerId}:fire.

    • inputs : entrées de variables configurées par l'utilisateur à partir de la carte.

  • Suppression de déclencheur (event.workflow.triggerDeletion) : se déclenche lorsque le déclencheur est supprimé du flux, ou lorsque l'ensemble du flux est désactivé ou supprimé.

    • triggerId: chaîne UUID unique de l'instance d'abonnement à nettoyer.

Cycle de vie de l'abonnement pour les autres environnements d'exécution (API HTTP)

Pour les modules complémentaires créés à l'aide d'autres environnements d'exécution, les notifications de cycle de vie de l'abonnement sont fournies à l'aide de requêtes POST HTTP à l'URL du point de terminaison HTTP configurée du module complémentaire, avec le nom de l'action spécifié par la fonction de rappel onManageFunction. La charge utile correspond à la représentation JSON de WorkflowEventObject.

Pour en savoir plus sur les autres environnements d'exécution, consultez Créer un module complémentaire Google Workspace à l'aide de points de terminaison HTTP.

Implémenter des rappels de cycle de vie dans Apps Script

L'exemple Apps Script suivant montre comment configurer la carte de l'interface utilisateur, gérer les événements de cycle de vie de l'abonnement à l'aide de onManageTrigger et renvoyer la requête de déclencheur à Google lorsqu'un événement se produit.

Apps Script

/**
 * Generates and returns the user configuration card to collect inputs.
 */
function onConfigTrigger() {
  const projectInput = CardService.newTextInput()
    .setFieldName("projectId")
    .setTitle("Project ID")
    .setHint("Enter the project identifier to watch");

  const section = CardService.newCardSection()
    .setHeader("Configure Event Trigger")
    .addWidget(projectInput);

  const card = CardService.newCardBuilder()
    .addSection(section)
    .build();

  return card;
}

/**
 * Handles subscription lifecycle events sent from Google Workspace Studio.
 *
 * @param {Object} event The Workspace Studio event object.
 */
function onManageTrigger(event) {
  const triggerCreation = event.workflow.triggerCreation;
  const triggerDeletion = event.workflow.triggerDeletion;

  if (triggerCreation) {
    const triggerId = triggerCreation.triggerId;
    // Fall back to constructing the endpoint URL if notifyUri is omitted.
    const notifyUri = triggerCreation.notifyUri ||
        ("https://workspacestudio.googleapis.com/v1/triggers/" +
         triggerId + ":fire");
    const inputs = triggerCreation.inputs;

    // Extract input values configured by the user.
    const projectId = inputs["projectId"].stringValues[0];

    // Tip: In Apps Script, use PropertiesService to persist triggerId and notifyUri:
    // const props = PropertiesService.getUserProperties();
    // props.setProperty("notifyUri", notifyUri);
    // props.setProperty("triggerId", triggerId);
    //
    // TODO: Save triggerId, notifyUri, and projectId in your database/service.
    // Your backend service listens for events related to 'projectId'
    // and calls notifyUri when those events occur.
    console.log("Trigger subscription created: " + triggerId +
                ", Notify URI: " + notifyUri +
                ", Match Project: " + projectId);

  } else if (triggerDeletion) {
    const triggerId = triggerDeletion.triggerId;

    // In Apps Script, clean up stored properties:
    // PropertiesService.getUserProperties().deleteProperty("notifyUri");
    // PropertiesService.getUserProperties().deleteProperty("triggerId");
    //
    // TODO: Remove references to triggerId from your database and stop
    // sending future event notifications to the associated notifyUri.
    console.log("Trigger subscription deleted: " + triggerId);
  }
}

/**
 * Mock function showing how your backend service fires the trigger.
 * This logic runs on your service when a watched event occurs.
 *
 * @param {string} notifyUri The stored notifyUri associated with the trigger.
 * @param {string} triggerId The stored triggerId.
 * @param {string} [userAccessToken] The OAuth 2.0 access token for the user.
 *     In Apps Script, defaults to ScriptApp.getOAuthToken().
 */
function simulateEventFire(notifyUri, triggerId, userAccessToken) {
  // In Apps Script, obtain the OAuth token using ScriptApp.getOAuthToken().
  const token = userAccessToken || ScriptApp.getOAuthToken();
  // A unique UUID version 4 is recommended as the requestId for idempotency.
  const requestId = Utilities.getUuid();

  const payload = {
    "name": "triggers/" + triggerId,
    "outputs": {
      "eventName": { "stringValues": ["EventOccurred"] },
      "eventMessage": { "stringValues": ["Hello from the service!"] }
    },
    "requestId": requestId
  };

  const options = {
    "method": "POST",
    "contentType": "application/json",
    "headers": {
      "Authorization": "Bearer " + token
    },
    "payload": JSON.stringify(payload),
    "muteHttpExceptions": true
  };

  const response = UrlFetchApp.fetch(notifyUri, options);
  const responseCode = response.getResponseCode();

  if (responseCode === 200) {
    console.log("Trigger successfully fired!");
  } else if (responseCode === 404) {
    // 404 means the trigger registration is invalid or deleted.
    console.log("Trigger not found. Stop sending events for this trigger.");
    // TODO: Clean up the trigger from your backend database.
  } else if (responseCode === 429 || responseCode >= 500) {
    console.log("Temporary error (" + responseCode + "). Retry using exponential backoff.");
  } else {
    console.log("Failed to fire trigger. HTTP Code: " + responseCode + " - " + response.getContentText());
  }
}

Utiliser l'API Workspace Studio

Vous pouvez utiliser l'API Workspace Studio (workspacestudio.googleapis.com) pour envoyer une notification programmatique à Google concernant les événements de déclencheur.

Les points de terminaison se trouvent sous le chemin de base : https://workspacestudio.googleapis.com/v1.

Envoie une notification concernant un événement de déclencheur

Déclenche un déclencheur à l'aide de la triggers.fire méthode pour lancer l'exécution d'un flux.

  • Méthode HTTP : POST
  • Chemin: /v1/triggers/{triggerId}:fire (où {triggerId} est l'identifiant unique récupéré lors de la création de l'abonnement au déclencheur)
  • Champ d'application OAuth : https://www.googleapis.com/auth/workspace.studio.trigger

L'exemple de code suivant montre comment déclencher un déclencheur dans la requête.

Demande

{
  "name": "triggers/TRIGGER_ID",
  "outputs": {
    "eventName": {
      "stringValues": [
        "EventOccurred"
      ]
    },
    "eventMessage": {
      "stringValues": [
        "Hello from the service!"
      ]
    }
  },
  "log": {
    "textFormatElements": [
      {
        "text": "An event occurred in the app."
      }
    ]
  },
  "requestId": "UNIQUE_REQUEST_ID"
}
  • name (chaîne, obligatoire) : nom de ressource du déclencheur, au format triggers/{triggerId}.
  • outputs (mappage, facultatif) : mappage des variables de sortie du déclencheur représentant les données d'événement. Chaque valeur est un objet VariableData compatible avec les listes typées (par exemple, stringValues, booleanValues, integerValues).
  • log (objet, facultatif) : représentation de balisage TextFormat affichée dans les journaux d'activité d'exécution de Workspace Studio.
  • requestId (chaîne, facultatif) : identifiant unique (UUID v4 recommandé) comportant jusqu'à 36 caractères ASCII pour garantir l'idempotence de l'API lors des nouvelles tentatives.

Réponse

En cas de réussite, la réponse renvoie un objet JSON vide {}.

Quotas de l'API Workspace Studio

Le trafic envoyé au service workspacestudio.googleapis.com est limité pour éviter la surcharge du système, encourager une utilisation équitable des ressources et protéger les performances globales de Google Workspace.

Les quotas suivants sont appliqués :

Type de quota Quota
Par minute et par projet 1 000 requêtes de déclencheur
Par minute et par utilisateur 100 requêtes de déclencheur

Les types de quotas sont les suivants :

  • Par minute et par projet : limite le nombre cumulé d'événements de déclencheur déclenchés à partir d'un seul projet Google Cloud de développeur à 1 000 requêtes par minute pour tous les utilisateurs exécutant ses déclencheurs.
  • Par minute et par utilisateur : limite le nombre cumulé d'invocations de déclencheur d'un seul utilisateur final dans un projet Cloud donné à 100 requêtes par minute.

Gérer les erreurs de quota basées sur le temps

Si vous dépassez ces quotas, l'API renvoie un code d'erreur HTTP 429 Too Many Requests (ou 429 Resource Exhausted) indiquant que le quota de débit a été dépassé.

Pour résoudre ces erreurs, votre code doit intercepter l'exception et utiliser une stratégie d'intervalle exponentiel entre les tentatives tronqué. L'intervalle exponentiel entre les tentatives relance les requêtes ayant échoué en utilisant des délais de plus en plus longs entre les tentatives, y compris une gigue aléatoire (recalcul d'un délai aléatoire à chaque itération) pour empêcher plusieurs clients de se synchroniser et de réessayer en même temps :

  1. Envoyez une requête à l'API Workspace Studio.
  2. Si la requête échoue avec une erreur 429, attendez 1 second + random_number_milliseconds, puis réessayez.
  3. Si l'opération échoue à nouveau, attendez 2 seconds + random_number_milliseconds, puis réessayez.
  4. Si l'opération échoue à nouveau, attendez 4 seconds + random_number_milliseconds, puis réessayez.
  5. Continuez cette boucle, en doublant le délai jusqu'à un seuil maximum_backoff (généralement 32 ou 64 secondes).
  6. Une fois que vous avez atteint la durée maximale de l'intervalle entre les tentatives, réessayez en utilisant ce délai constant jusqu'à ce que la limite maximale de nouvelles tentatives soit atteinte, puis arrêtez et enregistrez l'erreur.

Bonnes pratiques

Lorsque vous concevez et implémentez un déclencheur, tenez compte des bonnes pratiques suivantes :

Émettre des événements uniques au lieu de listes par lot

Concevez votre déclencheur pour qu'il émette un événement individuel pour chaque occurrence distincte (par exemple, un seul enregistrement mis à jour, un nouveau message publié ou une tâche attribuée) plutôt que d'émettre un seul événement contenant un lot ou une liste d'éléments :

  • Cohérence avec les déclencheurs intégrés : dans Workspace Studio, les déclencheurs Google Workspace intégrés (par exemple, la réception d'un e-mail dans Gmail ou l'ajout d'un utilisateur à un espace dans Google Chat) se déclenchent sur un seul événement. L'émission d'événements à un seul élément s'aligne sur ce comportement et offre une expérience cohérente et prévisible pour les utilisateurs sur tous les déclencheurs.
  • Configuration de flux plus simple : les étapes en aval d'un flux traitent généralement un élément à la fois. L'émission d'événements à un seul élément permet aux utilisateurs de mapper directement des variables sans ajouter d'étapes complexes pour itérer sur des tableaux ou analyser des listes.
  • Gérer individuellement les modifications par lot et l'interrogation : si votre service backend interroge une API externe et détecte plusieurs éléments modifiés au cours d'un seul intervalle d'interrogation, déclenchez un événement de déclencheur individuel pour chaque élément au lieu de les regrouper dans un seul événement par lot.
  • Gérer le débit et les quotas d'événements : étant donné que le déclenchement d'événements individuels pour plusieurs éléments modifiés peut entraîner un pic soudain de requêtes, assurez-vous que votre service respecte les quotas de l'API Workspace Studio (par exemple, la limite de 100 requêtes par minute et par utilisateur). Si un cycle d'interrogation génère un grand nombre d'éléments (par exemple, plus de 100 enregistrements modifiés), espacez ou limitez les envois d'événements au fil du temps pour éviter les erreurs 429 Too Many Requests.

Comportements principaux et cas particuliers

Lors de l'intégration de déclencheurs, les développeurs doivent gérer des comportements d'erreur et des fonctionnalités d'exécution spécifiques :

  • Aucune prise en charge des tests : Workspace Studio ne prend pas en charge les tests pour les déclencheurs.
  • Idempotence et prévention de la relecture : bien que cela ne soit pas strictement obligatoire, vous devez inclure un requestId unique (tel qu'un UUID) dans votre charge utile HTTP ou Apps Script. Fournir un requestId garantit l'idempotence en permettant à l'API de détecter et d'ignorer les notifications en double, ce qui empêche le flux de s'exécuter plusieurs fois pour un seul événement.
  • Flux désactivés et réactivés : lorsqu'un flux contenant votre déclencheur est désactivé dans Workspace Studio, Google envoie un événement de cycle de vie triggerDeletion à votre rappel onManageFunction. De plus, tous les appels à la méthode FireTrigger associée renvoient un 404 Not Found code d'erreur (Requested entity was not found.). Votre service doit réagir aux erreurs 404 en arrêtant les futures notifications d'événements pour cet ID d'instance de déclencheur.

    Si un utilisateur réactive ultérieurement le flux, Google lance un nouveau cycle de vie d'abonnement en appelant votre rappel onManageFunction avec un nouvel événement triggerCreation contenant un nouveau triggerId et notifyUri. Le triggerId précédent est définitivement mis hors service et n'est pas réactivé. Votre service ne doit donc pas interroger ni vérifier si une ancienne instance de déclencheur a été réactivée. Pour en savoir plus, consultez Gérer le cycle de vie de l'abonnement au déclencheur.

  • Suppression idempotente de l'abonnement : votre onManageFunction fonction de rappel doit gérer les requêtes de suppression de déclencheur de Google de manière idempotente. Si Google appelle plusieurs fois le hook de suppression pour le même triggerId (par exemple, lors de nouvelles tentatives en raison de pertes de connexion temporaires), la fonction doit renvoyer une réponse positive.

  • Quotas de flux : au-delà des quotas de l'API Workspace Studio, les flux utilisateur sont soumis à des contrôles de quota internes supplémentaires. Les boucles à haute fréquence ou le volume excessif d'événements peuvent dépasser les seuils de sécurité, ce qui entraîne la désactivation automatique du flux.

  • Autorisation refusée (403) lors du déclenchement du déclencheur : si les appels au point de terminaison triggers.fire renvoient 403 PERMISSION_DENIED avec un état d'erreur SERVICE_DISABLED, vérifiez les points suivants :

    • L'API Google Workspace Studio est activée dans votre projet Google Cloud.
    • Si vous utilisez Google Apps Script, votre projet est associé à un projet Cloud standard plutôt qu'au projet Cloud Apps Script par défaut.
    • Le jeton d'accès OAuth inclut le champ d'application https://www.googleapis.com/auth/workspace.studio.trigger.