Explore Developer Center's New Chatbot! MongoDB AI Chatbot can be accessed at the top of your navigation to answer all your MongoDB questions.

Introducing MongoDB 8.0, the fastest MongoDB ever!
MongoDB Developer
Atlas
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Productschevron-right
Atlaschevron-right

How to Send MongoDB Document Changes to a Slack Channel

Josman Pérez Expóstio6 min read • Published Oct 26, 2023 • Updated Oct 26, 2023
JavaScriptAtlas
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
In this tutorial, we will explore a seamless integration of your database with Slack using Atlas Triggers and the Slack API. Discover how to effortlessly send notifications to your desired Slack channels, effectively connecting the operations happening within your collections and relaying them in real-time updates.
The overall flow will be:
High level overview flow diagram of the proposed solution
In this way, every time an operation that we need to trace is registered, the content of the transaction itself will be processed and used to send a message to a specific Slack channel.

Creating the application in Atlas

To begin with, we will create a new application in Atlas. A step-by-step guide illustrating this process is available in our documentation.
Once this has been completed, we are ready to start creating our first database trigger that will react every time there is an operation in a certain collection.

Atlas trigger

For this tutorial, we will create a trigger that monitors all changes in a test collection for insert, update, and delete operations.
To create a new database trigger, you will need to:
  1. Click the Data Services tab in the top navigation of your screen if you haven't already navigated to Atlas.
  2. Click Triggers in the left-hand navigation.
  3. On the Overview tab of the Triggers page, click Add Trigger to open the trigger configuration page.
  4. Enter the configuration values for the trigger and click Save at the bottom of the page.
Please note that this trigger will make use of the event ordering as we want the operations to be processed according to when they were performed.
The trigger configuration values will look like this:
Screenshot of the triggers UI view
Finally, this trigger will be linked to a processEvent function which we'll see below.

Atlas functions

To create an Atlas function using the UI, we need to:
  1. Click the Data Services tab in the top navigation of your screen if you haven't already navigated to Atlas.
  2. Click Functions in the left navigation menu.
  3. Click New Function in the top right of the Functions page.
  4. Enter a unique, identifying name for the function in the Name field.
  5. Configure User Authentication. Functions in App Services always execute in the context of a specific application user or as a system user that bypasses rules. For this tutorial, we are going to use System user.

"processEvent" function

The processEvent function will process the change events every time an operation we are monitoring in the given collection is processed. In this way, we are going to create an object that we will then send to the function in charge of sending this message in Slack.
The code of the function is the following:
1exports = function(changeEvent) {
2
3 const docId = changeEvent.documentKey._id;
4
5 const { updateDescription, operationType } = changeEvent;
6
7 var object = {
8 operationType,
9 docId,
10 };
11
12 if (updateDescription) {
13 const updatedFields = updateDescription.updatedFields; // A document containing updated fields
14 const removedFields = updateDescription.removedFields; // An array of removed fields
15 object = {
16 ...object,
17 updatedFields,
18 removedFields
19 };
20 }
21
22 const result = context.functions.execute("sendToSlack", object);
23
24 return true;
25};
In this function, we will create an object that we will then send as a parameter to another function that will be in charge of sending to our Slack channel.
Here we will use change event and its properties to capture the:
  1. _id of the object that has been modified/inserted.
  2. Operation that has been performed.
  3. Fields of the object that have been modified or deleted when the operation has been an update.
With all this, we create an object and make use of the internal function calls to execute our sendToSlack function.

"sendToSlack" function

This function will make use of the "chat.postMessage" method of the Slack API to send a message to a specific channel.
To use the Slack library, you must add it as a dependency in your Atlas function. Therefore, in the Functions section, we must go to the Dependencies tab and install @slack/web-api.
You will need to have a Slack token that will be used for creating the WebClient object as well as a Slack application. Therefore:
  1. Create or use an existing Slack app: This is necessary as the subsequent token we will need will be linked to a Slack App. For this step, you can navigate to the Slack application and use your credentials to authenticate and create or use an existing app you are a member of.
  2. Within this app, we will need to create a bot token that will hold the authentication API key to send messages to the corresponding channel in the Slack app created. Please note that you will need to add as many authorization scopes on your token as you need, but the bare minimum is to add the chat:write scope to allow your app to post messages.
