Skip to content

Instantly share code, notes, and snippets.

@Andersos
Created January 29, 2024 20:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Andersos/6629cf0ea2531c4260bf018042e9c368 to your computer and use it in GitHub Desktop.
Save Andersos/6629cf0ea2531c4260bf018042e9c368 to your computer and use it in GitHub Desktop.
This script is run as a Firebase function to notify in a Slack channel about changes to Firebase Remote config. Read more in the blogpost about it at andersos.net/2024/firebase-remote-config-slack-notifications
import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';
import { TemplateVersion } from 'firebase-functions/v1/remoteConfig';
import jsonDiff from 'json-diff';
import fetch from 'node-fetch';
// If you are unsure about how to generate webhooks for Slack read this https://api.slack.com/messaging/webhooks
// const test_feed = 'https://hooks.slack.com/services/...';
const slack_notification_channel = 'https://hooks.slack.com/services/...';
const remoteConfigToSlack = async (versionMetadata: TemplateVersion): Promise<boolean> => {
functions.logger.log(`Remote config to Slack called`);
const { app } = admin.instanceId();
const currentVersion = versionMetadata.versionNumber;
const current = await admin.remoteConfig().getTemplateAtVersion(currentVersion);
const prev = await admin.remoteConfig().getTemplateAtVersion(currentVersion - 1);
const diff = jsonDiff.diff(prev, current);
const parameter = Object.keys(diff.parameters)[0] as string;
const parameters = Object.values(diff.parameters)[0] as any;
if(parameter.includes('__deleted')) {
await fetch(slack_notification_channel, {
method: 'POST',
body: JSON.stringify(
{
'blocks': [
{
'type': 'section',
'fields': [
{
'type': 'mrkdwn',
'text': `*Firebase Remote Config Deleted (${app.options.projectId})*`
}
]
},
{
'type': 'section',
'fields': [
{
'type': 'mrkdwn',
'text': `*Parameter deleted:*\n${parameter.substring(0, parameter.length - 9)}`
}
]
}
]
}
),
});
} else if(parameter.includes('__added')) {
await fetch(slack_notification_channel, {
method: 'POST',
body: JSON.stringify(
{
'blocks': [
{
'type': 'section',
'fields': [
{
'type': 'mrkdwn',
'text': `*Firebase Remote Config Added (${app.options.projectId})*`
}
]
},
{
'type': 'section',
'fields': [
{
'type': 'mrkdwn',
'text': `*Parameter added:*\n${parameter.substring(0, parameter.length - 7)}`
}
]
}
]
}
),
});
} else {
await fetch(slack_notification_channel, {
method: 'POST',
body: JSON.stringify(
{
'blocks': [
{
'type': 'section',
'fields': [
{
'type': 'mrkdwn',
'text': `*Firebase Remote Config Change (${app.options.projectId})*`
}
]
},
{
'type': 'section',
'fields': [
{
'type': 'mrkdwn',
'text': `*Parameter changed:*\n${parameter}`
}
]
},
{
'type': 'section',
'fields': [
{
'type': 'mrkdwn',
'text': `*Old:*\n${parameters.defaultValue.value.__old}`
},
{
'type': 'mrkdwn',
'text': `*New:*\n${parameters.defaultValue.value.__new}`
}
]
}
]
}
),
});
}
return true;
};
export default remoteConfigToSlack;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment