Potencia la carpeta Recibidos de Gmail con Google Cloud Functions

1. Introducción

Miles de millones de empresas y personas usan Gmail y otros servicios de G Suite para comunicarse y procesar datos. Google ofrece APIs de G Suite para ayudarte a acceder a la información de estos servicios de forma programática, y puedes usar las APIs para automatizar fácilmente tu flujo de trabajo diario. En este lab, compilarás una potente extensión de Gmail que categoriza automáticamente los correos electrónicos en los mensajes entrantes y guarda esas categorías en una hoja de cálculo de Google. Esta extensión usará las APIs de G Suite basadas en REST, Google Cloud Functions y otros servicios de Google Cloud Platform.

Qué compilarás

En este lab, compilarás e implementarás algunas Cloud Functions conectadas a las APIs de G Suite y a otros servicios de Google Cloud Platform. Estas funciones harán lo siguiente:

  • Autoriza el acceso seguro a tus datos de Gmail y Hojas de cálculo de Google
  • Extraer imágenes adjuntas a cualquier correo entrante
  • Categoriza esas imágenes con la API de Cloud Vision
  • Escribe esas categorías, la dirección del remitente y el nombre del archivo adjunto en una hoja de cálculo de Google.

Qué aprenderás

  • Conceptos básicos de las APIs de RESTful de G Suite
  • Conceptos básicos de Cloud Functions y otros servicios de Google Cloud
  • Cómo acceder a Gmail de forma programática con Google Cloud Functions

Lo que necesitarás

  • Una Cuenta de Google con acceso a Gmail y Hojas de cálculo de Google Si no tienes una, créala aquí.
  • Conocimientos básicos de JavaScript o Node.js

2. Primero lo primero

Habilita las APIs

En este lab, usarás los siguientes productos o servicios de Google:

  • Google Cloud Functions
  • Google Cloud Pub/Sub
  • API de Google Cloud Vision
  • Google Cloud Datastore
  • API de Gmail
  • API de Google Sheets

Google Cloud Functions

Google Cloud Functions es la plataforma de funciones como servicio sin servidores de Google que te permite ejecutar fragmentos individuales de código ("funciones") de una manera sencilla y escalable.

Para habilitar Google Cloud Functions, haz clic en el menú de hamburguesa que se encuentra en la parte superior izquierda de la pantalla para abrir la barra lateral de navegación izquierda:

f457988e33594bb6.png

Busca Cloud Functions en el menú de navegación y haz clic en él. Haz clic en Habilitar API para habilitar Google Cloud Functions en tu proyecto.

Google Cloud Pub/Sub

Google Cloud Pub/Sub es una base simple y escalable para la transmisión de datos y la entrega de eventos. En este lab, actúa como el servicio de mensajería entre Gmail y Google Cloud Functions.

Para habilitar Google Cloud Pub/Sub, abre la barra de navegación lateral izquierda, busca Pub/Sub y haz clic en él. Haz clic en Habilitar API para habilitar Google Cloud Pub/Sub en tu proyecto.

Google Cloud Datastore

Google Cloud Datastore es una base de datos sin servidores que es escalable y distribuida.

Para habilitar Google Cloud Datastore, en la barra de navegación lateral izquierda, busca Datastore y haz clic en él. Haz clic en Seleccionar modo Datastore en la página nueva.

98012c91fd4080d4.png

Puedes usar cualquier ubicación de la base de datos para este lab. Haz clic en Crear base de datos para habilitar Google Cloud Datastore. Esto puede tardar unos minutos en completarse.

Google Cloud Vision

La API de Google Cloud Vision es un potente servicio de aprendizaje automático que usa modelos entrenados previamente para obtener estadísticas a partir de tus imágenes.

Consulta las instrucciones a continuación para obtener información sobre cómo habilitar la API de Google Cloud Vision.

Habilita la API de Gmail, la API de Google Sheets y la API de Google Cloud Vision

Una vez más, abre la barra lateral de navegación izquierda y busca APIs y servicios. Haz clic en Biblioteca. En el campo Buscar APIs y servicios, escribe Gmail. En los resultados de la búsqueda, selecciona API de Gmail y haz clic en Habilitar.

Vuelve a la página Biblioteca de API. Busca la API de Google Sheets y habilítala.

Repite el proceso. Busca la API de Cloud Vision y habilítala.

Abre Google Cloud Shell

En este lab, usarás Google Cloud Shell para realizar la mayoría de las operaciones. Cloud Shell te brinda acceso de línea de comandos a tus recursos de Google Cloud Platform directamente desde el navegador, lo que te permite administrarlos sin usar una máquina local.

Para abrir Google Cloud Shell, haz clic en el botón Activar Cloud Shell en la barra horizontal azul superior:

