Potencia la carpeta Recibidos de Gmail con Google Cloud Functions

1. Introducción

Miles de millones de personas y empresas usan Gmail y otros servicios de G Suite para comunicarse y procesar datos. Google ofrece G Suite APIs para ayudarte a acceder a la información de estos servicios de manera 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 RESTful de G Suite, Google Cloud Functions y otros servicios de Google Cloud Platform.

Qué compilarás

En este lab, compilarás e implementarás algunas funciones de Cloud Functions conectadas a las API de G Suite y 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
  • Extrae imágenes adjuntas a cualquier correo entrante
  • Categoriza esas imágenes con la API de Cloud Vision.
  • Escriba 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 API de RESTful de G Suite
  • Conceptos básicos de Google Cloud Functions y otros servicios de Google Cloud Platform
  • Cómo acceder a Gmail de manera 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/Node.js

2. Primero lo primero

Habilitación de las API

En este lab, utilizarás los siguientes productos y servicios de Google:

  • Google Cloud Functions
  • Google Cloud Pub/Sub
  • Google Cloud Vision API
  • 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 manera simple y escalable.

Para habilitar Google Cloud Functions, haz clic en el menú de opciones 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 esa opción. Haz clic en Habilitar API para habilitar Google Cloud Functions en tu proyecto.

Google Cloud Pub/Sub

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

Para habilitar Google Cloud Pub/Sub, abre la barra lateral de navegación izquierda, busca Pub/Sub y haz clic en esa opción. 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 escalable y distribuida.

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

98012c91fd4080d4.png

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

Google Cloud Vision

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

Consulta las instrucciones que aparecen a continuación si necesitas información para habilitar la API de Google Cloud Vision.

Habilita la API de Gmail, la API de Hojas de cálculo de Google y la API de Google Cloud Vision

Abre la barra lateral izquierda de navegación y busca APIs y Servicios Haz clic en Biblioteca. En la sección Search for APIs & Servicios, escribe Gmail. En los resultados de la búsqueda, selecciona API de Gmail y haz clic en Habilitar.

Regresa a la página Biblioteca de APIs. Busca la API de Hojas de cálculo de Google 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 nuevo panel en la parte inferior de la pantalla:

34f498402e910802.png

Haz clic en el botón Iniciar editor de código 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 en Cloud Shell el siguiente comando 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, que aparece 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:

8c5d3e43f674b33.png

  1. El usuario configura las notificaciones push de Gmail: cada vez que llegue un mensaje nuevo a la carpeta Recibidos, Gmail enviará una notificación a Cloud Pub/Sub.
  2. Cloud Pub/Sub entrega la notificación de 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 electrónico contiene una imagen como archivo adjunto, la instancia de Cloud Functions llama a la API de Cloud Vision para analizarlo.
  5. La instancia de Cloud Functions actualiza la hoja de cálculo de Google que elijas y especifica quién envía el mensaje y dónde descargar el archivo adjunto.

4. Autorizar el acceso a Gmail

Antes de configurar una Cloud Function para que lea automáticamente tus correos electrónicos, debes autorizar su acceso a Gmail. Deberás registrar un cliente de OAuth con 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 la pantalla de consentimiento de OAuth.

91b2a3bac30bb2c5.png

Escribe un nombre en el campo Application name, como GCF + Gmail Codelab. No modifiques los demás parámetros de configuración, 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 de aplicación web, asígnale un nombre (aquí puedes usar nuevamente GCF + Codelab de Gmail) y haz clic en Crear. Deja los campos de Restricciones vacíos por ahora.

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

1160d8027ea52d90.png

Realiza el proceso de autorización

En el código de muestra, auth/index.js especifica dos Cloud Functions, auth_init y auth_callback, que trabajan en conjunto para realizar el proceso de autorización mediante el ID de cliente y el secreto de 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 muestra 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 acceso específico a tus datos a cualquier persona que los posea. auth_callback los guarda en Cloud Datastore.
  • Los tokens de actualización se utilizan para obtener nuevos tokens de acceso y son considerablemente más duraderos.

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. Deja los valores de YOUR-GOOGLE-CLIENT-CALLBACK-URL y YOUR-PUBSUB-TOPIC sin cambios por ahora.

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 el permiso para instalar comandos beta.

A continuación, ve a la consola de Google Cloud 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. Vuelve 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.

807c3bd38533335.png

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

Por último, abre el menú de navegación de la izquierda y haz clic en APIs y Servicios > Verificación del 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 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 autorizado de JavaScript. Por ejemplo, si la URL se parece a

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

Debes 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. Configura 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 notificaciones push.

Para recibir notificaciones push de Gmail, debes crear un tema de Pub/Sub. Todos los suscriptores del tema recibirán notificaciones de los mensajes entrantes automáticamente a medida que lleguen desde 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. Para ello, 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 asígnale el rol 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.

Ya está todo listo para autorizar y configurar las notificaciones push de Gmail. Espera hasta que se completen los cambios nuevos. Luego, regresa 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 de tu propiedad. 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 el navegador.

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

6. Procesa los mensajes entrantes

Como mencionamos antes, cualquier suscriptor del tema de Pub/Sub que creaste recibirá notificaciones cuando lleguen mensajes nuevos a tu bandeja de entrada. pubsub/index.js especifica una Cloud Function, watchGmailMessages, que, una vez implementada como suscriptor del tema, lee 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.

Recupera mensajes

Las notificaciones push de Gmail incluyen la dirección de correo electrónico con la que está asociada la notificación y un ID del historial. Por razones de simplicidad, 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 mejores resultados, usa el ID del 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;

Analizar 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 devuelva varias etiquetas de imagen. Por ejemplo, si se proporciona con una imagen de un cielo azul, la API de Cloud Vision puede mostrar las etiquetas azul, cielo y naturaleza.

watchGmailMessages usa la biblioteca de la API de Cloud Vision para Node.js con el objetivo de 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;
};

Actualizar 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 los hubiera).

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

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 valor.

watchGmailMessages se conecta con la API de Google Sheets para adjuntar 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 valores propios. Puedes encontrar estos valores en la consola de Google Cloud: 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 Cloud Function:

cd ~

cd gcf-gmail-codelab/pubsub

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

Si nombraste gmail-watch a tu tema de Cloud Pub/Sub, 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! Eso es todo. Envíate a ti mismo un correo electrónico con una imagen adjunta. Luego de unos segundos, verás que la hoja de cálculo de Google que creaste se actualizará automáticamente con la información que proporciones.