設定第三方服務通知

當 Cloud Build 建構變更狀態時,您可以透過電子郵件向第三方訊息傳遞服務傳送關於此變更的通知。

Slack 等服務提供「連入 Webhook」的功能,可讓使用者將來自外部服務的訊息傳送至其用戶端。 Cloud Functions 可讓使用者撰寫單一用途的程式輔助函式,以接聽建構等雲端事件。發生雲端事件時,「觸發條件」會執行動作來回應,例如傳送 Cloud Pub/Sub 訊息。

有許多使用跨應用程式訊息傳遞功能建構的第三方服務,例如 SendGrid 與 IFTTT。您可以使用本教學課程做為範本來與此類服務連線。

本教學課程示範如何使用 Cloud Functions 與 Cloud Pub/Sub,藉由 Mailgun,以電子郵件形式將 Cloud Build 相關通知傳送給 Slack。

目標

  • 部署 Slack 應用程式或設定 Mailgun 以接收來自 Cloud Build 的外部通知。
  • 撰寫 Cloud 函式以將 Pub/Sub 通知傳送給 Slack 或 Mailgun。

費用

本教學課程使用的 Cloud Platform 可計費元件包括:

  • Cloud Functions
  • Cloud Pub/Sub
  • Kubernetes Engine

使用 Pricing Calculator 可根據您的預測使用量來產生預估費用。

新加入 Cloud Platform 的使用者可能符合免費試用的資格。

事前準備

  1. 登入您的 Google 帳戶。

    如果您沒有帳戶,請申請新帳戶

  2. 選取或建立 Google Cloud Platform 專案。

    前往「Manage resources」(管理資源) 頁面

  3. 請確認您已啟用 Google Cloud Platform 專案的計費功能。

    瞭解如何啟用計費功能

  4. 啟用Cloud Functions, Cloud Pub/Sub, and Kubernetes Engine API。

    啟用 API

  5. 安裝並初始化 Cloud SDK
  6. 更新並安裝 gcloud 元件:
    gcloud components update &&
    gcloud components install alpha beta

另外建議您完成 Kubernetes Engine 快速入門導覽課程,熟悉一下本產品。

Slack 通知

以下幾節會逐步引導您瞭解如何設定 Slack 通知。

準備 Slack 應用程式

  1. 為電腦下載 Slack。您也必須透過註冊電子郵件或使用團隊管理員傳送的邀請來加入 Slack 團隊

  2. 使用您的團隊名稱與 Slack 帳戶憑證登入 Slack

  3. 建立新的 Slack 應用程式

    1. 選擇應用程式的名稱與您的 Slack 團隊。按一下 [Create] (建立)
    2. 按一下 [Incoming Webhooks] (連入的 Webhook)
    3. 啟用連入的 Webhook。
    4. 按一下 [Add New Webhook to Team] (將 Webhook 新增至團隊)。授權頁面隨即會開啟。
    5. 從下拉式選單中選取您想傳送通知的目標管道。
    6. 按一下 [Authorize] (授權)
    7. 系統已建立 Slack 應用程式的 Webhook。複製 Webhook 並加以儲存,以供日後使用。

撰寫 Cloud 函式

建立 Cloud Storage 值區以暫存 Cloud Functions 檔案,其中 [STAGING_BUCKET_NAME] 是不重複的值區名稱 (例如 [PROJECT-ID]_cloudbuilds):

gsutil mb gs://[STAGING_BUCKET_NAME]

您應該會看到以下的輸出內容:

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

接下來,針對應用程式程式碼,在您的本機系統建立目錄:

Linux / macOS

mkdir ~/gcb_slack
cd ~/gcb_slack

Windows

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

然後,在 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 creates 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] 是 Slack 應用程式的連入 Webhook。

這個程式會使用 Slack 的 Webhook 接聽並接收來自 Cloud 函式的訊息。觸發事件時,系統會將訊息傳送至 Webhook,然後轉發至 Slack。

這個範例的 createSlackMessage 函式已經簡化。您可以展開訊息以顯示更多內容,其中包括文字顏色、圖片與建構持續時間。

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 說明:

  • 程式的名稱、版本與說明
  • 其主要執行階段檔案
  • 其依附元件

這個檔案看起來好像很簡單:您可以根據需要新增更多的依附元件、需求及其他資訊。

現在,您應該在 gcb_slack 目錄中擁有 index.jspackage.json

部署 Cloud 函式

如要使用 Cloud Pub/Sub 觸發條件部署 subscribe 函式,請在 gcb_slack 目錄中執行下列指令:

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

其中,[STAGING_BUCKET_NAME] 是暫存 Cloud Storage 值區的名稱,例如 [PROJECT-ID]_cloudbuilds

