DEV Community

Hejun Wong
Hejun Wong

Posted on

Integrating MongoDB Atlas Alerts with Lark Custom Bot via AWS Lambda

Why Integrate Atlas with Lark?

MongoDB Atlas provides a sophisticated monitoring system that can alert teams to performance issues, security concerns, or other critical system events. Lark, on the other hand, is a powerful, versatile communication platform gaining popularity among businesses for its efficient collaboration tools.

However, integrating these alerts with communication platforms like Lark can be challenging since Atlas doesn't directly support it. Integrating Atlas alerts with Lark can streamline incident management by ensuring that critical alerts are immediately communicated to the right team members through their preferred communication channels.

The Integration Strategy

Understanding the Workflow
To integrate Atlas alerts with Lark, we need to create a middleware that receives alerts from Atlas, transforms the data into a Lark-compatible format, and forwards it to Lark.

Here's a step-by-step overview of the process:

  1. Setup a Lark Custom Bot in the Lark Group you would like to receive the Atlas Alerts

  2. Set up an AWS Lambda Function: This function will serve as the middleware that processes incoming alert data from Atlas, transforms it into a format compatible with Lark and forwards it to the Lark group.

  3. Configure API Gateway: Use API Gateway to expose a public REST endpoint that Atlas can send webhooks to. This gateway triggers the Lambda function.

  4. Integrate Atlas with the Webhook: Configure your Atlas project to send alerts to the API Gateway endpoint.

  5. Test out the Solution

Implementing the Solution

Define Environment Variables: Configure your Lambda function with the following environment variables to facilitate communication with Lark:

  • LARK_HOSTNAME: The base hostname for the Lark API. _open.larksuite.com_
  • LARK_PATH: The specific webhook path provided by Lark's Custom Bot /open-apis/bot/v2/hook/...
  • LARK_SECRET: The secret token provided by Lark's Custom Bot when signature verification has been enabled

AWS Lambda Function: Create a Lambda function that receives JSON payloads from Atlas and formats them for Lark.

import { request } from 'https';
import crypto from 'crypto';
function genSign(timestamp,secret) {
    // Take timestamp + "\n" + secret as the signature string
    const stringToSign = `${timestamp}\n${secret}`;
    // Use the HmacSHA256 algorithm to calculate the signature
    const hmac = crypto.createHmac('sha256', stringToSign);
    const signData = hmac.digest();
    // Return the Base64 encoded result
    return signData.toString('base64');
  }
export const handler = async (event) => {
    try {
        const parsedBody = JSON.parse(event.body);
        // Retrieve the humanReadable portion
        const humanReadableContent = parsedBody.humanReadable;
        const timestamp = Math.floor(Date.now() / 1000); // Example timestamp
        const secret = process.env.LARK_SECRET; // Replace with your Lark secret (enable Set signature verification)
        const signature = genSign(timestamp, secret);
        // Transform the payload to Lark's format
        const larkPayload = JSON.stringify({
            timestamp: timestamp,
            sign: signature,
            msg_type: 'text',
            content: {
                text: `Alert from MongoDB: \n${humanReadableContent}`,
            },
        });
        console.log('lark payload:', larkPayload);
        const options = {
            hostname: process.env.LARK_HOSTNAME, // Accesses the environment variable
            path: process.env.LARK_PATH,         // Accesses the environment variable
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Content-Length': larkPayload.length,
            },
        };
        await new Promise((resolve, reject) => {
            const req = request(options, (res) => {
                let data = '';
                res.on('data', (chunk) => {
                    data += chunk;
                });
                res.on('end', () => {
                    if (res.statusCode === 200) {
                        resolve();
                    } else {
                        reject(new Error(`Request failed. Status code: ${res.statusCode}`));
                    }
                });
            });
            req.on('error', (e) => {
                reject(e);
            });
            // Write the larkPayload data
            req.write(larkPayload);
            req.end();
        });
        return {
            statusCode: 200,
            body: JSON.stringify({ message: 'Alert forwarded to Lark' }),
        };
    } catch (error) {
        console.error('Error sending alert to Lark:', error);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: 'Failed to send alert to Lark' }),
        };
    }
}
Enter fullscreen mode Exit fullscreen mode

AWS API Gateway: Configure it to trigger the above Lambda function when an REST request from Atlas is received.

Integrate Atlas with the Webhook

  • Within your MongoDB Atlas Project Settings Page
  • Navigate to the Integrations section
  • Configure a new "Webhook"
  • In the "Webhook" field, enter the API Gateway endpoint URL that you configured
  • Save the settings

Test out the Solution
Add the Webhook as a new notifier within an existing active alert (e.g. Host has restarted) and perform a Resiliency Test on your MongoDB Cluster

Conclusion

By creating this middleware, we've effectively integrated MongoDB Atlas alerts with Lark, enhancing the operational communication within your organization. This setup allows for immediate and streamlined alert management, ensuring that your team can respond quickly to any issues that arise. Feel free to adapt and expand upon this solution to suit your organization's specific needs.

Integrating Atlas alerts with Lark can be a simple yet powerful improvement to your operational workflow. I hope this guide helps you in implementing it. Let me know your thoughts and feel free to share any enhancements you make.

Top comments (0)