Criar um starter

Este documento explica como criar uma ativação que permite que seu app ou serviço notifique o Google Workspace Studio quando um evento ocorre e inicie uma execução de fluxo. Na API, os iniciadores são chamados de workflowTriggers.

Um gatilho inicia um fluxo, enquanto uma etapa é uma única tarefa na sequência de tarefas que compõem um fluxo. Ao criar um starter, você permite que os usuários configurem fluxos automatizados que reagem a eventos em tempo real do seu app ou serviço.

Para criar um starter, declare-o no arquivo de manifesto do complemento e implemente callbacks de ciclo de vida no Google Apps Script ou acione o starter postando payloads no endpoint da API Google Workspace Studio.

Pré-requisitos e autorização OAuth

Para se comunicar com o endpoint de API Workspace Studio, seu app ou serviço precisa fazer a autenticação usando o OAuth 2.0. O app precisa solicitar o seguinte escopo OAuth dedicado aos usuários durante a autorização:

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

Esse escopo autoriza o app a chamar a API Workspace Studio e acionar fluxos que o usuário configurou para esse início.

Acesso off-line e tokens de atualização

Como os iniciadores notificam o Workspace Studio de forma assíncrona quando um evento ocorre no serviço externo (o que pode acontecer horas, dias ou meses depois que um usuário configura um fluxo), seu serviço precisa fornecer um token de acesso OAuth 2.0 válido ao chamar o endpoint da API.

O token de acesso fornecido pelo Google no objeto de evento do complemento (como durante a configuração inicial ou solicitações de callback do ciclo de vida) é de curta duração e válido por apenas uma hora. Não é suficiente para disparar eventos de inicialização de forma assíncrona no futuro. Para chamar a API Workspace Studio ao longo do tempo, seu serviço precisa de um token de atualização off-line para gerar tokens de acesso atualizados sob demanda.

A forma como você lida com a autorização e recebe um token de atualização depende do tempo de execução do complemento:

  • Complementos HTTP (runtimes alternativos): para complementos HTTP, o serviço de back-end precisa implementar um fluxo de autorização OAuth 2.0 separado e independente da autorização de complemento integrada para solicitar acesso off-line (access_type=offline) e receber um token de atualização.

    Você pode pedir que os usuários autorizem essa conexão mostrando um cartão de login ou autorização quando o usuário configurar o starter no Workspace Studio. Para mais informações sobre como retornar cartões de autorização e processar o fluxo do OAuth, consulte Conectar o complemento do Google Workspace a um serviço de terceiros (tratando o Google Workspace como o serviço de terceiros a que você se conecta).

    Seu serviço de back-end precisa armazenar o token de atualização com segurança (por exemplo, no banco de dados do serviço ao lado do triggerId) e usá-lo para recuperar um novo token de acesso sempre que um evento ocorrer antes de enviar solicitações ao notifyUri ou ao endpoint da API triggers.fire.

  • Complementos do Google Apps Script: os complementos baseados no Google Apps Script que usam acionadores programados (acionados por tempo) para pesquisar eventos podem pular a implementação de um fluxo OAuth independente. Como os gatilhos programados são executados diretamente no ambiente de execução do Google Apps Script, ele gerencia e atualiza automaticamente os tokens OAuth usando os escopos declarados no manifesto.

Definir o iniciador no arquivo de manifesto

Para definir um ponto de partida, adicione-o ao arquivo de manifesto do complemento (appsscript.json) no bloco addOns.studio.flows.workflowElements. Essa configuração é necessária para os ambientes de execução do Apps Script e HTTP (ambientes de execução alternativos). Configure o elemento como um workflowTrigger em vez de um workflowAction (que é usado ao definir uma etapa). Para mais informações, consulte Estrutura do manifesto para complementos do Google Workspace.

No bloco workflowTrigger, especifique:

  • inputs: variáveis que o usuário configura no card de configuração (como nome do projeto, filtro de recursos etc.).
  • outputs: variáveis que podem ser retornadas pelo iniciador para etapas downstream no fluxo.
  • onConfigFunction: o nome da função de callback que mostra a interface de configuração do usuário.
  • onManageFunction: o nome da função de callback invocada pelo Google para processar a criação e exclusão de assinaturas iniciais.

A amostra de código a seguir mostra um exemplo de definição de manifesto para um iniciador 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"
            }
          }
        ]
      }
    }
  }
}

Processar o ciclo de vida da assinatura inicial

Quando um usuário configura e ativa um fluxo que contém seu starter, ou se o fluxo é desativado ou excluído, o Google chama seu complemento usando a função de callback onManageFunction declarada no manifesto.