fd5c2925ca9cdfdd.png

Aparecerá un panel nuevo en la parte inferior de la pantalla:

34f498402e910802.png

Haz clic en el botón Abrir editor para iniciar el editor de código de Cloud Shell:

10f8631ef48bed22.png

El editor de código de Cloud Shell se abrirá en una ventana nueva.

Descarga el código

Ejecuta el siguiente comando en Cloud Shell para clonar el proyecto:

git clone https://github.com/googlecodelabs/gcf-gmail-codelab.git

cd gcf-gmail-codelab

Deberías ver una carpeta nueva, gcf-gmail-codelab, en el editor de código de Cloud Shell.

3. Descripción general de la arquitectura

A continuación, se muestra el flujo de trabajo de este lab:

79c5d3e43f674b33.png

  1. El usuario configura las notificaciones push de Gmail: Cada vez que llega un mensaje nuevo a la carpeta Recibidos, Gmail envía una notificación a Cloud Pub/Sub.
  2. Cloud Pub/Sub entrega la notificación del mensaje nuevo a Google Cloud Functions.
  3. Cuando llega la notificación de mensaje nuevo, una instancia de Cloud Functions se conecta a Gmail y recupera el mensaje nuevo.
  4. Si el correo tiene una imagen como adjunto, la instancia de Cloud Functions llama a la API de Cloud Vision para analizar el adjunto.
  5. La instancia de Cloud Functions actualiza una hoja de cálculo de Google de tu elección, en la que se especifica quién envía el mensaje y dónde descargar el archivo adjunto.

4. Autoriza el acceso a Gmail

Antes de configurar una Cloud Function para que lea tus correos electrónicos automáticamente, debes autorizar su acceso a Gmail. Deberás registrar un cliente de OAuth en Google y crear un ID de cliente asociado.

Registra un cliente de OAuth

En el menú de navegación de la izquierda de la consola de Google Cloud, busca APIs y servicios. Haz clic en Pantalla de consentimiento de OAuth.

91b2a3bac30bb2c5.png

Escribe un nombre en el campo Nombre de la aplicación, como GCF + Gmail Codelab. Deja los demás parámetros de configuración sin modificar, desplázate hacia abajo en la página y haz clic en Guardar.

Crea un ID de cliente asociado

Cambia a la pestaña Credenciales. Haz clic en Crear credenciales y elige ID de cliente de OAuth. Elige el tipo Aplicación web, asígnale un nombre (puedes volver a usar GCF + Gmail Codelab aquí) y haz clic en Crear. Por ahora, deja los campos de Restricciones vacíos.

Anota el ID de cliente y el secreto del cliente que se muestran en la ventana emergente. Puedes volver a hacer clic en el nombre de tu cliente en la página para ver estos valores:

1160d8027ea52d90.png

Realiza el proceso de autorización

En el código de ejemplo, auth/index.js especifica dos Cloud Functions, auth_init y auth_callback, que trabajan en conjunto para realizar el proceso de autorización con el ID de cliente y el secreto del cliente que acabas de crear.

Para inspeccionar el código, abre auth/index.js en el editor de código de Cloud Shell.

El proceso de autorización devuelve dos tipos de tokens: tokens de acceso y tokens de actualización.

  • Los tokens de acceso son pruebas de identidad de corta duración que otorgan a cualquier persona que los posea acceso con alcance a tus datos. auth_callback los guarda en Cloud Datastore.
  • Los tokens de actualización se usan para obtener tokens de acceso nuevos y tienen una vida útil mucho más larga.

Por lo general, se encriptan o se almacenan por separado de los tokens de acceso.

Edita auth/env_vars.yaml en el editor de código de Cloud Shell. Reemplaza YOUR-GOOGLE-CLIENT-ID y YOUR-GOOGLE-CLIENT-SECRET con tus valores. Consulta el paso anterior para obtener más información. Por el momento, no cambies los valores de YOUR-GOOGLE-CLIENT-CALLBACK-URL y YOUR-PUBSUB-TOPIC.

a2b4853c39a78bc6.png

Después de editar auth/env_vars.yaml, ejecuta el siguiente comando en Cloud Shell para implementar Cloud Functions:

cd ~
cd gcf-gmail-codelab/auth

# Deploy Cloud Function auth_init
gcloud functions deploy auth_init --runtime=nodejs8 --trigger-http --env-vars-file=env_vars.yaml

# Deploy Cloud Function auth_callback
gcloud functions deploy auth_callback --runtime=nodejs8 --trigger-http --env-vars-file=env_vars.yaml

La implementación de Cloud Functions puede tardar unos minutos. Si se te solicita, otorga al SDK de Cloud permiso para instalar comandos beta.

