Configura notificaciones para servicios de terceros

Cuando tus compilaciones de Cloud Build cambian de estado, puedes enviar notificaciones sobre estos cambios a servicios de mensajería de terceros y por correo electrónico.

Los servicios como Slack ofrecen webhooks entrantes, que habilitan a los usuarios a que envíen mensajes de servicios externos a sus clientes. Cloud Functions permite que los usuarios escriban funciones programáticas de uso único que escuchan eventos de la nube, como compilaciones. Cuando se produce un evento de la nube, un activador responde mediante la ejecución de una acción, como enviar un mensaje de Cloud Pub/Sub.

Hay muchos servicios de terceros compilados con la funcionalidad de mensajería entre aplicaciones, como IFTTT y SendGrid. Puedes usar este instructivo como plantilla para conectarte con servicios como estos.

En este instructivo, se muestra cómo puedes usar Cloud Functions y Cloud Pub/Sub para enviar notificaciones sobre Cloud Build a Slack y a través de correo electrónico mediante Mailgun.

Objetivos

  • Implementa una aplicación de Slack o configura Mailgun para recibir notificaciones externas de Cloud Build.
  • Escribe una función de Cloud Functions para enviar notificaciones de Pub/Sub a Slack o Mailgun.

Costos

En este instructivo, se usan componentes facturables de Cloud Platform, incluidos los siguientes:

  • Cloud Functions
  • Cloud Pub/Sub
  • Kubernetes Engine

Usa la calculadora de precios para generar una estimación de los costos según el uso previsto.

Los usuarios nuevos de Cloud Platform pueden optar por una prueba gratuita.

Antes de comenzar

  1. Accede a tu Cuenta de Google.

    Si todavía no tienes una cuenta, regístrate para obtener una nueva.

  2. Selecciona o crea un proyecto de GCP.

    Ir a la página Administrar recursos

  3. Asegúrate de tener habilitada la facturación para tu proyecto.

    Aprende a habilitar la facturación

  4. Habilita las Cloud Functions, Cloud Pub/Sub, and Kubernetes Engine API necesarias.

    Habilita las API

  5. Realiza la instalación y la inicialización del SDK de Cloud.
  6. Actualiza y, luego, instala los componentes de gcloud:
    gcloud components update &&
    gcloud components install alpha beta

Puede que también quieras completar la guía de inicio rápido de Kubernetes Engine para familiarizarte con este producto.

Notificaciones de Slack

En las siguientes secciones, se te indicará cómo configurar notificaciones de Slack.

Prepara la aplicación de Slack

  1. Descarga Slack para tu computadora. También debes unirte a un equipo de Slack, puedes hacerlo si te registras con tu correo electrónico o usas una invitación que te envió un administrador del equipo.

  2. Accede a Slack con el nombre de tu equipo y tus credenciales de la cuenta de Slack.

  3. Para crear una app de Slack nueva, sigue estos pasos:

    1. Elige el nombre de la app y tu equipo de Slack. Haz clic en Crear.
    2. Haz clic en Webhooks entrantes.
    3. Habilita los webhooks entrantes.
    4. Haz clic en Agregar Webhook nuevo a un equipo. Se abrirá una página de autorización.
    5. En el menú desplegable, selecciona el canal al que deseas que se envíen las notificaciones.
    6. Haz clic en Autorizar.
    7. Se creó un webhook para tu aplicación de Slack. Copia el webhook y guárdalo para usarlo más tarde.

Escribe la función de Cloud Functions

Crea un depósito de Cloud Storage para habilitar a etapa tus archivos de Cloud Functions, en el que [STAGING_BUCKET_NAME] es un nombre de depósito único a nivel global (como [PROJECT-ID]_cloudbuilds):

gsutil mb gs://[STAGING_BUCKET_NAME]

Deberías ver el siguiente resultado:

Creating gs://[PROJECT-ID]_cloudbuilds/[STAGING_BUCKET_NAME]...

A continuación, crea un directorio en tu sistema local para el código de la aplicación:

Linux/macOS

mkdir ~/gcb_slack
cd ~/gcb_slack

Windows

mkdir %HOMEPATH%\gcb_slack
cd %HOMEPATH%\gcb_slack

Luego, crea los siguientes archivos en el directorio gcb_slack:

index.js

