Firebase Cloud Functions Slack notifications

Reddit
Linkedin

Listing GCP events from the Firebase Cloud function is a big part of a scalable app

This is part 2 of a series of devops 101 with firebase cloud functions.

You can check the working repo here.

  1. Firebase Cloud Functions CI/CD with Cloud Build
  2. Firebase Cloud Functions and Slack notifications
  3. Firebase Cloud Functions Logging events
  4. Firestore Backups
  5. Firebase Disaster Recovery

Integrating a system with 3rd parties tool that makes us aware that something is going on is a critical part of any DevOps process these days. Let's see how we can integrate our previously cloud build deployment process with slack notifications. This is a part 2 of this cloud build integration with firebase cloud function series.

Setup

Before we start, we need to make sure we have everything available.

Subscribe our firebase project to Pub/Sub

  1. Open your gcloud console and go to the IAM section.

  2. Locate your firebase project, it should be called something like YOUR_PROJECT_NAME@appspot.gserviceaccount.com

  3. Add the PubSub subscriber role

IAM VIEW

Roles VIEW

Create your slack webhook

  1. Open your slack application page here and select your app.

  2. On the left sidebar, click on Incoming Webhooks then click Add New Webhook to Workspace select which channel you want to post your message.

  3. Copy the url generated, we are going to need it.

Slack webhook

Let's create the cloud function

A little of information here, when we trigger a deployment as we set on the previous post this triggers a message via PubSub called cloud-builds, our main goal is to listen to this even and act according, easy 👻.

The trigger

Your end result should like this:

import * as admin from 'firebase-admin'
import * as functions from 'firebase-functions'
import { sendBuildNotification } from './build_notification'
admin.initializeApp()
export const sendSlackMessage = functions.pubsub
    .topic(`cloud-builds`)
    .onPublish(sendBuildNotification)

The Message sender

You will need to divide this part into two:

  1. Assembling your event
  2. Formatting the slack message

The message

Let's install some dependencies (assuming you already installed the firebase project).

npm install --save @slack/client lodash

Now we need to set the SLACK_WEBHOOK_URL as an environment variable:

firebase functions:config:set slack.deploymentWebhook="YOUR SLACK WEBHOOK HERE"
import { IncomingWebhook }  from '@slack/client'
import * as functions from 'firebase-functions'
import { includes } from 'lodash'

const environment = functions.config()
const webhook = new IncomingWebhook(environment.slack.deploymentWebhook)

export const sendBuildNotification = async (message) => {
  try {
    const build = message.data ? 
    JSON.parse(new Buffer(message.data, 'base64').toString())
    : null // parse the stream message

    const status = ['SUCCESS', 'FAILURE', 'INTERNAL_ERROR', 'TIMEOUT']
    if (!includes(status, build.status)) return Promise.resolve({}) // ignore status that we dont care

    const message = _createSlackMessage(build) // format the slack message payload
    await webhook.send(message) // send the message 
    return Promise.resolve({ ok: true })
  } catch(error) {
    return Promise.reject({ error: error.message })
  }
}

Elegant and beautiful, let's know parse the slack payload

Slack payload

This part is a little more custom.

const _createSlackMessage = (build) => {
  const DEFAULT = `blue`
  const STATUS_COLOR = {
    QUEUED: DEFAULT,
    WORKING: DEFAULT,
    SUCCESS: `green`
    FAILURE: `red`,
    TIMEOUT: `yellow`,
    INTERNAL_ERROR: `red`,
  }
  return {
    color: STATUS_COLOR[build.status] || DEFAULT,
    title: 'GCP Build 👻',
    title_link: build.logUrl,
    fields: [{
      title: 'Status',
      value: build.status
    }],
    footer: 'Google Cloud Build',
    footer_icon: 'https://ssl.gstatic.com/pantheon/images/containerregistry/container_registry_color.png',
  }
}

Now after you deploy your project it should look like this on slack:

Slack Message

Conclusion

This is another tool to keep incorporating other CGS services into our firebase project that will help us to support a solid platform!

If you have any question about it please let me know at @andresmijares25 or @thecloudfn.

You can check the working repo here.

Enjoyed this post? Receive the next one in your inbox!

I hand pick all the best resources about Firebase and GCP around the web.


Not bullshit, not spam, just good content, promised 😘.


Reddit
Linkedin