Pausar e retomar um fluxo de trabalho usando callbacks e as Planilhas Google


O Planilhas Google é uma solução de planilhas baseada na nuvem que oferece suporte à colaboração em tempo real e ferramentas para visualizar, processar e comunicar dados.

Este tutorial demonstra como criar e implantar um fluxo de trabalho que cria um endpoint de callback (ou webhook), salva o URL do callback no Planilhas Google, pausa a execução e aguarda a aprovação humana pela planilha de planilhas para reiniciar o fluxo de trabalho. Saiba mais sobre o uso de callbacks.

Objetivos

Com este tutorial, você vai:

  1. Crie uma nova pasta no Google Drive. Essa pasta é usada para armazenar sua planilha e permite que o fluxo de trabalho grave nela.
  2. Crie uma planilha do Google Sheets para capturar uma aprovação e iniciar um callback para um fluxo de trabalho.
  3. Use o Google Apps Script, uma plataforma JavaScript baseada na nuvem que permite criar, ler e editar produtos do Google Workspace de forma programática. Ele pode ser usado para retomar um fluxo de trabalho pausado sempre que uma solicitação for aprovada por uma atualização na planilha.
  4. Crie e implante um fluxo de trabalho que chame o conector da API Google Sheets para anexar dados à planilha. O fluxo de trabalho é executado, pausado e retomado quando um callback é aprovado pela planilha. Saiba mais sobre os conectores do Workflows.
  5. Teste todo o processo e confirme se o fluxo de trabalho continua conforme o esperado.

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

O tutorial também usa o Google Workspace. Os serviços empresariais que não estão incluídos nos apps gratuitos do Google para consumidores são faturáveis.

Antes de começar

É possível executar alguns dos comandos a seguir no console do Google Cloud ou usando a Google Cloud CLI no terminal ou no Cloud Shell.

As restrições de segurança definidas pela sua organização podem impedir que você conclua as etapas a seguir. Para informações sobre solução de problemas, consulte Desenvolver aplicativos em um ambiente restrito do Google Cloud.

Console

  1. No Console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  2. Verifique se a cobrança está ativada para o seu projeto do Google Cloud. Saiba como verificar se o faturamento está ativado em um projeto.

  3. Ative as APIs Compute Engine, Sheets e Workflows.

    Ative as APIs

  4. Anote a conta de serviço padrão do Compute Engine, porque você vai associá-la ao fluxo de trabalho neste tutorial para fins de teste. Os novos projetos que ativaram a API Compute Engine têm essa conta de serviço criada com a função básica de editor do IAM e com o seguinte formato de e-mail:

    PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Encontre o número do projeto na página Welcome do console do Google Cloud.

    Para ambientes de produção, recomendamos criar uma nova conta de serviço e conceder a ela um ou mais papéis do IAM que contenham as permissões mínimas necessárias e sigam o princípio de privilégio mínimo.

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. Verifique se a cobrança está ativada para o seu projeto do Google Cloud. Saiba como verificar se o faturamento está ativado em um projeto.

  3. Ative as APIs Compute Engine, Sheets e Workflows.

    gcloud services enable \
        compute.googleapis.com \
        sheets.googleapis.com \
        workflows.googleapis.com
  4. Anote a conta de serviço padrão do Compute Engine, porque você vai associá-la ao fluxo de trabalho neste tutorial para fins de teste. Os novos projetos que ativaram a API Compute Engine têm essa conta de serviço criada com a função básica de editor do IAM e com o seguinte formato de e-mail:

    PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Para recuperar o número do projeto:

    gcloud projects describe PROJECT_ID

    Para ambientes de produção, recomendamos criar uma nova conta de serviço e conceder a ela um ou mais papéis do IAM que contenham as permissões mínimas necessárias e sigam o princípio de privilégio mínimo.

Criar uma nova pasta no Google Drive

Crie uma nova pasta no Google Drive. Essa pasta é usada para armazenar a planilha. Ao configurar uma permissão para a pasta compartilhada, seu fluxo de trabalho pode gravar na planilha.

  1. Acesse drive.google.com.
  2. Clique em Novo > Nova pasta.
  3. Digite um nome para a pasta.
  4. Clique em Criar.
  5. Clique com o botão direito do mouse na nova pasta e selecione Compartilhar.
  6. Adicione o endereço de e-mail da conta de serviço padrão do Compute Engine.

    Isso dá à conta de serviço acesso à pasta. Quando você associa a conta de serviço ao seu fluxo de trabalho, ele tem acesso de edição a qualquer arquivo na pasta. Saiba mais sobre o compartilhamento de arquivos, pastas e drives.

  7. Selecione o papel Editor.

  8. Desmarque a caixa de seleção Notificar pessoas.

  9. Clique em Compartilhar.