A continuación, ve a Google Cloud Console y haz clic en Cloud Functions en el menú de navegación de la izquierda. Haz clic en auth_callback en la lista de Cloud Functions y cambia a la pestaña Activador.

cb094bd341f9b299.png

45678a327c80e0f1.png

Copia la URL de la página. Regresa a la página de Cloud Functions y haz clic en auth_init en la lista de Cloud Functions. En la pestaña General, haz clic en Editar. Haz clic en Variables de entorno, redes, tiempos de espera y más y reemplaza el valor de GOOGLE_CALLBACK_URL por la URL que acabas de copiar.

939ca3bd38047282.png

Haz clic en Implementar para aplicar los cambios. Repite el proceso y actualiza auth_callback también.

Por último, abre el menú de navegación de la izquierda y haz clic en APIs y servicios > Verificación de dominio. Para agregar un dominio autorizado, haz clic en Agregar dominio. Por ejemplo, si la URL que copiaste antes se ve así:

https://us-central1-my-project.cloudfunctions.net/auth_callback

Debes agregar lo siguiente como un dominio autorizado:

us-central1-my-project.cloudfunctions.net

Presiona Agregar dominio para confirmar.

4348748f232ceb87.png

Regresa a la página Credenciales. Haz clic en el nombre de tu cliente de OAuth y agrega la URL que copiaste como un URI de redireccionamiento autorizado. Presiona Intro para confirmar.

Quita la parte /auth_callback de la URL y agrega el resto como un origen JavaScript autorizado. Por ejemplo, si tu URL se ve así:

https://us-central1-my-project.cloudfunctions.net/auth_callback

Deberías agregar lo siguiente como origen:

https://us-central1-my-project.cloudfunctions.net/

159bad719432582c.png

Presiona Intro para confirmar y haz clic en Guardar para aplicar los cambios.

5. Cómo configurar las notificaciones push de Gmail

Si el proceso de autorización se realiza correctamente, auth_callback llamará automáticamente a la API de Gmail para configurar las notificaciones push.

Para recibir notificaciones push de Gmail, debes crear un tema de Pub/Sub. Cualquier suscriptor del tema recibirá automáticamente notificaciones de los mensajes entrantes a medida que lleguen de Gmail.

Para crear un tema de Pub/Sub, ve a la consola de Google Cloud y haz clic en Pub/Sub > Temas en el menú de navegación de la izquierda. Haz clic en Crear tema. Escribe el nombre del tema, como gmail-watch, y haz clic en Crear. Además, debes otorgarle permiso a Gmail para enviar mensajes a tu tema de Pub/Sub: haz clic en el menú contextual del tema que acabas de crear (tres puntos verticales) y elige Permisos; haz clic en Agregar miembros, especifica gmail-api-push@system.gserviceaccount.com como miembro nuevo y otórgale el rol de Pub/Sub > Publicador de Pub/Sub; por último, haz clic en Guardar para aplicar los cambios.

Actualiza la Cloud Function auth_callback para especificar qué tema de Pub/Sub usar. Haz clic en Cloud Functions en el menú de navegación de la izquierda y selecciona auth_callback en la lista de Cloud Functions. En la pestaña General, haz clic en Editar. Haz clic en Más y reemplaza el valor de PUBSUB_TOPIC por el nombre del tema de Pub/Sub que acabas de crear. Haz clic en Guardar para aplicar los cambios.

Ahora puedes autorizar y configurar las notificaciones push de Gmail. Espera a que finalicen los cambios nuevos y, luego, vuelve a la página Cloud Functions, selecciona auth_init en la lista de Cloud Functions y cambia a la pestaña Activador. Haz clic en la URL y se te redireccionará a la página Acceder con Google:

348ab0a7e0c9cd03.png

Accede con una cuenta de Gmail que te pertenezca. Cualquier mensaje nuevo que llegue a la carpeta Recibidos de la cuenta activará una notificación push. Después de acceder, verás la siguiente página:

cfdad62fd02de004.png

Haz clic en Permitir para autorizar el acceso. auth_callback completará el proceso de autorización, guardará los tokens de acceso y configurará las notificaciones push de Gmail por ti. Cuando se complete este proceso, deberías ver el mensaje Successfully set up Gmail push notifications en tu navegador.

En este codelab, se usa el paquete @google-cloud/express-oauth2-handlers para automatizar el flujo de trabajo de autorización. Para obtener más información, consulta su repositorio en GitHub.

6. Procesa mensajes entrantes