const IncomingWebhook = require('@slack/client').IncomingWebhook;
const SLACK_WEBHOOK_URL = "[SLACK_WEBHOOK]"

const webhook = new IncomingWebhook(SLACK_WEBHOOK_URL);

// subscribe is the main function called by Cloud Functions.
module.exports.subscribe = (event, callback) => {
 const build = eventToBuild(event.data.data);

// Skip if the current status is not in the status list.
// Add additional statues to list if you'd like:
// QUEUED, WORKING, SUCCESS, FAILURE,
// INTERNAL_ERROR, TIMEOUT, CANCELLED
  const status = ['SUCCESS', 'FAILURE', 'INTERNAL_ERROR', 'TIMEOUT'];
  if (status.indexOf(build.status) === -1) {
    return callback();
  }

  // Send message to Slack.
  const message = createSlackMessage(build);
  webhook.send(message, callback);
};

// eventToBuild transforms pubsub event message to a build object.
const eventToBuild = (data) => {
  return JSON.parse(new Buffer(data, 'base64').toString());
}

// createSlackMessage create a message from a build object.
const createSlackMessage = (build) => {
  let message = {
   text: `Build \`${build.id}\``,
    mrkdwn: true,
    attachments: [
      {
        title: 'Build logs',
        title_link: build.logUrl,
        fields: [{
          title: 'Status',
          value: build.status
        }]
      }
    ]
  };
  return message
}

[SLACK-WEBHOOK] es el webhook entrante de tu app de Slack.

Este programa usa el webhook de Slack para escuchar y recibir mensajes de Cloud Functions. Cuando se activa un evento, se envía un mensaje al webhook y, luego, se transmite a Slack.

La función createSlackMessage se simplificó para este ejemplo. Puedes expandir el mensaje para que incluye mucho más, como los colores del texto, las imágenes y la duración de la compilación.

package.json

{
  "name": "google-container-slack",
  "version": "0.0.1",
  "description": "Slack integration for Google Cloud Build, using Google Cloud Functions",
  "main": "index.js",
  "dependencies": {
    "@slack/client": "3.9.0"
  }
}

package.json describe lo siguiente:

  • el nombre, la versión y la descripción del programa
  • sus archivos de entorno de ejecución principales
  • sus dependencias

Este archivo parece simple: puedes agregar más dependencias, requisitos y otra información según sea necesario.

Ahora, deberías tener index.js y package.json en el directorio gcb_slack.

Implementa la función de Cloud Functions

Para implementar la función subscribe con un activador de Cloud Pub/Sub, ejecuta el siguiente comando en el directorio gcb_slack:

gcloud functions deploy subscribe --stage-bucket [STAGING_BUCKET_NAME] --trigger-topic cloud-builds

en el que [STAGING_BUCKET_NAME] es el nombre de tu depósito de etapa de pruebas de Cloud Storage, como [PROJECT-ID]_cloudbuilds.

Deberías ver un resultado similar al que se detalla a continuación:

Copying file:///var/folders/../.../fun.zip [Content-Type=application/zip]...
/ [1 files][  1.5 KiB/  1.5 KiB]
Operation completed over 1 objects/1.5 KiB.
Waiting for operation to finish...done.
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
entryPoint: subscribe
eventTrigger:
  eventType: providers/cloud.pubsub/eventTypes/topic.publish
  resource: projects/[PROJECT-ID]/topics/cloud-builds
latestOperation: operations/...
name: projects/[PROJECT-ID]/locations/us-central1/functions/subscribe
status: READY
timeout: 60s

Una vez que se completa la implementación de la función de Cloud Functions, cuando se produce un evento de compilación, recibes una notificación de Slack.

Notificaciones por correo electrónico

En las secciones siguientes, se te indicará cómo configurar notificaciones por correo electrónico con la API de Mailgun.

Si recién comienzas a usar Mailgun, consulta su documentación de inicio rápido.

Prepara la configuración de Mailgun

  1. Si aún no lo hiciste, crea una cuenta de Mailgun.
  2. Agrega un dominio nuevo y, luego, sigue las instrucciones de Mailgun para verificar tu dominio. Esto puede tardar hasta 48 horas.
  3. En la página de dominios, haz clic en tu dominio para abrir la página de configuración.
  4. En la página de configuración de tu dominio, copia la clave de API del dominio y guárdala para usarla más tarde.