O objeto de evento de ciclo de vida

A função de callback recebe um WorkflowEventObject que contém o contexto da ação. Para começar, isso inclui:

  • Criação de acionador (event.workflow.triggerCreation): disparado quando o fluxo é publicado ou ativado.

    • triggerId: uma string UUID exclusiva que identifica esta instância de registro inicial.

    • notifyUri: o URL exclusivo do endpoint da API REST associado a este registro inicial (por exemplo, https://workspacestudio.googleapis.com/v1/triggers/YOUR_TRIGGER_ID:fire).

    • inputs: as entradas de variáveis configuradas pelo usuário no card.

  • Exclusão do acionador (event.workflow.triggerDeletion): disparado quando o início é removido do fluxo ou quando todo o fluxo é desativado ou excluído.

    • triggerId: a string UUID exclusiva da instância de assinatura a ser limpa.

Ciclo de vida da assinatura do Alternate Runtimes (API HTTP)

Para complementos criados com runtimes alternativos, as notificações de ciclo de vida da assinatura são entregues usando solicitações HTTP POST para o URL do endpoint HTTP configurado do complemento com o nome da ação especificado pela função de callback onManageFunction. O payload corresponde à representação JSON do WorkflowEventObject.

Para mais informações sobre runtimes alternativos, consulte Criar um complemento do Google Workspace usando endpoints HTTP.

Implementar callbacks do ciclo de vida no Apps Script

O exemplo do Apps Script a seguir mostra como configurar o card da interface do usuário, processar eventos do ciclo de vida da assinatura usando onManageTrigger e acionar a solicitação inicial de volta ao Google quando um evento ocorre.

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

Usar a API Workspace Studio

Você pode usar a API Workspace Studio (workspacestudio.googleapis.com) para notificar o Google de eventos de inicialização de maneira programática.

Os endpoints ficam no caminho base: https://workspacestudio.googleapis.com/v1.

Notifica um evento inicial.

Aciona um iniciador usando o método triggers.fire para iniciar a execução de um fluxo.

  • Método HTTP: POST
  • Caminho: /v1/triggers/{triggerId}:fire (em que {triggerId} é o identificador exclusivo recuperado durante a criação da assinatura do gatilho)
  • Escopo do OAuth: https://www.googleapis.com/auth/workspace.studio.trigger

O exemplo de código a seguir mostra como acionar um iniciador na solicitação.

Solicitação

{
  "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 (string, obrigatório): o nome do recurso do iniciador, formatado como triggers/{triggerId}.
  • outputs (mapa, opcional): um mapa de variáveis de saída do ativador que representam os dados de eventos. Cada valor é um objeto VariableData que aceita listas tipadas (como stringValues, booleanValues e integerValues).
  • log (objeto, opcional): uma representação de marcação TextFormat mostrada nos registros de atividade de execução do Workspace Studio.
  • requestId (string, opcional): um identificador exclusivo (recomendado UUID v4) de até 36 caracteres ASCII para garantir a idempotência da API em novas tentativas.

Resposta

A resposta retorna um objeto JSON vazio {} em caso de sucesso.

Cotas da API Workspace Studio

O tráfego enviado ao serviço workspacestudio.googleapis.com é restrito para evitar a sobrecarga do sistema, incentivar o uso aceitável dos recursos e proteger o desempenho geral do Google Workspace.

As seguintes cotas são aplicadas:

Tipo da cota Cota
Por minuto em cada projeto 1.000 solicitações iniciais
Por minuto por usuário 100 solicitações iniciais

Os tipos de cota são:

  • Por minuto por projeto: limita o número cumulativo de eventos de inicialização acionados de um único projeto na nuvem do Google Cloud de um desenvolvedor a 1.000 solicitações por minuto em todos os usuários que executam os inicializadores.
  • Por minuto por usuário: limita a 100 solicitações por minuto as invocações cumulativas de ativação de um único usuário final em um determinado projeto na nuvem.

Processar erros de cota com base no tempo

Se você exceder essas cotas, a API vai retornar um código de erro HTTP 429 Too Many Requests (ou 429 Resource Exhausted) indicando que a cota de taxa foi excedida.

Para resolver esses erros, seu código precisa capturar a exceção e usar uma estratégia de espera exponencial truncada. A espera exponencial repete solicitações com falha usando atrasos cada vez mais longos entre as tentativas, incluindo jitter aleatório (recalculando um atraso aleatório em cada iteração) para evitar que vários clientes sincronizem e tentem novamente ao mesmo tempo:

  1. Faça uma solicitação para a API do Workspace Studio.
  2. Se a solicitação falhar com um erro 429, aguarde 1 second + random_number_milliseconds e tente de novo.
  3. Se falhar de novo, aguarde 2 seconds + random_number_milliseconds e tente outra vez.
  4. Se falhar de novo, aguarde 4 seconds + random_number_milliseconds e tente outra vez.
  5. Continue esse loop, dobrando o atraso até um limite de maximum_backoff (normalmente 32 ou 64 segundos).
  6. Quando você atingir a duração máxima de espera, tente de novo usando esse atraso constante até atingir o limite máximo de novas tentativas. Depois, pare e registre o erro.

Práticas recomendadas

Ao criar e implementar um modelo inicial, considere as seguintes práticas recomendadas:

Emitir eventos únicos em vez de listas em lote

Projete seu gatilho para emitir um evento individual para cada ocorrência distinta (como um único registro atualizado, uma nova mensagem postada ou uma tarefa atribuída) em vez de emitir um único evento contendo um lote ou uma lista de itens:

  • Consistência com os iniciadores integrados: no Workspace Studio, os iniciadores integrados do Google Workspace (como receber um e-mail no Gmail ou um usuário entrar em um espaço no Google Chat) são acionados em um único evento. A emissão de eventos de item único se alinha a esse comportamento e oferece uma experiência consistente e previsível para os usuários em todos os iniciadores.
  • Configuração de fluxo mais simples: as etapas downstream em um fluxo normalmente processam um item por vez. A emissão de eventos de item único permite que os usuários mapeiem variáveis diretamente sem adicionar etapas complexas para iterar matrizes ou analisar listas.
  • Processe as mudanças de pesquisa e em lote individualmente: se o serviço de back-end consultar uma API externa e detectar vários itens alterados durante um único intervalo de pesquisa, acione um evento inicializador individual para cada item em vez de agrupá-los em um evento em lote.
  • Gerenciar a taxa de eventos e as cotas: como o disparo de eventos individuais para vários itens alterados pode causar um aumento repentino de solicitações, verifique se o serviço está dentro das cotas da API Workspace Studio (como o limite de 100 solicitações por minuto por usuário). Se um ciclo de polling gerar um grande volume de itens (por exemplo, mais de 100 registros alterados), ajuste ou limite os envios de eventos ao longo do tempo para evitar erros 429 Too Many Requests.

Comportamentos principais e casos extremos

Ao integrar inicializadores, os desenvolvedores precisam processar comportamentos de erro específicos e recursos de tempo de execução:

  • Sem suporte para execução de testes: o Workspace Studio não oferece suporte para execução de testes para iniciantes.
  • Idempotência e prevenção de repetição: embora não seja estritamente necessário, inclua um requestId exclusivo (como um UUID) no payload HTTP ou do Apps Script. Fornecer um requestId garante a idempotência, permitindo que a API detecte e ignore notificações duplicadas, evitando que o fluxo seja executado várias vezes para um único evento.
  • Fluxos desativados e reativados: quando um fluxo que contém seu acionador é desativado no Workspace Studio, o Google envia um evento de ciclo de vida triggerDeletion ao seu callback onManageFunction. Além disso, todas as chamadas para o método FireTrigger associado retornam um código de retorno de erro 404 Not Found (Requested entity was not found.). Seu serviço precisa reagir a erros 404 interrompendo as entregas futuras de notificações de eventos para esse ID de instância inicial.

    Se um usuário reativar o fluxo mais tarde, o Google vai iniciar um novo ciclo de vida da assinatura invocando seu callback onManageFunction com um novo evento triggerCreation que contém um novo triggerId e notifyUri. O triggerId anterior é desativado permanentemente e não é reativado. Portanto, seu serviço não deve sondar nem verificar se uma instância de gatilho antiga foi reativada. Para mais informações, consulte Gerenciar o ciclo de vida da assinatura inicial.

  • Exclusão idempotente de assinaturas: sua função de callback onManageFunction precisa processar solicitações de exclusão de assinaturas iniciais do Google de maneira idempotente. Se o Google chamar o hook de exclusão várias vezes para o mesmo triggerId (por exemplo, durante novas tentativas devido a perdas temporárias de conexão), a função deverá ser retornada com sucesso.

  • Cotas de fluxo: além das cotas da API Workspace Studio, os fluxos de usuários estão sujeitos a outros controles internos de cota. Loops de alta frequência ou volume excessivo de eventos podem exceder os limites de segurança, resultando na desativação automática do fluxo.