En este documento, se explica cómo compilar un activador que permita que tu app o servicio notifique a Google Workspace Studio cuando ocurre un evento y que inicie una ejecución de flujo. En la API, los iniciadores se denominan workflowTriggers.
Un activador inicia un flujo, mientras que un paso es una sola tarea en la secuencia de tareas que abarca un flujo. Cuando compilas un iniciador, permites que los usuarios configuren flujos automatizados que reaccionan a eventos en tiempo real de tu app o servicio.
Para compilar un iniciador, debes declararlo en el archivo de manifiesto del complemento y, luego, implementar devoluciones de llamada del ciclo de vida en Google Apps Script o activar el iniciador publicando cargas útiles en el endpoint de API de Google Workspace Studio.
Requisitos previos y autorización de OAuth
Para comunicarse con el extremo de la API de Workspace Studio, tu app o servicio debe autenticarse con OAuth 2.0. Durante la autorización, la app debe solicitar a los usuarios el siguiente permiso de OAuth dedicado:
https://www.googleapis.com/auth/workspace.studio.trigger
Este alcance autoriza a la app a llamar a la API de Workspace Studio y a activar los flujos que el usuario configuró para ese iniciador.
Acceso sin conexión y tokens de actualización
Dado que los activadores notifican a Workspace Studio de forma asíncrona cuando se produce un evento en el servicio externo (lo que puede ocurrir horas, días o meses después de que un usuario configura un flujo), tu servicio debe proporcionar un token de acceso de OAuth 2.0 válido cuando llame al extremo de la API.
El token de acceso que proporciona Google en el objeto de evento del complemento (por ejemplo, durante la configuración inicial o las solicitudes de devolución de llamada del ciclo de vida) tiene una duración corta y solo es válido por 1 hora. No es suficiente para activar eventos de inicio de forma asíncrona en el futuro. Para llamar a la API de Workspace Studio con el tiempo, tu servicio requiere un token de actualización sin conexión para generar tokens de acceso nuevos a pedido.
La forma en que controlas la autorización y obtienes un token de actualización depende del entorno de ejecución del complemento:
Complementos HTTP (tiempos de ejecución alternativos): En el caso de los complementos HTTP, tu servicio de backend debe implementar un flujo de autorización de OAuth 2.0 independiente de la autorización integrada del complemento para solicitar acceso sin conexión (
access_type=offline) y recibir un token de actualización.Puedes solicitar a los usuarios que autoricen esta conexión mostrando una tarjeta de acceso o autorización cuando configuren el iniciador en Workspace Studio. Para obtener más información sobre cómo devolver tarjetas de autorización y controlar el flujo de OAuth, consulta Conecta tu complemento de Google Workspace a un servicio de terceros (tratando a Google Workspace como el servicio de terceros al que te conectas).
Tu servicio de backend debe almacenar el token de actualización de forma segura (por ejemplo, en la base de datos de tu servicio junto con
triggerId) y usarlo para recuperar un token de acceso nuevo cada vez que ocurra un evento antes de enviar solicitudes alnotifyUridel activador o al endpoint de API detriggers.fire.Complementos de Google Apps Script: Los complementos basados en Google Apps Script que usan activadores programados (controlados por tiempo) para sondear eventos pueden omitir la implementación de un flujo de OAuth independiente. Dado que los activadores programados se ejecutan directamente en el entorno de ejecución de Google Apps Script, Google Apps Script administra y actualiza automáticamente los tokens de OAuth con los permisos declarados en el manifiesto.
Cómo definir el starter en el archivo de manifiesto
Para definir un iniciador, agrégalo a tu archivo de manifiesto del complemento (appsscript.json) dentro del bloque addOns.studio.flows.workflowElements. Esta configuración es obligatoria para los tiempos de ejecución de Apps Script y HTTP (tiempos de ejecución alternativos). Configura el elemento como un workflowTrigger en lugar de un workflowAction (que se usa cuando se define un paso). Para obtener más información, consulta Estructura del manifiesto de los complementos de Google Workspace.
Dentro del bloque workflowTrigger, especifica lo siguiente:
inputs: Son las variables que el usuario configura en la tarjeta de configuración (como el nombre del proyecto, el filtro de recursos, etcétera).outputs: Son las variables que puede devolver el iniciador a los pasos posteriores del flujo.onConfigFunction: Es el nombre de la función de devolución de llamada que muestra la interfaz de configuración del usuario.onManageFunction: Es el nombre de la función de devolución de llamada que invoca Google para controlar la creación y eliminación de suscripciones de inicio.
En la siguiente muestra de código, se muestra un ejemplo de definición de manifiesto para un activador de eventos:
JSON
{
"timeZone": "America/Los_Angeles",
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"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"
}
}
]
}
}
}
}
Cómo controlar el ciclo de vida de la suscripción de nivel básico
Cuando un usuario configura y habilita un flujo que contiene tu starter, o si el flujo está inhabilitado o borrado, Google llama a tu complemento con la función de devolución de llamada onManageFunction declarada en el manifiesto.
Objeto de evento de ciclo de vida
La función de devolución de llamada recibe un WorkflowEventObject que contiene el contexto de la acción. Para empezar, esto incluye lo siguiente:
Creación del activador (
event.workflow.triggerCreation): Se activa cuando se publica o habilita el flujo.triggerId: Es una cadena de UUID única que identifica esta instancia de registro de inicio.notifyUri: Es la URL única del extremo de la API de REST asociada con este registro inicial (por ejemplo,https://workspacestudio.googleapis.com/v1/triggers/YOUR_TRIGGER_ID:fire).inputs: Son las entradas de variables que el usuario configuró desde la tarjeta.
Trigger Deletion (
event.workflow.triggerDeletion): Se activa cuando se quita el iniciador del flujo o cuando se inhabilita o borra todo el flujo.triggerId: Es la cadena UUID única de la instancia de suscripción que se debe limpiar.
Ciclo de vida de la suscripción a Alternate Runtimes (API de HTTP)
En el caso de los complementos creados con tiempos de ejecución alternativos, las notificaciones del ciclo de vida de la suscripción se entregan con solicitudes HTTP POST a la URL del extremo HTTP configurado del complemento con el nombre de acción especificado por la función de devolución de llamada onManageFunction. La carga útil coincide con la representación JSON de WorkflowEventObject.
Para obtener más información sobre los tiempos de ejecución alternativos, consulta Crea un complemento de Google Workspace con endpoints HTTP.
Implementa devoluciones de llamada de ciclo de vida en Apps Script
En el siguiente ejemplo de Apps Script, se muestra cómo configurar la tarjeta de la interfaz de usuario, controlar los eventos del ciclo de vida de la suscripción con onManageTrigger y activar la solicitud de inicio a Google cuando se produce 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;
const notifyUri = triggerCreation.notifyUri;
const inputs = triggerCreation.inputs;
// Extract input values configured by the user.
const projectId = inputs["projectId"].stringValues[0];
// 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;
// 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
* (obtained using your stored refresh token).
*/
function simulateEventFire(notifyUri, triggerId, userAccessToken) {
// 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 " + userAccessToken
},
"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());
}
}
Usa la API de Workspace Studio
Puedes usar la API de Workspace Studio (workspacestudio.googleapis.com) para notificar a Google de forma programática sobre los eventos de inicio.
Los endpoints se encuentran en la ruta base:
https://workspacestudio.googleapis.com/v1.
Notifica un evento de inicio
Activa un iniciador con el método triggers.fire para iniciar la ejecución de un flujo.
- Método HTTP:
POST - Ruta de acceso:
/v1/triggers/{triggerId}:fire(donde{triggerId}es el identificador único recuperado durante la creación de la suscripción al activador) - Alcance de OAuth:
https://www.googleapis.com/auth/workspace.studio.trigger
En la siguiente muestra de código, se muestra cómo activar un iniciador en la solicitud.
Solicitud
{
"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(cadena, obligatorio): Es el nombre del recurso del iniciador, con el formatotriggers/{triggerId}.outputs(mapa, opcional): Es un mapa de las variables de salida del activador que representan los datos del evento. Cada valor es un objetoVariableDataque admite listas escritas (comostringValues,booleanValuesyintegerValues).log(objeto, opcional): Es una representación de marcadoTextFormatque se muestra en los registros de actividad de ejecución de Workspace Studio.requestId(cadena, opcional): Es un identificador único (se recomienda UUID v4) de hasta 36 caracteres ASCII para garantizar la idempotencia de la API en los reintentos.
Respuesta
Si la respuesta es exitosa, se muestra un objeto JSON vacío {}.
Cuotas de la API de Workspace Studio
El tráfico que se envía al servicio de workspacestudio.googleapis.com está restringido para evitar la sobrecarga del sistema, fomentar el uso legítimo de los recursos y proteger el rendimiento general de Google Workspace.
Se aplican las siguientes cuotas:
| Tipo de cuota | Cuota |
|---|---|
| Por minuto y por proyecto | 1,000 solicitudes de inicio |
| Por minuto, por usuario | 100 solicitudes iniciales |
Los tipos de cuotas son los siguientes:
- Por minuto y por proyecto: Limita la cantidad acumulativa de eventos de inicio activados desde el proyecto de Google Cloud de un solo desarrollador a 1,000 solicitudes por minuto en todos los usuarios que ejecutan sus iniciadores.
- Por minuto y por usuario: Limita las invocaciones acumulativas de inicio de cualquier usuario final en un proyecto de Cloud determinado a 100 solicitudes por minuto.
Cómo controlar errores de cuota basados en el tiempo
Si excedes estas cuotas, la API devolverá un código de error HTTP 429 Too Many Requests (o 429 Resource Exhausted) que indica que se excedió la cuota de frecuencia.
Para resolver estos errores, tu código debe detectar la excepción y usar una estrategia de retirada exponencial truncada. La retirada exponencial vuelve a intentar las solicitudes con errores con retrasos cada vez más largos entre los intentos, lo que incluye una fluctuación aleatoria (recalcula un retraso aleatorio en cada iteración) para evitar que varios clientes se sincronicen y vuelvan a intentar la solicitud al mismo tiempo:
- Realiza una solicitud a la API de Workspace Studio.
- Si la solicitud falla con un error
429, espera1 second + random_number_millisecondsy vuelve a intentarla. - Si vuelve a fallar, espera
2 seconds + random_number_millisecondsy vuelve a intentarlo. - Si vuelve a fallar, espera
4 seconds + random_number_millisecondsy vuelve a intentarlo. - Continúa este bucle y duplica la demora hasta alcanzar un umbral de
maximum_backoff(por lo general, 32 o 64 segundos). - Una vez que alcances la duración máxima de retirada, vuelve a intentarlo con esa demora constante hasta que se alcance el límite máximo de reintentos. Luego, detente y registra el error.
Prácticas recomendadas
Cuando diseñes e implementes un iniciador, ten en cuenta las siguientes prácticas recomendadas:
Emite eventos individuales en lugar de listas por lotes
Diseña tu activador para que emita un evento individual por cada ocurrencia distinta (como un solo registro actualizado, un mensaje nuevo publicado o una tarea asignada) en lugar de emitir un solo evento que contenga un lote o una lista de elementos:
- Coherencia con los iniciadores integrados: En Workspace Studio, los iniciadores integrados de Google Workspace (como recibir un correo electrónico en Gmail o que un usuario se una a un espacio en Google Chat) se activan con un solo evento. Emitir eventos de un solo elemento se alinea con este comportamiento y proporciona una experiencia coherente y predecible para los usuarios en todos los iniciadores.
- Configuración de flujo más simple: Los pasos posteriores en un flujo suelen procesar un elemento a la vez. La emisión de eventos de un solo elemento permite que los usuarios asignen variables directamente sin agregar pasos complejos para iterar sobre arrays o analizar listas.
- Controla los cambios de sondeo y por lotes de forma individual: Si tu servicio de backend sondea una API externa y detecta varios elementos modificados durante un solo intervalo de sondeo, activa un evento de inicio individual para cada elemento en lugar de agruparlos en un solo evento por lotes.
- Administra la tasa de eventos y las cuotas: Debido a que el envío de eventos individuales para varios elementos modificados puede provocar una ráfaga repentina de solicitudes, asegúrate de que tu servicio se mantenga dentro de las cuotas de la API de Workspace Studio (como el límite de 100 solicitudes por minuto por usuario). Si un ciclo de sondeo genera un gran volumen de elementos (por ejemplo, más de 100 registros modificados), limita o regula el envío de eventos con el tiempo para evitar errores de
429 Too Many Requests.
Comportamientos principales y casos extremos
Cuando integran starters, los desarrolladores deben controlar comportamientos de error y funciones de tiempo de ejecución específicos:
- No se admiten ejecuciones de prueba: Workspace Studio no admite ejecuciones de prueba para los activadores.
- Idempotencia y prevención de repeticiones: Si bien no es estrictamente necesario, debes incluir un
requestIdúnico (como un UUID) en tu carga útil de HTTP o Apps Script. Proporcionar unrequestIdgarantiza la idempotencia, ya que permite que la API detecte y omita las notificaciones duplicadas, lo que evita que el flujo se ejecute varias veces para un solo evento. Flujos inhabilitados y rehabilitados: Cuando se inhabilita un flujo que contiene tu activador en Workspace Studio, Google envía un evento de ciclo de vida
triggerDeletiona tu devolución de llamadaonManageFunction. Además, todas las llamadas al métodoFireTriggerasociado devuelven un código de retorno de error404 Not Found(Requested entity was not found.). Tu servicio debe reaccionar a los errores404deteniendo las entregas futuras de notificaciones de eventos para ese ID de instancia de inicio.Si el usuario vuelve a habilitar el flujo más adelante, Google iniciará un nuevo ciclo de vida de la suscripción invocando tu devolución de llamada
onManageFunctioncon un nuevo eventotriggerCreationque contiene un nuevotriggerIdynotifyUri. EltriggerIdanterior se retiró de forma permanente y no se reactivará, por lo que tu servicio no debe sondear ni verificar si se volvió a habilitar una instancia de activación anterior. Para obtener más información, consulta Cómo controlar el ciclo de vida de la suscripción de nivel básico.Eliminación idempotente de la suscripción: Tu función de devolución de llamada
onManageFunctiondebe controlar las solicitudes de eliminación de iniciadores de Google de forma idempotente. Si Google llama al gancho de eliminación varias veces para el mismotriggerId(por ejemplo, durante reintentos debido a pérdidas temporales de conexión), la función debe devolver una respuesta correcta.Cuotas de flujo: Además de las cuotas de la API de Workspace Studio, los flujos de usuarios están sujetos a controles de cuotas internos adicionales. Los bucles de alta frecuencia o el volumen excesivo de eventos pueden superar los umbrales de seguridad, lo que provoca la inhabilitación automática del flujo.
Temas relacionados
- Cómo crear un paso
- Conecta tu complemento de Google Workspace a un servicio externo
- Variables de entrada
- Variables de salida
- Registro de actividad y errores
- Cómo controlar errores
- Objetos de eventos de Workspace Studio