Como configurar notificações para serviços de terceiros

Quando o Cloud Build cria estados de alteração, é possível enviar notificações sobre essas alterações por meio de serviços de mensagens de terceiros ou por e-mail.

Serviços como o Slack oferecem Webhooks de entrada , uma forma simples de postar mensagens de aplicativos no Slack. Cloud Functions é uma solução de computação leve para criar funções de finalidade única, autônomas, que respondem a eventos de nuvem, como versões, sem que seja preciso gerenciar um servidor ou ambiente de execução. Quando ocorre um evento de nuvem, um acionador responde executando uma ação, como o envio de uma mensagem do Cloud Pub/Sub.

Há muitos serviços de terceiros, criados com a funcionalidade de mensagens entre aplicativos, como SendGrid e IFTTT. Use este tutorial como um modelo para se conectar a esses serviços.

Neste tutorial, mostramos como usar o Cloud Functions e o Cloud Pub/Sub para enviar notificações sobre o Cloud Build via Slack e Mailgun.

Objetivos

  • Implantar um aplicativo Slack para receber notificações externas do Cloud Build.
  • Escrever uma Cloud Function para enviar notificações do Pub/Sub para o Slack.
  • Configurar o Mailgun para receber notificações externas do Cloud Build.
  • Gravar uma "Função do Cloud" para enviar notificações do Pub/Sub para o Mailgun.

Custos

Neste tutorial, usamos componentes do Cloud Platform que podem ser cobrados, inclusive:

  • Cloud Functions
  • Cloud Pub/Sub
  • Cloud Build

Use a calculadora de preços para gerar uma estimativa de custo com base no uso previsto.

Usuários novos do Cloud Platform podem se qualificar para umaavaliação gratuita.

Antes de começar

  1. Faça login na sua Conta do Google.

    Se você ainda não tiver uma, inscreva-se.

  2. No Console do GCP, na página do seletor de projetos, selecione ou crie um projeto do GCP.

    Acesse a página do seletor de projetos

  3. Verifique se o faturamento foi ativado no projeto do Google Cloud Platform. Saiba como confirmar que o faturamento está ativado para seu projeto.

  4. Ative a(s) Cloud Functions e Cloud Pub/Sub APIs necessária(s).

    Ativar a(s) APIs

  5. Instale e inicialize o SDK do Cloud..
  6. Atualize e instale os componentes gcloud:
    gcloud components update &&
    gcloud components install alpha beta

Notificações do Slack

Veja nas seções a seguir as orientações para configurar notificações do Slack.

Como preparar o aplicativo Slack

  1. Faça o download do Slack no seu computador. Você precisa ingressar em um espaço de trabalho do Slack, para isso, registre-se com seu e-mail ou use um convite enviado por um Administrador do espaço de trabalho.

  2. Faça login no Slack usando o nome do seu espaço de trabalho e as credenciais da sua conta do Slack.

  3. Crie um novo aplicativo do Slack:

    1. Escolha o nome do aplicativo e o espaço de trabalho do Slack. Clique em Criar app.
    2. Em Recursos, clique em Webhooks de entrada.
    3. Ative Ativar Webhooks de entrada.
    4. Clique em Adicionar novo Webhook ao espaço de trabalho. Será aberta uma página de autorização.
    5. No menu suspenso, selecione o canal que receberá as notificações enviadas.
    6. Clique em Instalar.
    7. Foi criado um webhook para o aplicativo Slack. Copie o URL do Webhook e salve-o para uso posterior.

Como gravar o Cloud Function

Crie um novo diretório com o nome gcb_slack e altere o diretório nele:

mkdir ~/gcb_slack
cd ~/gcb_slack

Em seguida, crie os arquivos index.js e package.json no diretório gcb_slack:

index.js

const { IncomingWebhook } = require('@slack/webhook');
const url = process.env.SLACK_WEBHOOK_URL;