A full guide on how to get these two can be found in the Slack official documentation.
First, we will perform the logic with the received object to create a message adapted to the event that occurred.
1var message = "";
2if (arg.operationType == 'insert') {
3 message += `A new document with id \`${arg.docId}\` has been inserted`;
4} else if (arg.operationType == 'update') {
5 message += `The document \`${arg.docId}\` has been updated.`;
6 if (arg.updatedFields && Object.keys(arg.updatedFields).length > 0) {
7 message += ` The fileds ${JSON.stringify(arg.updatedFields)} has been modified.`;
8 }
9 if (arg.removedFields && arg.removedFields.length > 0) {
10 message += ` The fileds ${JSON.stringify(arg.removedFields)} has been removed.`;
11 }
12} else {
13 message += `An unexpected operation affecting document \`${arg.docId}\` ocurred`;
14}
Once we have the library, we must use it to create a WebClient client that we will use later to make use of the methods we need.
1 const { WebClient } = require('@slack/web-api');
2 // Read a token from the environment variables
3 const token = context.values.get('SLACK_TOKEN');
4 // Initialize
5 const app = new WebClient(token);
Finally, we can send our message with:
1try {
2 // Call the chat.postMessage method using the WebClient
3 const result = await app.chat.postMessage({
4 channel: channelId,
5 text: `New Event: ${message}`
6 });
7
8 console.log(result);
9}
10catch (error) {
11 console.error(error);
12}
The full function code will be as:
1exports = async function(arg){
2
3 const { WebClient } = require('@slack/web-api');
4 // Read a token from the environment variables
5 const token = context.values.get('SLACK_TOKEN');
6 const channelId = context.values.get('CHANNEL_ID');
7 // Initialize
8 const app = new WebClient(token);
9
10 var message = "";
11 if (arg.operationType == 'insert') {
12 message += `A new document with id \`${arg.docId}\` has been inserted`;
13 } else if (arg.operationType == 'update') {
14 message += `The document \`${arg.docId}\` has been updated.`;
15 if (arg.updatedFields && Object.keys(arg.updatedFields).length > 0) {
16 message += ` The fileds ${JSON.stringify(arg.updatedFields)} has been modified.`;
17 }
18 if (arg.removedFields && arg.removedFields.length > 0) {
19 message += ` The fileds ${JSON.stringify(arg.removedFields)} has been removed.`;
20 }
21 } else {
22 message += `An unexpected operation affecting document \`${arg.docId}\` ocurred`;
23 }
24
25 try {
26 // Call the chat.postMessage method using the WebClient
27 const result = await app.chat.postMessage({
28 channel: channelId,
29 text: `New Event: ${message}`
30 });
31 console.log(result);
32 }
33 catch (error) {
34 console.error(error);
35 }
36
37};
Note: The bot token we use must have the minimum permissions to send messages to a certain channel. We must also have the application created in Slack added to the channel where we want to receive the messages.
If everything is properly configured, every change in the collection and monitored operations will be received in the Slack channel:
Screenshot of a message being received in a Slack channel.
Please note that this example here is a simple guide. But from this guide, it can be extended and adapted to more complex needs.
You can use $match" expressions to only detect certain changes and then adapt the change event to only receive certain fields with a "$project".

Conclusion

In this tutorial, we've learned how to seamlessly integrate your database with Slack using Atlas Triggers and the Slack API. This integration allows you to send real-time notifications to your Slack channels, keeping your team informed about important operations within your database collections.
We started by creating a new application in Atlas and then set up a database trigger that reacts to specific collection operations. We explored the processEvent function, which processes change events and prepares the data for Slack notifications. Through a step-by-step process, we demonstrated how to create a message and use the Slack API to post it to a specific channel.
Now that you've grasped the basics, it's time to take your integration skills to the next level. Here are some steps you can follow:
  • Explore advanced use cases: Consider how you can adapt the principles you've learned to more complex scenarios within your organization. Whether it's custom notifications or handling specific database events, there are countless possibilities.
  • Dive into the Slack API documentation: For a deeper understanding of what's possible with Slack's API, explore their official documentation. This will help you harness the full potential of Slack's features.
By taking these steps, you'll be well on your way to creating powerful, customized integrations that can streamline your workflow and keep your team in the loop with real-time updates. Good luck with your integration journey!

Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Tutorial

Calling the MongoDB Atlas Administration API: How to Do it from Node, Python, and Ruby


Jun 18, 2024 | 4 min read
Article

Realm Triggers Treats and Tricks - Document-Based Trigger Scheduling


Sep 09, 2024 | 5 min read
Tutorial

Part #1: Build Your Own Vector Search with MongoDB Atlas and Amazon SageMaker


Sep 18, 2024 | 4 min read
Tutorial

Combining Your Database With Azure Blob Storage Using Data Federation


Oct 08, 2024 | 7 min read
Table of Contents
  • Creating the application in Atlas