Criar uma planilha usando as Planilhas Google

Quando você cria uma planilha nas Planilhas Google, ela é salva no Google Drive. Por padrão, a planilha é salva na sua pasta raiz no Drive. Não é possível criar uma planilha diretamente em uma pasta especificada usando a API Google Sheets. No entanto, há alternativas, incluindo mover a planilha para uma pasta específica após criá-la, como é feito neste exemplo. Para mais informações, consulte Trabalhar com pastas do Google Drive.

  1. Acesse sheets.google.com.

  2. Clique em Novo Mais.

    Uma planilha será criada e aberta. Cada planilha tem um valor spreadsheetId exclusivo, que contém letras, números, hifens ou sublinhados. Você pode encontrar o ID da planilha em um URL do app Planilhas Google:

    https://docs.google.com/spreadsheets/d/spreadsheetId/edit#gid=0

  3. Anote esse ID, porque ele será necessário ao criar seu fluxo de trabalho.

  4. Adicione cabeçalhos de colunas para corresponder ao exemplo abaixo:

    Exemplo de planilha para registrar aprovações

    O valor na coluna G, Aprovado?, é usado para iniciar callbacks no fluxo de trabalho.

  5. Mova a planilha para a pasta do Google Drive que você criou antes:

    1. Na planilha, selecione Arquivo > Mover.
    2. Acesse a pasta que você criou.
    3. Clique em Mover.

Também é possível usar o conector da API Google Sheets para criar uma planilha. Ao usar o conector, o spreadsheetId pode ser recuperado do resultado resp. Exemplo:

- create_spreadsheet:
    call: googleapis.sheets.v4.spreadsheets.create
    args:
      body:
      connector_params:
        scopes: ${driveScope}
    result: resp
- assign_sheet_id:
    assign:
      - sheetId: ${resp.spreadsheetId}

Estender as Planilhas Google usando o Apps Script

