Pausar y reanudar un flujo de trabajo mediante retrollamadas y Hojas de cálculo de Google


Hojas de cálculo de Google es una solución de hojas de cálculo basada en la nube que admite la colaboración en tiempo real y proporciona herramientas para visualizar, procesar y comunicar datos.

En este tutorial se muestra cómo crear e implementar un flujo de trabajo que cree un endpoint de retrollamada (o webhook), guarde la URL de retrollamada en Hojas de cálculo de Google, pause la ejecución y, a continuación, espere la aprobación de un usuario a través de la hoja de cálculo para reiniciar el flujo de trabajo. Consulta más información sobre el uso de devoluciones de llamada.

Objetivos

En este tutorial, aprenderás a hacer lo siguiente:

  1. Crea una carpeta en Google Drive. Esta carpeta se usa para almacenar tu hoja de cálculo y permite que el flujo de trabajo escriba en ella.
  2. Crea una hoja de cálculo de Google para registrar una aprobación e iniciar una retrollamada a un flujo de trabajo.
  3. Usa Google Apps Script, una plataforma de JavaScript basada en la nube que te permite crear, leer y editar productos de Google Workspace de forma programática, para activar la reanudación de un flujo de trabajo pausado cada vez que se apruebe una solicitud mediante una actualización de la hoja de cálculo.
  4. Crea e implementa un flujo de trabajo que llame al conector de la API de Hojas de cálculo de Google para añadir datos a la hoja de cálculo. El flujo de trabajo se ejecuta, se pausa y, a continuación, se reanuda cuando se aprueba una retrollamada a través de la hoja de cálculo. Más información sobre los conectores de Workflows
  5. Prueba todo el proceso y confirma que el flujo de trabajo se desarrolla según lo previsto.

Costes

En este documento, se utilizan los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costes basada en el uso previsto, utiliza la calculadora de precios.

Los usuarios nuevos Google Cloud pueden disfrutar de una prueba gratuita.

En el tutorial también se usa Google Workspace. Los servicios empresariales que no se incluyen en las aplicaciones para consumidores gratuitas de Google se facturan.

Antes de empezar

Puedes ejecutar algunos de los siguientes comandos en la Google Cloud consola o mediante la CLI de Google Cloud en tu terminal o en Cloud Shell.

Es posible que las restricciones de seguridad definidas por tu organización te impidan completar los siguientes pasos. Para obtener información sobre cómo solucionar problemas, consulta el artículo Desarrollar aplicaciones en un entorno limitado Google Cloud .

Consola

  1. En la Google Cloud consola, en la página del selector de proyectos, selecciona o crea un Google Cloud proyecto.

    Ir al selector de proyectos

  2. Comprueba que la facturación esté habilitada en tu Google Cloud proyecto. Consulta cómo comprobar si la facturación está habilitada en un proyecto.

  3. Habilita las APIs Compute Engine, Hojas de cálculo y Workflows.

    Habilita las APIs

  4. Anota la cuenta de servicio predeterminada de Compute Engine, ya que la asociarás al flujo de trabajo de este tutorial para hacer pruebas. En los proyectos nuevos en los que se ha habilitado la API Compute Engine, se crea esta cuenta de servicio con el rol básico de editor de IAM y con el siguiente formato de correo:

    PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Puedes encontrar el número de tu proyecto en la página Bienvenido de la consola de Google Cloud .

    En los entornos de producción, te recomendamos que crees una cuenta de servicio y le asignes uno o varios roles de IAM que contengan los permisos mínimos necesarios y que sigas el principio de privilegio 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. Comprueba que la facturación esté habilitada en tu Google Cloud proyecto. Consulta cómo comprobar si la facturación está habilitada en un proyecto.

  3. Habilita las APIs Compute Engine, Hojas de cálculo y Workflows.

    gcloud services enable \
        compute.googleapis.com \
        sheets.googleapis.com \
        workflows.googleapis.com
  4. Anota la cuenta de servicio predeterminada de Compute Engine, ya que la asociarás al flujo de trabajo de este tutorial para hacer pruebas. En los proyectos nuevos en los que se ha habilitado la API Compute Engine, se crea esta cuenta de servicio con el rol básico de editor de IAM y con el siguiente formato de correo:

    PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Puedes obtener tu número de proyecto de las siguientes formas:

    gcloud projects describe PROJECT_ID

    En los entornos de producción, te recomendamos que crees una cuenta de servicio y le asignes uno o varios roles de IAM que contengan los permisos mínimos necesarios y que sigas el principio de privilegio mínimo.