const webhook = new IncomingWebhook(url);

// subscribeSlack is the main function called by Cloud Functions.
module.exports.subscribeSlack = (pubSubEvent, context) => {
  const build = eventToBuild(pubSubEvent.data);

  // Skip if the current status is not in the status list.
  // Add additional statuses 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;
  }

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

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

// createSlackMessage creates a message from a build object.
const createSlackMessage = (build) => {
  const 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_URL é uma variável de ambiente do Cloud Functions que especifica o URL do webhook, criado para seu aplicativo Slack. Essa variável de ambiente será definida quando a função for implantada.

Esse programa usa o webhook do Slack para ficar atento e receber mensagens do Cloud Function. Quando um evento é disparado, uma mensagem é enviada ao webhook e transmitida para o Slack.

A função createSlackMessage foi simplificada para este exemplo. É possível expandir a mensagem para incluir outros dados, como cores de texto, imagens e duração da versão.

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/webhook": "5.0.1"
  }
}

package.json descreve:

  • nome, versão e descrição do programa
  • o arquivo de tempo de execução primário
  • as respectivas dependências

Este arquivo parece ser simples, mas é possível adicionar mais dependências, requisitos e outras informações, conforme necessário.

Agora, você deve ter index.js e package.json no diretório gcb_slack.

Como implantar o Cloud Function

Para implantar o subscribeSlack com um acionador do Cloud Pub/Sub, execute o seguinte comando no diretório gcb_slack:

gcloud functions deploy subscribeSlack --trigger-topic cloud-builds --runtime nodejs10 --set-env-vars "SLACK_WEBHOOK_URL=https://hooks.slack.com/…"

em que SLACK_WEBHOOK_URL define o URL de webhook criado para seu aplicativo Slack. O formato do URL é: https://hooks.slack.com/services/T…/B…/….

O resultado deve ser similar ao seguinte:

Deploying function…
availableMemoryMb: 256
entryPoint: subscribeSlack
environmentVariables:
  SLACK_WEBHOOK_URL: https://hooks.slack.com/services/…
eventTrigger:
  eventType: google.pubsub.topic.publish
  failurePolicy: {}
  resource: projects/[PROJECT-ID]/topics/cloud-builds
  service: pubsub.googleapis.com
labels:
  deployment-tool: cli-gcloud
name: projects/[PROJECT-ID]/locations/us-central1/functions/subscribeSlack
runtime: nodejs10
serviceAccountEmail: [PROJECT-ID]@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/…
status: ACTIVE
timeout: 60s
updateTime: 'YYYY-MM-DDThh:mm:ssZ'
versionId: '1'

Depois de concluir a implantação do Cloud Function, você receberá uma notificação do Slack quando ocorrer um evento de versão.

Notificações por e-mail

Nas seções a seguir, explicamos a configuração de notificações por e-mail usando a API Mailgun.

Se você é novo no Mailgun, siga a documentação do Guia de início rápido.

Preparar configurações do Mailgun

  1. Crie uma conta do Mailgun, se ainda não tiver criado.
  2. Use o domínio do sandbox do Mailgun ou adicione um novo domínio e siga as instruções do Mailgun.
  3. Na página de domínios, clique no seu domínio para abrir a página de configurações.
  4. Na API, clique em Selecionar, Node.js, copie a chave de API do domínio e salve-a para uso posterior.

Você também precisa ter os seguintes itens:

  • Um endereço de e-mail para envios. Esse endereço de e-mail pode pertencer ao domínio que você forneceu. Se você tiver dúvida sobre o endereço de e-mail que usará, entre em contato com seu provedor de domínio. É possível fornecer um e-mail inexistente, caso você não espere receber uma resposta do destinatário, como noreply@mydomain.com.
  • Um endereço de e-mail para recebimentos.

Como gravar o Cloud Function

Crie um novo diretório com o nome gcb_email e altere o diretório nele:

mkdir ~/gcb_email
cd ~/gcb_email

Em seguida, crie os arquivos index.js, config.json e package.json no diretório gcb_email:

index.js

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

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

// subscribeMailgun is the main function called by Cloud Functions.
module.exports.subscribeMailgun = (pubSubEvent, context) => {
  const build = eventToBuild(pubSubEvent.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;
  }

  // Send email.
  const message = createEmail(build);
  mailgun.messages().send(message, (error, body) => console.log(body.message));
};

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

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

config.json

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

Neste arquivo, você precisa fornecer as informações abaixo:

  • MAILGUN_API_KEY, a chave de API que você coletou.
  • MAILGUN_DOMAIN, o domínio que você configurou
  • MAILGUN_FROM, o endereço de e-mail pertencente ao domínio de onde o e-mail é enviado (mesmo um que não exista).
  • MAILGUN_TO, o endereço para onde o e-mail é enviado.

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 descreve:

  • nome, versão e descrição do programa
  • o arquivo de tempo de execução primário
  • as respectivas dependências

Agora você deve ter index.js, config.json e package.json no diretório gcb_email.

Como implantar o Cloud Function

Para implantar a função, execute o seguinte comando no diretório gcb_email:

gcloud functions deploy subscribeMailgun --trigger-topic cloud-builds --runtime nodejs10

Depois de concluir a implantação do Cloud Function, você receberá uma notificação por e-mail quando ocorrer um evento de versão.

Como testar a função

Após a configuração, você precisa testar sua implementação para garantir que ela esteja funcionando como esperado. É possível testar enviando uma versão para o Cloud Build.

Crie um novo diretório com o nome gcb_test e altere o diretório nele:

mkdir ~/gcb_test
cd ~/gcb_test

Em seguida, crie um arquivo com o nome de request.json, contendo o código a seguir. Essa solicitação aciona uma versão de clonagem de um repositório.

request.json

{
  "steps": [
    {
      "name": "gcr.io/cloud-builders/git",
      "args": [
        "clone",
        "https://github.com/GoogleCloudPlatform/cloud-builders"
      ]
    }
  ]
}

Em seguida, execute o seguinte comando no diretório gcb_test:

Linux / macOS

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

PowerShell

(Invoke-WebRequest `
  -Method POST `
  -Headers @{ "Authorization" = "Bearer $(gcloud auth print-access-token)" } `
  -ContentType "application/json; charset=utf-8" `
  -InFile request.json `
  -Uri https://cloudbuild.googleapis.com/v1/projects/[PROJECT-ID]/builds `
).Content

em que o ID do projeto é [PROJECT-ID]

Você receberá uma resposta semelhante a esta:

{
  "name": "operations/build/[PROJECT-ID]/…",
  "metadata": {
    "@type": "type.googleapis.com/google.devtools.cloudbuild.v1.BuildOperationMetadata",
    "build": {
      "id": "…",
      "status": "QUEUED",
      "createTime": "…",
      "steps": [
        {
          "name": "gcr.io/cloud-builders/git",
          "args": [
            "clone",
            "https://github.com/GoogleCloudPlatform/cloud-builders"
          ]
        }
      ],
…

Se você tiver seguido as instruções do Slack, verá uma notificação do Slack como esta:

Se você tiver seguido as instruções do Mailgun, receberá um e-mail sobre a versão.

Limpar

Para evitar que os recursos usados neste tutorial sejam cobrados na conta do Google Cloud Platform:

Como excluir 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. No Console do GCP, acesse a página Gerenciar recursos.

    Acessar a página Gerenciar recursos

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

Como excluir o Cloud Functions

Para excluir o Cloud Functions implantado com este tutorial, execute os seguintes comandos:

gcloud functions delete subscribeMailgun
gcloud functions delete subscribeSlack

Também é possível excluir o Cloud Functions do Console do Google Cloud Platform.

A seguir