Com o Apps Script, você pode criar, ler e editar planilhas Google de maneira programática. A maioria dos scripts criados para as Planilhas manipula matrizes para interagir com as células, linhas e colunas em uma planilha. Para uma introdução ao uso do Apps Script com as Planilhas Google, consulte o Guia de início rápido da função personalizada.

  1. Crie um projeto do Apps Script nas Planilhas Google:

    1. Abra a planilha do Planilhas Google.
    2. Selecione Extensões > Apps Script.
    3. No editor de script, clique em Projeto sem título.
    4. Dê um nome ao projeto e clique em Renomear.

    Agora, seu script está vinculado à planilha, o que dá a ele habilidades especiais para alterar a interface do usuário ou responder quando a planilha é aberta.

    Um projeto de script representa uma coleção de arquivos e recursos do Apps Script. Os arquivos de código em um projeto de script têm uma extensão .gs.

  2. Você pode usar o Apps Script para escrever funções personalizadas que podem ser usadas no Google Planilhas, assim como uma função integrada. As funções personalizadas são criadas usando o JavaScript padrão. Crie uma função:

    1. Abra seu projeto do Apps Script.
    2. Clique em Editor .
    3. Um arquivo de script aparece como um arquivo de projeto com o nome Code.gs. Para editar o arquivo, selecione-o.
    4. Substitua qualquer código no editor de script pelo código abaixo, que lê os dados na planilha e os transmite como entrada para uma execução de fluxo de trabalho:

      function handleEdit(e) {
        var range = e.range.getA1Notation();
        var sheet = e.source;
      
        if (range.length > 1 && range[0] === 'G') {
          if (e.value == "TRUE") {
            Logger.log("Approved: TRUE");
      
            var row = range.slice(1);
            var url = sheet.getRange('E' + row).getCell(1, 1).getValue();
            var approver = sheet.getRange('F' + row).getCell(1, 1).getValue();
      
            callback(url, approver);
          }
          else {
            Logger.log("Approved: FALSE");
          }
        }
      }
      
      function callback(url, approver) {
        const headers = {
          "Authorization": "Bearer " + ScriptApp.getOAuthToken()
        };
      
        var payload = {
          'approver': approver
        };
      
        const params = {
          "method": 'POST',
          "contentType": 'application/json',
          "headers": headers,
          "payload": JSON.stringify(payload)
        };
      
      
        Logger.log("Workflow callback request to " + url);
        var response = UrlFetchApp.fetch(url, params);
        Logger.log(response);
      }
    5. Clique em Salvar .

  3. Os gatilhos instaláveis do Apps Script permitem que um projeto de script execute uma função especificada quando determinadas condições são atendidas, como quando uma planilha é aberta ou editada. Crie um acionador:

    1. Abra seu projeto do Apps Script.
    2. Clique em Acionadores .
    3. Clique em Adicionar acionador.
    4. Na caixa de diálogo Adicionar gatilho para YOUR_PROJECT_NAME, configure o gatilho:
      1. Na lista Escolher a função a ser executada, selecione handleEdit.
      2. Na lista Escolher qual implantação será executada, selecione Cabeça.
      3. Na lista Selecionar origem de eventos, selecione Em uma planilha.
      4. Na lista Selecionar tipo de evento, selecione Na edição.
      5. Na lista Configurações de notificação de falha, selecione Notificar diariamente.
    5. Clique em Salvar.
    6. Se você receber uma solicitação para escolher uma Conta do Google, selecione a conta adequada e clique em Permitir.

      Isso permite que seu projeto do Apps Script acesse, edite, crie e exclua suas planilhas do Google Sheets e se conecte a um serviço externo.

  4. Um arquivo de manifesto do projeto do Apps Script é um arquivo JSON que especifica informações básicas do projeto que o Apps Script precisa para executar um script. O editor do Apps Script oculta arquivos de manifesto por padrão para proteger as configurações do projeto. Edite o arquivo de manifesto:

    1. Abra seu projeto do Apps Script.
    2. Clique em Configurações do projeto .
    3. Selecione a caixa de seleção Mostrar arquivo de manifesto "appsscript.json" no editor.
    4. Clique em Editor .
    5. O arquivo de manifesto aparece como um arquivo de projeto chamado appsscript.json. Para editar o arquivo, selecione-o.
    6. O campo oauthScopes especifica uma matriz de strings. Para definir os escopos de autorização usados pelo projeto, adicione uma matriz com os escopos que você quer oferecer suporte. Exemplo:

      {
        "timeZone": "America/Toronto",
        "dependencies": {
        },
        "exceptionLogging": "STACKDRIVER",
        "runtimeVersion": "V8",
        "oauthScopes": [
          "https://www.googleapis.com/auth/script.external_request",
          "https://www.googleapis.com/auth/cloud-platform",
          "https://www.googleapis.com/auth/spreadsheets"
        ]
      }

      Isso define os escopos explícitos para:

      • Conectar a um serviço externo
      • Acessar, editar, configurar e excluir seus dados do Google Cloud e conferir o endereço de e-mail da sua Conta do Google
      • Ver, editar, criar e excluir todas as suas planilhas do Planilhas Google
    7. Clique em Salvar .

Implantar um fluxo de trabalho que grava em uma planilha e usa callbacks

Implante um fluxo de trabalho que é executado, pausado e retomado quando um callback é aprovado em uma planilha. O fluxo de trabalho é gravado em uma planilha do Sheets usando o conector da API Sheets.