Como mencionamos anteriormente, cualquier suscriptor del tema de Pub/Sub que creaste recibirá notificaciones cuando lleguen mensajes nuevos a tu carpeta Recibidos. pubsub/index.js especifica una Cloud Function, watchGmailMessages, que, una vez implementada como suscriptor del tema, leerá los mensajes nuevos, categorizará las imágenes adjuntas y exportará esas categorías a una hoja de cálculo de Google.

Para inspeccionar el código, abre pubsub/index.js en el editor de código de Cloud Shell.

Cómo recuperar mensajes

Una notificación push de Gmail incluye la dirección de correo electrónico con la que está asociada la notificación y un ID de historial. Para simplificar las cosas, en este codelab, simplemente le pedirás a la API de Gmail el mensaje más reciente cuando llegue una notificación push. Para obtener un mejor resultado, usa el ID de historial para buscar mensajes.

// Look up the most recent message.
const listMessagesRes = await gmail.users.messages.list({
  userId: email,
  maxResults: 1
});
const messageId = listMessagesRes.messages[0].id;

// Get the message using the message ID.
const message = await gmail.users.messages.get({
  userId: email,
  id: messageId
});

return message;

Analiza archivos adjuntos de imágenes

Si el mensaje tiene una imagen adjunta, watchGmailMessages llamará a la API de Cloud Vision para anotar la imagen. En este codelab, le pedirás a la API de Cloud Vision que clasifique la imagen y muestre una cantidad de etiquetas de imagen. Por ejemplo, si se le proporciona una imagen de un cielo azul, la API de Cloud Vision puede devolver las etiquetas azul, cielo y naturaleza.

watchGmailMessages usa la biblioteca de la API de Cloud Vision para Node.js para llamar a la API de Cloud Vision:

// Tag the attachment using Cloud Vision API
const analyzeAttachment = async (data, filename) => {
  var topLabels = ['', '', ''];
  if (filename.endsWith('.png') || filename.endsWith('.jpg')) {
    const [analysis] = await visionClient.labelDetection({
      image: {
        content: Buffer.from(data, 'base64')
      }
    });
    const labels = analysis.labelAnnotations;
    topLabels = labels.map(x => x.description).slice(0, 3);
  }

  return topLabels;
};

Actualiza la hoja de cálculo de Google

watchGmailMessages exporta los resultados de este análisis a una hoja de cálculo de Google. Incluye el nombre del remitente, el nombre del archivo adjunto y las etiquetas de los archivos adjuntos de imágenes (si corresponde).

Primero, crea una hoja de cálculo de Google. Abre Hojas de cálculo de Google y haz clic en la plantilla En blanco en Iniciar una nueva hoja de cálculo. Copia el ID de tu hoja. Por ejemplo, si la dirección en tu navegador se ve de la siguiente manera:

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

El ID de tu hoja de cálculo es abcdefghij01234567890. En el editor de código de Cloud Shell, actualiza gcf-gmail-codelab/pubsub/env_vars.yaml y reemplaza YOUR-GOOGLE-SHEET-ID por tu propio valor.

watchGmailMessages se conecta con la API de Google Sheets para agregar información:

const updateReferenceSheet = async (from, filename, topLabels) => {
  await googleSheets.spreadsheets.values.append({
    spreadsheetId: SHEET,
    range: SHEET_RANGE,
    valueInputOption: 'USER_ENTERED',
    requestBody: {
      range: SHEET_RANGE,
      majorDimension: 'ROWS',
      values: [
        [from, filename].concat(topLabels)
      ]
    }
  });
};

Un último paso

En el editor de código de Cloud Shell, abre gcf-gmail-codelab/pubsub/env_vars.yaml y reemplaza YOUR-GOOGLE-CLIENT-ID, YOUR-GOOGLE-CLIENT-SECRET y YOUR-GOOGLE-CALLBACK-URL por tus propios valores. Puedes encontrar estos valores en Google Cloud Console: abre Cloud Functions en el menú de navegación de la izquierda, selecciona auth_init en la lista de Cloud Functions y busca la sección Variables de entorno.

Implementa el código

Ejecuta el siguiente comando para implementar la función de Cloud Functions:

cd ~

cd gcf-gmail-codelab/pubsub

gcloud functions deploy watchGmailMessages --runtime=nodejs8 --trigger-topic=gmail-watch --env-vars-file=env_vars.yaml

Si le asignaste a tu tema de Cloud Pub/Sub un nombre diferente a gmail-watch, reemplaza gmail-watch en el comando anterior por el nombre de tu tema. La implementación de la Cloud Function puede tardar unos segundos.

7. Probar

¡Felicitaciones! Terminaste. Envía un correo electrónico a tu propia dirección con una imagen adjunta. En unos segundos, verás que la Hoja de cálculo de Google que creaste se actualiza automáticamente con la información que proporcionaste.