También debes tener lo siguiente:

  • Una dirección de correo electrónico para enviar correos electrónicos. Esta dirección de correo electrónico puede pertenecer al dominio que proporciones. Si no estás seguro de qué dirección de correo electrónico debes usar, consulta con tu proveedor de dominio. También puedes proporcionar un correo electrónico inexistente si no esperas una respuesta del destinatario, como noreply@mydomain.com.
  • Una dirección de correo electrónico para recibir correos electrónicos. El destinatario puede ser cualquier dirección de correo electrónico.

Escribe la función de Cloud Functions

Crea un depósito de Cloud Storage para habilitar a etapa tus archivos de Cloud Functions, en el que [STAGING_BUCKET_NAME] es un nombre de depósito único a nivel global (como [PROJECT-ID]_cloudbuilds):

gsutil mb gs://[STAGING_BUCKET_NAME]

Deberías ver el siguiente resultado:

Creating gs://[PROJECT-ID]_cloudbuilds/[STAGING_BUCKET_NAME]...

A continuación, crea un directorio en tu sistema local para el código de la aplicación:

Linux/macOS

mkdir ~/gcb_email
cd ~/gcb_email

Windows

mkdir %HOMEPATH%\gcb_email
cd %HOMEPATH%\gcb_email

Luego, crea los siguientes archivos en el directorio gcb_email:

index.js

const Mailgun = require('mailgun-js');
const humanizeDuration = require('humanize-duration');
const config = require('./config.json');

module.exports.mailgun = new Mailgun({
  apiKey: config.MAILGUN_API_KEY,
  domain: config.MAILGUN_DOMAIN,
});

// subscribe is the main function called by Cloud Functions.
module.exports.subscribe = (event, callback) => {
  const build = module.exports.eventToBuild(event.data.data);

  // Skip if the current status is not in the status list.
  const status = ['SUCCESS', 'FAILURE', 'INTERNAL_ERROR', 'TIMEOUT'];
  if (status.indexOf(build.status) === -1) {
    return callback();
  }

  // Send email.
  const message = module.exports.createEmail(build);
  module.exports.mailgun.messages().send(message, callback);
};

// eventToBuild transforms pubsub event message to a build object.
module.exports.eventToBuild = (data) => {
  return JSON.parse(new Buffer(data, 'base64').toString());
}

// createEmail create an email message from a build object.
module.exports.createEmail = (build) => {
  let duration = humanizeDuration(new Date(build.finishTime) - new Date(build.startTime));
  let content = `<p>Build ${build.id} finished with status ${build.status}, in ${duration}.</p>`
    + `<p><a href="${build.logUrl}">Build logs</a></p>`;
  if (build.images) {
    let images = build.images.join(',');
    content += `<p>Images: ${images}</p>`;
  }
  let message = {
    from: config.MAILGUN_FROM,
    to: config.MAILGUN_TO,
    subject: `Build ${build.id} finished`,
    text: content
  };
  return message
}

config.json

  {
     "MAILGUN_API_KEY":"[API_KEY]",
     "MAILGUN_DOMAIN":"email.com",
     "MAILGUN_FROM":"me@email.com",
     "MAILGUN_TO":"someone@email.com"
  }

En este archivo, debes proporcionar la siguiente información:

  • MAILGUN_API_KEY, la clave de API que recopilaste
  • MAILGUN_DOMAIN, el dominio que agregaste
  • MAILGUN_FROM, la dirección de correo electrónico que pertenece al dominio desde el cual se envían los correos electrónicos (incluso uno que no existe)
  • MAILGUN_TO, la dirección de correo electrónico a la que se envía el correo electrónico

package.json

  {
    "name": "google-container-email",
    "version": "0.0.1",
    "description": "Email integration for Google Cloud Build, using Google Cloud Functions",
    "main": "index.js"
    },
    "dependencies": {
      "humanize-duration": "3.10.0",
      "mailgun-js": "~0.11.2"
    },
    "devDependencies": {
      "async": "^2.1.5",
      "mocha": "3.2.0",
      "should": "11.2.1"
    },
  }

package.json describe lo siguiente:

  • el nombre, la versión y la descripción del programa
  • sus archivos de entorno de ejecución principales
  • sus dependencias