Crear una carpeta en Google Drive

Crea una carpeta en Google Drive. Esta carpeta se usa para almacenar tu hoja de cálculo. Al configurar un permiso para la carpeta compartida, tu flujo de trabajo podrá escribir en la hoja de cálculo.

  1. Ve a drive.google.com.
  2. Haz clic en Nuevo > Nueva carpeta.
  3. Asigna un nombre a la carpeta.
  4. Haz clic en Crear.
  5. Haz clic con el botón derecho en la carpeta nueva y selecciona Compartir.
  6. Añade la dirección de correo de la cuenta de servicio predeterminada de Compute Engine.

    De esta forma, la cuenta de servicio tendrá acceso a la carpeta. Cuando asocies la cuenta de servicio a tu flujo de trabajo, este tendrá acceso de edición a cualquier archivo de la carpeta. Más información sobre cómo compartir archivos, carpetas y unidades

  7. Selecciona el rol Editor.

  8. Desmarca la casilla Notificar a los usuarios.

  9. Haz clic en Compartir.

Crear una hoja de cálculo con Hojas de cálculo de Google

Cuando creas una hoja de cálculo con Hojas de cálculo de Google, se guarda en Google Drive. De forma predeterminada, la hoja de cálculo se guarda en la carpeta raíz de Drive. No hay ninguna opción para crear una hoja de cálculo directamente en una carpeta específica mediante la API de Hojas de cálculo de Google. Sin embargo, hay otras opciones, como mover la hoja de cálculo a una carpeta específica después de crearla, como se hace en este ejemplo. Para obtener más información, consulta el artículo Trabajar con carpetas de Google Drive.

  1. Ve a sheets.google.com.

  2. Haz clic en Nuevo Plus.

    Al hacerlo, se abrirá una hoja de cálculo nueva. Cada hoja de cálculo tiene un valor spreadsheetId único que contiene letras, números, guiones o guiones bajos. Puedes encontrar el ID de hoja de cálculo en una URL de Hojas de cálculo de Google:

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

  3. Anota este ID, ya que lo necesitarás cuando crees el flujo de trabajo.

  4. Añade encabezados de columna que coincidan con el siguiente ejemplo:

    Ejemplo de hoja de cálculo para registrar aprobaciones

    Ten en cuenta que el valor de la columna G, ¿Aprobado?, se usa para iniciar devoluciones de llamada en el flujo de trabajo.

  5. Mueve la hoja de cálculo a la carpeta de Google Drive que has creado anteriormente:

    1. En la hoja de cálculo, selecciona Archivo > Mover.
    2. Ve a la carpeta que has creado.
    3. Haz clic en Mover.

También puedes usar el conector de la API de Hojas de cálculo de Google para crear una hoja de cálculo. Ten en cuenta que, al usar el conector, el spreadsheetId se puede obtener del resultado resp. Por ejemplo:

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

Ampliar Hojas de cálculo de Google con Apps Script

