Crea un comando iniziale

Questo documento spiega come creare un comando iniziale che consenta alla tua app o al tuo servizio di inviare una notifica a Google Workspace Studio quando si verifica un evento e di avviare l'esecuzione di un flusso. Nell'API, i comandi iniziali sono chiamati workflowTriggers.

Un comando iniziale avvia un flusso, mentre un passaggio è una singola attività nella sequenza di attività che comprende un flusso. Creando un comando iniziale, gli utenti possono configurare flussi automatici che reagiscono agli eventi in tempo reale della tua app o del tuo servizio.

La creazione di un comando iniziale prevede la dichiarazione del comando iniziale nel file manifest del componente aggiuntivo e l'implementazione dei callback del ciclo di vita in Google Apps Script oppure l'attivazione del comando iniziale pubblicando i payload nell'endpoint dell'API Google Workspace Studio.

Prerequisiti

  • Un Account Google con accesso a Workspace Studio.
  • Un progetto Google Cloud.

Abilita l'API

Nel progetto Google Cloud, abilita l'API Google Workspace Studio:

Abilita l'API

Passa a un progetto Google Cloud standard (solo Google Apps Script)

Per impostazione predefinita, i progetti Apps Script utilizzano un progetto Cloud predefinito che non supporta l'abilitazione delle API o la configurazione delle schermate per il consenso OAuth. Se stai creando il comando iniziale con Apps Script, devi passare a un progetto Google Cloud standard:

  1. Nell'editor di Apps Script, fai clic su Impostazioni progetto .
  2. In Progetto Google Cloud Platform (GCP), fai clic su Cambia progetto.
  3. Inserisci il numero del progetto Cloud standard e fai clic su Imposta progetto.
  4. Dopo aver cambiato progetto, autorizza di nuovo lo script eseguendo una funzione nell'editor e concedendo le autorizzazioni richieste.

Per saperne di più, vedi Passare a un progetto cloud standard di Google.

Configura la schermata per il consenso OAuth

Per comunicare con l'endpoint dell'API Workspace Studio, la tua app o il tuo servizio deve eseguire l'autenticazione utilizzando OAuth 2.0. Configura la schermata per il consenso OAuth del progetto e aggiungi il seguente ambito OAuth dedicato:

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

Questo ambito autorizza l'app a chiamare l'API Workspace Studio e ad attivare i flussi che l'utente ha configurato per questo comando iniziale.

Per maggiori informazioni, vedi Configurare la schermata per il consenso OAuth e scegliere gli ambiti.

Accesso offline e token di aggiornamento

Poiché i comandi iniziali inviano una notifica a Workspace Studio in modo asincrono quando si verifica un evento nel servizio esterno, che potrebbe verificarsi ore, giorni o mesi dopo che un utente ha configurato un flusso, il tuo servizio deve fornire un token di accesso OAuth 2.0 valido quando chiama l'endpoint dell'API.

Il token di accesso fornito da Google nell'oggetto evento del componente aggiuntivo (ad esempio durante la configurazione del comando iniziale o le richieste di callback del ciclo di vita) è di breve durata e valido solo per 1 ora. Non è sufficiente per attivare gli eventi del comando iniziale in modo asincrono in futuro. Per chiamare l'API Workspace Studio nel tempo, il tuo servizio richiede un token di aggiornamento offline per generare token di accesso nuovi su richiesta.

La modalità di gestione dell'autorizzazione e di ottenimento di un token di aggiornamento dipende dal runtime del componente aggiuntivo:

  • Componenti aggiuntivi HTTP (runtime alternativi): per i componenti aggiuntivi HTTP, il servizio di backend deve implementare un flusso di autorizzazione OAuth 2.0 separato e indipendente dall'autorizzazione integrata del componente aggiuntivo per richiedere l'accesso offline (access_type=offline) e ricevere un token di aggiornamento.

    Puoi chiedere agli utenti di autorizzare questa connessione visualizzando una scheda di accesso o di autorizzazione quando l'utente configura il comando iniziale in Workspace Studio. Per saperne di più sulla restituzione delle schede di autorizzazione e sulla gestione del flusso OAuth, vedi Collegare il componente aggiuntivo di Google Workspace a un servizio di terze parti (trattando Google Workspace come il servizio di terze parti a cui ti connetti).

    Il servizio di backend deve archiviare il token di aggiornamento in modo sicuro (ad esempio, nel database del servizio insieme a triggerId) e utilizzarlo per recuperare un nuovo token di accesso ogni volta che si verifica un evento prima di inviare richieste all'endpoint API notifyUri o triggers.fire del comando iniziale.

  • Componenti aggiuntivi di Google Apps Script: i componenti aggiuntivi basati su Google Apps Script che utilizzano trigger pianificati (basati sul tempo) per eseguire il polling degli eventi possono saltare l'implementazione di un flusso OAuth indipendente. Poiché i trigger pianificati vengono eseguiti direttamente nell'ambiente di runtime di Google Apps Script, Google Apps Script gestisce e aggiorna automaticamente i token OAuth utilizzando gli ambiti dichiarati nel manifest. Puoi recuperare un token di accesso OAuth utilizzando ScriptApp.getOAuthToken().