Ahora, deberías tener index.js, config.json y package.json en el directorio gcb_email.

Implementa la función de Cloud Functions

Para implementar la función, ejecuta el siguiente comando en el directorio gcb_email:

gcloud functions deploy subscribe --stage-bucket [STAGING_BUCKET_NAME] --trigger-topic cloud-builds

en el que [STAGING_BUCKET_NAME] es el nombre de tu depósito de etapa de pruebas de Cloud Storage, como [PROJECT-ID]_cloudbuilds.

Luego de completar la implementación de la función de Cloud Functions, debes recibir una notificación por correo electrónico cuando se produce un evento de compilación.

Prueba la función

Después de la configuración, debes probar tu implementación para asegurarte de que funciona según lo esperado. Para realizar la prueba, envía una compilación a Cloud Build.

Si deseas probar tu implementación con rapidez desde tu entorno local, crea un archivo llamado request.json que contenga el siguiente código. Esta solicitud sube una imagen de demostración en tu repositorio.

  {
    "source": {
      "storageSource": {
        "bucket": "cloud-build-examples",
        "object": "node-docker-example.tar.gz"
      }
    },
    "steps": [
      {
        "name": "gcr.io/cloud-builders/docker",
        "args": [
          "build", "-t", "gcr.io/$PROJECT_ID/cb-demo-img", "."
        ]
      }
    ],
    "images": [
      "gcr.io/$PROJECT_ID/cb-demo-img"
    ]
  }
  

Luego, ejecuta el siguiente comando desde tu shell o ventana de terminal:

curl -X POST -T /PATH/TO/request.json -H "Authorization: Bearer $(gcloud auth print-access-token)" https://cloudbuild.googleapis.com/v1/projects/[PROJECT-ID]/builds

en donde:

  • [PROJECT-ID] es el ID del proyecto
  • /PATH/TO/request.json es la ruta del archivo

Deberías ver un resultado similar al que se detalla a continuación:

{
  "name": "operations/build/[PROJECT-ID]/...,
  "metadata": {
    "@type": "type.googleapis.com/google.devtools.cloudbuild.v1.BuildOperationMetadata",
    "build": {
      "id": "...",
      "status": "QUEUED",
      "source": {
        "storageSource": {
          "bucket": "cloud-build-examples",
          "object": "node-docker-example.tar.gz"
        }
      },
      "createTime": "...",
      "steps": [
        {
          "name": "gcr.io/cloud-builders/docker",
          "args": [
            "build",
            "-t",
            "gcr.io/[PROJECT-ID]/cb-demo-img",
            "."
          ]
        }
      ],
      "timeout": "600s",
      "images": [
        "gcr.io/[PROJECT-ID]/cb-demo-img"
      ],
      "projectId": "[PROJECT-ID]",

Si seguiste las instrucciones de Slack, deberías ver una notificación de Slack como la que se presenta a continuación:

Si seguiste las instrucciones de Mailgun, deberías recibir un correo electrónico sobre la compilación.

Borra la imagen de demostración

Para borrar la imagen de demostración, sigue estos pasos:

  1. Con tu navegador web, dirígete a https://gcr.io/[PROJECT-ID]/cb-demo-img, en el que [PROJECT-ID] es el ID del proyecto.
  2. Marca la casilla junto a la imagen.
  3. Haz clic en Borrar.

Limpieza

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud Platform por los recursos que usaste en este instructivo:

Cómo borrar el proyecto

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

Para borrar el proyecto, haz lo siguiente:

  1. En la GCP Console, dirígete a la página Proyectos.

    Ir a la página Proyectos

  2. En la lista de proyectos, selecciona el proyecto que deseas borrar y haz clic en Borrar.
  3. En el cuadro de diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

Borra las funciones de Cloud Functions

Borrar las funciones de Cloud Functions quita todos los recursos de Kubernetes Engine, pero debes quitar de manera manual cualquier recurso en Cloud Storage y Cloud Pub/Sub.

Usa el siguiente comando para borrar una función de Cloud Functions:

gcloud functions delete [NAME_OF_FUNCTION]

También puedes borrar las funciones de Cloud Functions desde Google Cloud Platform Console.

Pasos siguientes

¿Te sirvió esta página? Envíanos tu opinión:

Enviar comentarios sobre…

Documentación de Cloud Build