Console

  1. No console do Google Cloud, acesse a página Fluxos de trabalho:

    Acessar fluxos de trabalho

  2. Clique em Criar.

  3. Insira um nome para o novo fluxo de trabalho: workflows-awaits-callback-sheets.

  4. Na lista Região, selecione us-central1 (Iowa).

  5. Na Conta de serviço, selecione a conta de serviço padrão do Compute Engine (PROJECT_NUMBER-compute@developer.gserviceaccount.com).

  6. Clique em Próxima.

  7. No editor de fluxo de trabalho, insira a seguinte definição:

    main:
      steps:
        - init:
            assign:
            # Replace with your sheetId and make sure the service account
            # for the workflow has write permissions to the sheet
            - sheetId: "10hieAH6b-oMeIVT_AerSLNxQck14IGhgi8ign-x2x8g"
        - before_sheets_callback:
            call: sys.log
            args:
              severity: INFO
              data: ${"Execute steps here before waiting for callback from sheets"}
        - wait_for_sheets_callback:
            call: await_callback_sheets
            args:
              sheetId: ${sheetId}
            result: await_callback_result
        - after_sheets_callback:
            call: sys.log
            args:
              severity: INFO
              data: ${"Execute steps here after receiving callback from sheets"}
        - returnResult:
            return: ${await_callback_result}
    
    await_callback_sheets:
        params: [sheetId]
        steps:
            - init:
                assign:
                  - project_id: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
                  - location: ${sys.get_env("GOOGLE_CLOUD_LOCATION")}
                  - workflow_id: ${sys.get_env("GOOGLE_CLOUD_WORKFLOW_ID")}
                  - execution_id: ${sys.get_env("GOOGLE_CLOUD_WORKFLOW_EXECUTION_ID")}
            - create_callback:
                call: events.create_callback_endpoint
                args:
                  http_callback_method: POST
                result: callback_details
            - save_callback_to_sheets:
                call: googleapis.sheets.v4.spreadsheets.values.append
                args:
                    range: ${"Sheet1!A1:G1"}
                    spreadsheetId: ${sheetId}
                    valueInputOption: RAW
                    body:
                        majorDimension: "ROWS"
                        values:
                          - ["${project_id}", "${location}", "${workflow_id}", "${execution_id}", "${callback_details.url}", "", "FALSE"]
            - log_and_await_callback:
                try:
                  steps:
                    - log_await_start:
                        call: sys.log
                        args:
                          severity: INFO
                          data: ${"Started waiting for callback from sheet " + sheetId}
                    - await_callback:
                        call: events.await_callback
                        args:
                          callback: ${callback_details}
                          timeout: 3600
                        result: callback_request
                    - log_await_stop:
                        call: sys.log
                        args:
                          severity: INFO
                          data: ${"Stopped waiting for callback from sheet " + sheetId}
                except:
                    as: e
                    steps:
                        - log_error:
                            call: sys.log
                            args:
                                severity: "ERROR"
                                text: ${"Received error " + e.message}
            - check_null_await_result:
                switch:
                  - condition: ${callback_request == null}
                    return: null
            - log_await_result:
                call: sys.log
                args:
                  severity: INFO
                  data: ${"Approved by " + callback_request.http_request.body.approver}
            - return_await_result:
                return: ${callback_request.http_request.body}
  8. Substitua o valor do marcador de posição sheetId pelo spreadsheetId.

  9. Clique em Implantar.