您應該會看到類似下列的輸出:

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

完成 Cloud 函式的部署作業之後,如果發生建構事件,您就會收到 Slack 通知。

電子郵件通知

以下幾節會逐步引導您使用 Mailgun API 設定電子郵件通知。

如果您是第一次使用 Mailgun,請遵循其快速入門導覽課程說明文件

準備 Mailgun 設定

  1. 如果您尚未建立 Mailgun 帳戶,請先建立帳戶。
  2. 新增網域,然後依照 Mailgun 的操作說明驗證網域。這項作業最多可能需要 48 小時才能完成。
  3. 網域頁面按一下您的網域,開啟其設定頁面。
  4. 從網域設定頁面,複製網域的 API 金鑰並加以儲存,以供日後使用。

您也必須擁有下列項目:

  • 用來傳送電子郵件的電子郵件地址。這個電子郵件地址可以屬於您提供的網域。如果您不確定要使用哪個電子郵件地址,請與網域供應商確認。如果您並不想收到收件者的回應,也可以提供不存在的電子郵件,例如 noreply@mydomain.com
  • 用來接收電子郵件的電子郵件地址。收件者可以是任何電子郵件地址。

撰寫 Cloud 函式

建立 Cloud Storage 值區以暫存 Cloud Functions 檔案,其中 [STAGING_BUCKET_NAME] 是不重複的值區名稱 (例如 [PROJECT-ID]_cloudbuilds):

gsutil mb gs://[STAGING_BUCKET_NAME]

您應該會看到以下的輸出內容:

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

接下來,針對應用程式程式碼,在您的本機系統建立目錄:

Linux / macOS

mkdir ~/gcb_email
cd ~/gcb_email

Windows

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

然後,在 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 creates 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"
  }

您必須在這個檔案中提供下列資訊:

  • MAILGUN_API_KEY,您收集的 API 金鑰
  • MAILGUN_DOMAIN,您新增的網域
  • MAILGUN_FROM,屬於傳送電子郵件來源網域的電子郵件地址 (不存在的電子郵件地址也可以)
  • MAILGUN_TO,接收電子郵件的電子郵件地址

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 說明:

  • 程式的名稱、版本與說明
  • 其主要執行階段檔案
  • 其依附元件

現在,您應該在 gcb_email 目錄中擁有 index.jsconfig.jsonpackage.json

部署 Cloud 函式

如要部署函式,請在 gcb_email 目錄中執行下列指令:

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

其中,[STAGING_BUCKET_NAME] 是暫存 Cloud Storage 值區的名稱,例如 [PROJECT-ID]_cloudbuilds

完成 Cloud 函式的部署作業之後,如果發生建構事件,您就會收到電子郵件通知。

測試函式

設定之後,您應該測試實作,確保其如預期般運作。您可以將建構提交至 Cloud Build 來進行測試。

如果您想從本機環境快速測試實作,請建立名為 request.json 且包含下列程式碼的檔案。這個要求會將示範映像檔上傳至您的存放區。

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

然後,從殼層或終端機視窗執行下列指令:

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

其中

  • [PROJECT-ID] 是您的專案 ID
  • /PATH/TO/request.json 是檔案路徑

您應該會看到類似下列的輸出:

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

如果您已依照 Slack 操作說明執行操作,應該會看到類似下列的 Slack 通知:

如果您已依照 Mailgun 操作說明執行操作,應該會收到關於建構的電子郵件。

刪除示範映像檔

如要刪除示範映像檔,請按照下列步驟操作:

  1. 使用網路瀏覽器造訪 https://gcr.io/[PROJECT-ID]/cb-demo-img,其中 [PROJECT-ID] 是您的專案 ID。
  2. 勾選映像檔旁邊的方塊。
  3. 按一下 [Delete] (刪除)

清除所用資源

如何避免系統向您的 Google Cloud Platform 帳戶收取您在本教學課程中使用資源的相關費用:

刪除專案

如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。

刪除專案:

  1. 前往 GCP 主控台的「Projects」(專案) 頁面。

    前往專案頁面

  2. 在專案清單中選取要刪除的專案,然後按一下 [Delete] (刪除)
  3. 在對話方塊中輸入專案 ID,按一下 [Shut down] (關閉) 即可刪除專案。

刪除 Cloud Functions

刪除 Cloud Functions 也會一併移除所有 Kubernetes Engine 資源,但您必須手動移除 Cloud Storage 與 Cloud Pub/Sub 中的任何資源。

使用下列指令刪除 Cloud 函式:

gcloud functions delete [NAME_OF_FUNCTION]

您也可從 Google Cloud Platform 主控台刪除 Cloud Functions。

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Cloud Build Documentation