Apps Script te permite crear, leer y editar hojas de cálculo de Google de forma programática. La mayoría de las secuencias de comandos diseñadas para Hojas de cálculo manipulan matrices para interactuar con las celdas, las filas y las columnas de una hoja de cálculo. Para obtener una introducción al uso de Apps Script con Hojas de cálculo de Google, consulta la guía de inicio rápido de funciones personalizadas.

  1. Crea un proyecto de Apps Script desde Hojas de cálculo de Google:

    1. Abre tu hoja de cálculo de Hojas de cálculo.
    2. Selecciona Extensiones > Apps Script.
    3. En el editor de secuencias de comandos, haz clic en Proyecto sin título.
    4. Asigna un nombre al proyecto y haz clic en Cambiar nombre.

    Tu secuencia de comandos ahora está vinculada a tu hoja de cálculo, lo que le da a la secuencia de comandos capacidades especiales para modificar la interfaz de usuario o responder cuando se abre la hoja de cálculo.

    Un proyecto de secuencias de comandos representa una colección de archivos y recursos de Apps Script. Los archivos de código de un proyecto de secuencia de comandos tienen la extensión .gs.

  2. Puedes usar Apps Script para escribir funciones personalizadas que puedes usar en Hojas de cálculo de Google como si fueran funciones integradas. Las funciones personalizadas se crean con JavaScript estándar. Crea una función:

    1. Abre tu proyecto de Apps Script.
    2. Haz clic en Editor .
    3. El archivo de secuencia de comandos aparece como un archivo de proyecto llamado Code.gs. Para editar el archivo, selecciónalo.
    4. Sustituye el código del editor de secuencias de comandos por el siguiente, que lee los datos de tu hoja de cálculo y los transfiere como entrada a una ejecución de flujo de trabajo:

      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. Haz clic en Guardar .

  3. Los activadores instalables de Apps Script permiten que un proyecto de secuencia de comandos ejecute una función específica cuando se cumplan determinadas condiciones, como cuando se abra o se edite una hoja de cálculo. Crea un activador:

    1. Abre tu proyecto de Apps Script.
    2. Haga clic en Activadores .
    3. Haz clic en Añadir activador.
    4. En el cuadro de diálogo Añadir activador para YOUR_PROJECT_NAME, configura el activador:
      1. En la lista Choose which function to run (Elige qué función quieres ejecutar), selecciona handleEdit.
      2. En la lista Choose which deployment should run (Elige qué implementación se debe ejecutar), selecciona Head (Principal).
      3. En la lista Seleccionar fuente de evento, selecciona De hoja de cálculo.
      4. En la lista Select event type (Seleccionar tipo de evento), selecciona On edit (Al editar).
      5. En la lista Ajustes de notificaciones de errores, selecciona Enviarme una notificación diaria.
    5. Haz clic en Guardar.
    6. Si se te pide que elijas una cuenta de Google, selecciona la cuenta adecuada y haz clic en Permitir.

      Esto permite que tu proyecto de Apps Script vea, edite, cree y elimine tus hojas de cálculo de Google, así como que se conecte a un servicio externo.

  4. Un archivo de manifiesto de un proyecto de Apps Script es un archivo JSON que especifica información básica del proyecto que Apps Script necesita para ejecutar una secuencia de comandos correctamente. Ten en cuenta que el editor de Apps Script oculta los archivos de manifiesto de forma predeterminada para proteger los ajustes de tu proyecto de Apps Script. Edita el archivo de manifiesto:

    1. Abre tu proyecto de Apps Script.
    2. Haz clic en Configuración del proyecto .
    3. Selecciona la casilla Mostrar el archivo de manifiesto "appsscript.json" en el editor.
    4. Haz clic en Editor .
    5. El archivo de manifiesto aparece como un archivo de proyecto llamado appsscript.json. Para editar el archivo, selecciónalo.
    6. El campo oauthScopes especifica una matriz de cadenas. Para definir los ámbitos de autorización que usa tu proyecto, añade un array con los ámbitos que quieras que se admitan. Por ejemplo:

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

      De esta forma, se definen los siguientes ámbitos explícitos:

      • Permite conectarse a un servicio externo
      • Ver, editar, configurar y eliminar tus Google Cloud datos y ver la dirección de correo de tu cuenta de Google
      • Ver, editar, crear y eliminar todas tus hojas de cálculo de Hojas de cálculo de Google
    7. Haz clic en Guardar .

Desplegar un flujo de trabajo que escribe en una hoja de cálculo y usa retrollamadas

Implementa un flujo de trabajo que se ejecute, se pause y, a continuación, se reanude cuando se apruebe una retrollamada a través de una hoja de cálculo. El flujo de trabajo escribe en una hoja de cálculo de Google mediante el conector de la API de Hojas de cálculo de Google.