gcloud

  1. Crie um arquivo de código-fonte para seu fluxo de trabalho:

    touch workflows-awaits-callback-sheets.yaml
  2. Em um editor de texto, copie o seguinte fluxo de trabalho para o arquivo de código-fonte:

    main:
      steps:
        - init:
            assign:
            # Replace with your sheetId and make sure the service account
            # for the workflow has write permissions to the sheet
            - sheetId: "10hieAH6b-oMeIVT_AerSLNxQck14IGhgi8ign-x2x8g"
        - before_sheets_callback:
            call: sys.log
            args:
              severity: INFO
              data: ${"Execute steps here before waiting for callback from sheets"}
        - wait_for_sheets_callback:
            call: await_callback_sheets
            args:
              sheetId: ${sheetId}
            result: await_callback_result
        - after_sheets_callback:
            call: sys.log
            args:
              severity: INFO
              data: ${"Execute steps here after receiving callback from sheets"}
        - returnResult:
            return: ${await_callback_result}
    
    await_callback_sheets:
        params: [sheetId]
        steps:
            - init:
                assign:
                  - project_id: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
                  - location: ${sys.get_env("GOOGLE_CLOUD_LOCATION")}
                  - workflow_id: ${sys.get_env("GOOGLE_CLOUD_WORKFLOW_ID")}
                  - execution_id: ${sys.get_env("GOOGLE_CLOUD_WORKFLOW_EXECUTION_ID")}
            - create_callback:
                call: events.create_callback_endpoint
                args:
                  http_callback_method: POST
                result: callback_details
            - save_callback_to_sheets:
                call: googleapis.sheets.v4.spreadsheets.values.append
                args:
                    range: ${"Sheet1!A1:G1"}
                    spreadsheetId: ${sheetId}
                    valueInputOption: RAW
                    body:
                        majorDimension: "ROWS"
                        values:
                          - ["${project_id}", "${location}", "${workflow_id}", "${execution_id}", "${callback_details.url}", "", "FALSE"]
            - log_and_await_callback:
                try:
                  steps:
                    - log_await_start:
                        call: sys.log
                        args:
                          severity: INFO
                          data: ${"Started waiting for callback from sheet " + sheetId}
                    - await_callback:
                        call: events.await_callback
                        args:
                          callback: ${callback_details}
                          timeout: 3600
                        result: callback_request
                    - log_await_stop:
                        call: sys.log
                        args:
                          severity: INFO
                          data: ${"Stopped waiting for callback from sheet " + sheetId}
                except:
                    as: e
                    steps:
                        - log_error:
                            call: sys.log
                            args:
                                severity: "ERROR"
                                text: ${"Received error " + e.message}
            - check_null_await_result:
                switch:
                  - condition: ${callback_request == null}
                    return: null
            - log_await_result:
                call: sys.log
                args:
                  severity: INFO
                  data: ${"Approved by " + callback_request.http_request.body.approver}
            - return_await_result:
                return: ${callback_request.http_request.body}
  3. Substitua o valor do marcador de posição sheetId pelo spreadsheetId.

  4. Implante o fluxo de trabalho digitando o seguinte comando:

    gcloud workflows deploy workflows-awaits-callback-sheets \
        --source=workflows-awaits-callback-sheets.yaml \
        --location=us-central1 \
        --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Substitua PROJECT_NUMBER pelo número do projeto do Google Cloud. Para recuperar o número do projeto:

    gcloud projects describe PROJECT_ID

Testar o fluxo completo

Execute o fluxo de trabalho para testar o fluxo completo. Quando um fluxo de trabalho é executado, a definição atual associada a ele também é.

Console

  1. No console do Google Cloud, acesse a página Fluxos de trabalho:

    Acessar fluxos de trabalho

  2. Na página Fluxos de trabalho, selecione o fluxo de trabalho workflows-awaits-callback-sheets para acessar a página de detalhes dele.

  3. Na página Detalhes do fluxo de trabalho, clique em Executar.

  4. Clique em Executar novamente.

    O fluxo de trabalho é iniciado e o estado de execução dele é Running. Os registros também indicam que o fluxo de trabalho está pausado e aguardando:

    Execute steps here before waiting for callback from sheets
    ...
    Started waiting for callback from sheet 1JlNFFnqs760M_KDqeeeDc_qtrABZDxoalyCmRE39dpM
  5. Verifique se o fluxo de trabalho gravou os detalhes do callback em uma linha da planilha.

    Por exemplo, você vai encontrar o ID de execução do fluxo de trabalho na coluna ID de execução, um endpoint de callback na coluna URL do callback e FALSO na coluna Aprovado?.

  6. Na planilha, mude FALSE para TRUE.

    Após um ou dois minutos, a execução será retomada e concluída com um estado de execução de Concluído.

gcloud

  1. Abra um terminal.

  2. Execute o fluxo de trabalho:

      gcloud workflows run workflows-awaits-callback-sheets

    O fluxo de trabalho é iniciado, e a saída precisa indicar que ele está pausado e em espera:

      Waiting for execution [a8361789-90e0-467f-8bd7-ea1c81977820] to complete...working.

  3. Verifique se o fluxo de trabalho gravou os detalhes do callback em uma linha da planilha.

    Por exemplo, você vai encontrar o ID de execução do fluxo de trabalho na coluna ID de execução, um endpoint de callback na coluna URL do callback e FALSO na coluna Aprovado?.

  4. Na planilha, mude FALSE para TRUE.

    Depois de um ou dois minutos, a execução será retomada e concluída com um estado de execução de SUCCEEDED.

Limpar

Se você criou um novo projeto para este tutorial, exclua o projeto. Se você usou um projeto atual e quer mantê-lo sem as alterações incluídas neste tutorial, exclua os recursos criados para o tutorial.

Exclua o projeto

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para o tutorial.

Para excluir o projeto:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Excluir os recursos criados neste tutorial

  1. Excluir arquivos no Google Drive.
  2. Excluir um fluxo de trabalho.

A seguir