Definisci il comando iniziale nel file manifest

Per definire un comando iniziale, aggiungilo al file manifest del componente aggiuntivo (appsscript.json) all'interno del blocco addOns.studio.flows.workflowElements. Questa configurazione è obbligatoria sia per i runtime Apps Script sia per i runtime HTTP (runtime alternativi). Configura l'elemento come workflowTrigger anziché come workflowAction (utilizzato per definire un passaggio). Per maggiori informazioni, vedi Struttura del manifest per i componenti aggiuntivi di Google Workspace.

All'interno del blocco workflowTrigger, specifica:

  • inputs: variabili che l'utente configura nella scheda di configurazione (ad esempio nome del progetto, filtro delle risorse e così via).
  • outputs: variabili restituibili dal comando iniziale ai passaggi successivi del flusso.
  • onConfigFunction: il nome della funzione di callback che visualizza l'interfaccia di configurazione utente.
  • onManageFunction: il nome della funzione di callback richiamata da Google per gestire la creazione e l'eliminazione dell'abbonamento al comando iniziale.

Il seguente esempio di codice mostra una definizione di manifest di esempio per un comando iniziale di evento:

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

Gestisci il ciclo di vita dell'abbonamento al comando iniziale

Quando un utente configura e attiva un flusso contenente il comando iniziale oppure se il flusso viene disattivato o eliminato, Google chiama il componente aggiuntivo utilizzando la funzione di callback onManageFunction dichiarata nel manifest.

L'oggetto evento del ciclo di vita

La funzione di callback riceve un WorkflowEventObject contenente il contesto dell'azione. Per i comandi iniziali, sono inclusi:

  • Creazione del trigger (event.workflow.triggerCreation): si attiva quando il flusso viene pubblicato o attivato.

    • triggerId: una stringa UUID univoca che identifica questa istanza di registrazione del comando iniziale.

    • notifyUri: l'URL dell'endpoint API REST univoco associato a questa registrazione del comando iniziale (ad esempio, https://workspacestudio.googleapis.com/v1/triggers/YOUR_TRIGGER_ID:fire). Se notifyUri viene omesso dal payload dell'evento, costruisci l'URL dell'endpoint direttamente utilizzando triggerId: https://workspacestudio.googleapis.com/v1/triggers/{triggerId}:fire.

    • inputs: gli input delle variabili configurati dall'utente dalla scheda.

  • Eliminazione del trigger (event.workflow.triggerDeletion): si attiva quando il comando iniziale viene rimosso dal flusso oppure quando l'intero flusso viene disattivato o eliminato.

    • triggerId: la stringa UUID univoca dell'istanza dell'abbonamento da pulire.

Ciclo di vita dell'abbonamento ai runtime alternativi (API HTTP)

Per i componenti aggiuntivi creati utilizzando runtime alternativi, le notifiche del ciclo di vita dell'abbonamento vengono inviate utilizzando le richieste POST HTTP all'URL dell'endpoint HTTP configurato del componente aggiuntivo con il nome dell'azione specificato dalla funzione di callback onManageFunction. Il payload corrisponde alla rappresentazione JSON di WorkflowEventObject.

Per saperne di più sui runtime alternativi, vedi Creare un componente aggiuntivo di Google Workspace utilizzando endpoint HTTP.

Implementa i callback del ciclo di vita in Apps Script

Il seguente esempio di Apps Script mostra come configurare la scheda dell'interfaccia utente, gestire gli eventi del ciclo di vita dell'abbonamento utilizzando onManageTrigger e inviare la richiesta del comando iniziale a Google quando si verifica un evento.

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());
  }
}