Consola

  1. En la Google Cloud consola, ve a la página Flujos de trabajo:

    Ve a Workflows

  2. Haz clic en Crear.

  3. Escribe un nombre para el nuevo flujo de trabajo: workflows-awaits-callback-sheets.

  4. En la lista Región, selecciona us-central1 (Iowa).

  5. En Cuenta de servicio, selecciona la cuenta de servicio predeterminada de Compute Engine (PROJECT_NUMBER-compute@developer.gserviceaccount.com).

  6. Haz clic en Siguiente.

  7. En el editor del flujo de trabajo, introduce la siguiente definición para tu flujo de trabajo:

    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. Sustituye el valor del marcador de posición sheetId por tu spreadsheetId.

  9. Haz clic en Desplegar.

gcloud

  1. Crea un archivo de código fuente para tu flujo de trabajo:

    touch workflows-awaits-callback-sheets.yaml
  2. En un editor de texto, copia el siguiente flujo de trabajo en tu archivo de código fuente:

    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. Sustituye el valor del marcador de posición sheetId por tu spreadsheetId.

  4. Para desplegar el flujo de trabajo, introduce el siguiente 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

    Sustituye PROJECT_NUMBER por el número de tu proyecto. Google Cloud Puedes obtener tu número de proyecto de las siguientes formas:

    gcloud projects describe PROJECT_ID

Probar el flujo de principio a fin

Ejecuta el flujo de trabajo para probar el flujo de principio a fin. Al ejecutar un flujo de trabajo, se ejecuta la definición del flujo de trabajo actual asociada a él.

Consola

  1. En la Google Cloud consola, ve a la página Flujos de trabajo:

    Ve a Workflows

  2. En la página Workflows (Flujos de trabajo), selecciona el flujo de trabajo workflows-awaits-callback-sheets para ir a su página de detalles.

  3. En la página Detalles del flujo de trabajo, haz clic en Ejecutar.

  4. Vuelve a hacer clic en Ejecutar.

    El flujo de trabajo se inicia y su estado de ejecución debe ser En ejecución. Los registros también indican que el flujo de trabajo está en pausa y esperando:

    Execute steps here before waiting for callback from sheets
    ...
    Started waiting for callback from sheet 1JlNFFnqs760M_KDqeeeDc_qtrABZDxoalyCmRE39dpM
  5. Comprueba que el flujo de trabajo haya escrito los detalles de la retrollamada en una fila de tu hoja de cálculo.

    Por ejemplo, deberías ver el ID de ejecución del flujo de trabajo en la columna ID de ejecución, un endpoint de retrollamada en la columna URL de retrollamada y FALSE en la columna ¿Aprobado?.

  6. En la hoja de cálculo, cambia FALSE por TRUE.

    Al cabo de un minuto o dos, la ejecución debería reanudarse y completarse con el estado Succeeded.

gcloud

  1. Abre la terminal.

  2. Ejecuta el flujo de trabajo:

      gcloud workflows run workflows-awaits-callback-sheets

    El flujo de trabajo se inicia y el resultado debe indicar que el flujo de trabajo está en pausa y esperando:

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

  3. Comprueba que el flujo de trabajo haya escrito los detalles de la retrollamada en una fila de tu hoja de cálculo.

    Por ejemplo, deberías ver el ID de ejecución del flujo de trabajo en la columna ID de ejecución, un endpoint de retrollamada en la columna URL de retrollamada y FALSE en la columna ¿Aprobado?.

  4. En la hoja de cálculo, cambia FALSE por TRUE.

    Al cabo de uno o dos minutos, la ejecución debería reanudarse y completarse con el estado SUCCEEDED.

Limpieza

Si has creado un proyecto para este tutorial, elimínalo. Si has usado un proyecto y quieres conservarlo sin los cambios que se han añadido en este tutorial, elimina los recursos creados para el tutorial.

Eliminar el proyecto

La forma más fácil de evitar que te cobren es eliminar el proyecto que has creado para el tutorial.

Para ello, sigue las instrucciones que aparecen a continuación:

  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.

Eliminar los recursos creados en este tutorial

  1. Eliminar archivos de Google Drive.
  2. Eliminar un flujo de trabajo.

Siguientes pasos