Utilizza l'API Workspace Studio

Puoi utilizzare l'API Workspace Studio (workspacestudio.googleapis.com) per inviare una notifica a Google in modo programmatico degli eventi del comando iniziale.

Gli endpoint si trovano nel percorso di base: https://workspacestudio.googleapis.com/v1.

Invia una notifica di un evento del comando iniziale

Attiva un comando iniziale utilizzando il triggers.fire metodo per avviare l'esecuzione di un flusso.

  • Metodo HTTP: POST
  • Percorso: /v1/triggers/{triggerId}:fire (dove {triggerId} è l'identificatore univoco recuperato durante la creazione dell'abbonamento al trigger)
  • Ambito OAuth: https://www.googleapis.com/auth/workspace.studio.trigger

Il seguente esempio di codice mostra come attivare un comando iniziale nella richiesta.

Richiesta

{
  "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 (stringa, obbligatoria): il nome risorsa del comando iniziale, nel formato triggers/{triggerId}.
  • outputs (mappa, facoltativa): una mappa delle variabili di output del comando iniziale che rappresentano i dati sugli eventi. Ogni valore è un oggetto VariableData che supporta elenchi tipizzati (ad esempio, stringValues, booleanValues, integerValues).
  • log (oggetto, facoltativo): una rappresentazione di markup TextFormat mostrata nei log delle attività di esecuzione di Workspace Studio.
  • requestId (stringa, facoltativa): un identificatore univoco (consigliato UUID v4) di massimo 36 caratteri ASCII per garantire l'idempotenza dell'API nei nuovi tentativi.

Risposta

La risposta restituisce un oggetto JSON vuoto {} in caso di esito positivo.

Quote dell'API Workspace Studio

Il traffico inviato al servizio workspacestudio.googleapis.com è limitato per evitare il sovraccarico del sistema, incoraggiare un utilizzo equo delle risorse e proteggere le prestazioni complessive di Google Workspace.

Vengono applicate le seguenti quote:

Tipo di quota Quota
Al minuto per progetto 1000 richieste di comandi iniziali
Al minuto per utente 100 richieste di comandi iniziali

I tipi di quota sono:

  • Al minuto per progetto: limita il numero cumulativo di eventi di comandi iniziali attivati da un singolo progetto Google Cloud dello sviluppatore a 1000 richieste al minuto per tutti gli utenti che eseguono i relativi comandi iniziali.
  • Al minuto per utente: limita le chiamate cumulative di comandi iniziali di un singolo utente finale in un determinato progetto Cloud a 100 richieste al minuto.

Gestisci gli errori di quota basati sul tempo

Se superi queste quote, l'API restituisce un codice di errore HTTP 429 Too Many Requests (o 429 Resource Exhausted) che indica che la quota di frequenza è stata superata.

Per risolvere questi errori, il codice deve rilevare l'eccezione e utilizzare una strategia di backoff esponenziale troncata. I nuovi tentativi di backoff esponenziale delle richieste non riuscite utilizzano ritardi progressivamente più lunghi tra i tentativi, incluso il jitter randomizzato (ricalcolo di un ritardo randomizzato a ogni iterazione) per impedire a più client di sincronizzarsi e riprovare contemporaneamente:

  1. Invia una richiesta all'API Workspace Studio.
  2. Se la richiesta non riesce con un errore 429, attendi 1 second + random_number_milliseconds e riprova.
  3. Se non riesce di nuovo, attendi 2 seconds + random_number_milliseconds e riprova.
  4. Se non riesce di nuovo, attendi 4 seconds + random_number_milliseconds e riprova.
  5. Continua questo loop, raddoppiando il ritardo fino a una soglia maximum_backoff (in genere 32 o 64 secondi).
  6. Una volta raggiunta la durata massima del backoff, riprova utilizzando questo ritardo costante fino a raggiungere il limite massimo di nuovi tentativi, quindi interrompi e registra l'errore.

Best practice

Quando progetti e implementi un comando iniziale, tieni presente le seguenti best practice:

Emetti singoli eventi anziché elenchi batch

Progetta il comando iniziale in modo che emetta un singolo evento per ogni occorrenza distinta (ad esempio, un singolo record aggiornato, un nuovo messaggio pubblicato o un'attività assegnata) anziché emettere un singolo evento contenente un batch o un elenco di elementi:

  • Coerenza con i comandi iniziali integrati: in Workspace Studio, i comandi iniziali di Google Workspace integrati (ad esempio, la ricezione di un'email in Gmail o l'aggiunta di un utente a uno spazio in Google Chat) si attivano su un singolo evento. L'emissione di eventi a singolo elemento è in linea con questo comportamento e offre un'esperienza coerente e prevedibile per gli utenti in tutti i comandi iniziali.
  • Configurazione del flusso più semplice: i passaggi successivi di un flusso in genere elaborano un elemento alla volta. L'emissione di eventi a singolo elemento consente agli utenti di mappare le variabili direttamente senza aggiungere passaggi complessi per scorrere gli array o analizzare gli elenchi.
  • Gestisci singolarmente il polling e le modifiche batch: se il servizio di backend esegue il polling di un'API esterna e rileva più elementi modificati durante un singolo intervallo di polling, attiva un singolo evento di comando iniziale per ogni elemento modificato anziché raggrupparli in un unico evento batch.
  • Gestisci la frequenza degli eventi e le quote: poiché l'attivazione di singoli eventi per più elementi modificati può causare un'improvvisa raffica di richieste, assicurati che il tuo servizio rispetti le quote dell'API Workspace Studio (ad esempio, il limite di 100 richieste al minuto per utente). Se un ciclo di polling genera un volume elevato di elementi (ad esempio, più di 100 record modificati), distribuisci o limita gli invii di eventi nel tempo per evitare errori 429 Too Many Requests.

Comportamenti principali e casi limite

Quando integrano i comandi iniziali, gli sviluppatori devono gestire comportamenti di errore e funzionalità di runtime specifici:

  • Nessun supporto per l'esecuzione di test: Workspace Studio non supporta l'esecuzione di test per i comandi iniziali.
  • Idempotenza e prevenzione della riproduzione: anche se non è strettamente necessario, devi includere un requestId univoco (ad esempio un UUID) nel payload HTTP o Apps Script. Fornire un requestId garantisce l'idempotenza consentendo all'API di rilevare e ignorare le notifiche duplicate, impedendo l'esecuzione del flusso più volte per un singolo evento.
  • Flussi disattivati e riattivati: quando un flusso contenente il comando iniziale viene disattivato in Workspace Studio, Google invia un triggerDeletion evento del ciclo di vita al callback onManageFunction. In oltre, tutte le chiamate al metodo FireTrigger associato restituiscono un 404 Not Found codice di errore (Requested entity was not found.). Il tuo servizio deve reagire agli errori 404 interrompendo le future consegne di notifiche di eventi per l'ID dell'istanza del comando iniziale.

    Se un utente riattiva il flusso in un secondo momento, Google avvia un nuovo ciclo di vita dell'abbonamento richiamando il callback onManageFunction con un nuovo evento triggerCreation contenente un nuovo triggerId e notifyUri. Il triggerId precedente viene ritirato in modo permanente e non viene riattivato, pertanto il tuo servizio non deve eseguire il polling o verificare se una vecchia istanza del trigger è stata riattivata. Per maggiori informazioni, vedi Gestisci il ciclo di vita dell'abbonamento al comando iniziale.

  • Eliminazione idempotente dell'abbonamento: la onManageFunction funzione di callback deve gestire le richieste di eliminazione del comando iniziale da Google in modo idempotente. Se Google chiama più volte l'hook di eliminazione per lo stesso triggerId (ad esempio, durante i nuovi tentativi a causa di perdite di connessione temporanee), la funzione deve essere restituita correttamente.

  • Quote dei flussi: oltre alle quote dell'API Workspace Studio, i flussi utente sono soggetti a controlli di quota interni aggiuntivi. I loop ad alta frequenza o un volume eccessivo di eventi potrebbero superare le soglie di sicurezza, con conseguente disattivazione automatica del flusso.

  • Autorizzazione negata (403) per l'attivazione del trigger: se le chiamate all' triggers.fire endpoint restituiscono 403 PERMISSION_DENIED con uno stato di errore SERVICE_DISABLED, verifica che:

    • L'API Google Workspace Studio sia abilitata nel progetto Google Cloud.
    • Se utilizzi Google Apps Script, il progetto è collegato a un progetto Cloud standard anziché al progetto Cloud Apps Script predefinito.
    • Il token di accesso OAuth include l'ambito https://www.googleapis.com/auth/workspace.studio.trigger.