Building a Simple Microservice

Build a simple microservice using Catalyst Basic I/O Functions and integrate it with Zoho CRM to send automated counter-based email alerts when more than a specific number of leads are created

Configure the Function

Let's begin coding the microservice.

If you have initialized the Basic I/O function in Java, the functions directory, in this case functions/countfunction, contains:

  • The CountAlert.java main function file
  • The catalyst-config.json configuration file
  • The JAR library files
  • Other dependencies

If you have initialized the Basic I/O function in Node.js, the functions directory, in this case functions/counter_based_alert_function, contains:

We will be adding code in the CountAlert.java or index.js file.

Note: Please go through the code given in this section to gain a better understanding.

Copy the Java code and paste it in CountAlert.java in the functions/countfunction directory, or the Node.js code and paste it in index.js in the functions/counter_based_alert_function directory of your project, and save the file. You can use any IDE of your choice to work with the application's files.

  • View code for CountAlert.java, index.js

    Copied 
    import com.catalyst.Context;
    import com.catalyst.basic.BasicIO;
    import com.catalyst.basic.ZCFunction;
    import com.zc.component.cache.ZCCache;
    import com.zc.component.mail.ZCMail;
    import com.zc.component.mail.ZCMailContent;
    
    import java.util.logging.Logger;
    import java.util.logging.Level;
    
    public class CountAlert implements ZCFunction {
     private static final Logger LOGGER = Logger.getLogger(CountAlert.class.getName());
    
     private static final String FROM_EMAIL="emma@zylker.com"; // The email address of the sender. Replace this with the email address you configured in Mail.
    
     private static final String TO_EMAIL="brandon.cooper@zylker.com"; // Replace this with the email address that you want the alert email to be sent to. 
    
     @Override
        public void runner(Context context, BasicIO basicIO) throws Exception {
    
      try {
       // Passes the feature name that was obtained from the input as the parameter. The feature name can be 'CRM' or 'Desk'.
       String featureName = (String) basicIO.getParameter("feature_name");
    
       // Passes the threshold count that was obtained from the input as the parameter
       String mailCountThreshold = (String) basicIO.getParameter("mail_count_threshold");
    
       // Gets the current count for the feature from the default segment of Catalyst Cache
       String value = ZCCache.getInstance()
              .getCacheValue("COUNTER_" + featureName)
              .getValue();
    
       // If the value is null, then the count is set to 1. This is done during the first execution for the feature.
       if (value == null) {
        ZCCache.getInstance()
            .putCacheValue("COUNTER_" + featureName, String.valueOf(1), 1l);
       } else {
        Integer count = Integer.valueOf(value);
    
        // If the value is not null, then the count is incremented by 1.
        count++;
    
        // Writes the count value to the default segment of Catalyst cache
        ZCCache.getInstance().putCacheValue("COUNTER_"+featureName,count.toString(),1l);
    
        // If the current count is greater than the threshold value, then an email alert is sent to the receiver configured above
        if (count > Integer.valueOf(mailCountThreshold)) {
         ZCMailContent content = ZCMailContent.getInstance();
         content.setFromEmail(FROM_EMAIL);
         content.setSubject("Alert!");
         content.setContent("Count exceeded the threshold limit for the feature:" +featureName);
         content.setToEmail(TO_EMAIL);
         ZCMail.getInstance()
            .sendMail(content);
         LOGGER.log(Level.INFO, "Email alert sent");//Written to the logs. You can view this log from Logs under the Monitor section in the console
        }
       }
    
       // Handles the 200 status code
       basicIO.setStatus(200);
       basicIO.write("The function executed successfully");
      }catch(Exception e)
      {
       LOGGER.log(Level.SEVERE,"Exception occurred while processing",e); //Written to the logs. You can view this log from Logs under the Monitor section in the console
    
       // Handles the 500 status code, when an exception occurs
       basicIO.setStatus(500);
       basicIO.write("Error in the function execution");
      }
     }
    }
    
    Copied  
    const catalyst = require("zcatalyst-sdk-node");
    
    module.exports = async(context, basicIO) => {
    try {
     const FROM_EMAIL="emma@zylker.com"; // The email address of the sender. Replace this with the email address you configured in Mail.
     const TO_EMAIL="brandon.cooper@zylker.com"; // Replace this with the email address that you want the alert email to be sent to. 
     let featureName = basicIO.getArgument("feature_name");
     let mailCountThreshold = basicIO.getArgument("mail_count_threshold");
     let app =  catalyst.initialize(context);
     let value = null;
     let cache = app.cache();
     let segment = cache.segment();
     let cachePromise = segment.getValue("COUNTER_" + featureName);
     await cachePromise.then((entity) => {
         value = entity;			
     	}).catch((err) => {
     		throw err;				
     		});
      if (value == null) {
             await segment.put("COUNTER_" + featureName,1,1);
        } else {
     	let count = parseInt(value);	
     	// If the value is not null, then the count is incremented by 1.
     	count++;	
     	// Writes the count value to the default segment of Catalyst cache	
     	await segment.put("COUNTER_" + featureName,count,1);	
     	// If the current count is greater than the threshold value, then an email alert is sent to the receiver configured above
     	if (count > parseInt(mailCountThreshold)) {
     		//Create a config object with the email configuration
     		let config = {
     			from_email: FROM_EMAIL, 
     			to_email: [TO_EMAIL],				
     			subject: 'Alert!',
     			content: "Count exceeded the threshold limit for the feature:" +featureName,				
     		};
     		//Send the mail by passing the config object
     		let email = app.email();
     		let mailPromise = email.sendMail(config);
     		await mailPromise.then((mailObject) => {	
     				console.log("Email Alert Sent");						
     			})
     			.catch((err) => {
     			throw err;				
     			});		
     	}
        }
        // Handles the 200 status code
     	 basicIO.setStatus(200);
     	 basicIO.write("The function executed successfully");
     } catch (error) {
     	console.log("Exception occurred while processing",error.toString()); //Written to the logs. You can view this log from Logs under the Monitor section in the console
     	// Handles the 500 status code, when an exception occurs
     	basicIO.setStatus(500);
     	basicIO.write("Error in the function execution");
     	}
     context.close(); //end of application
    };
    
Note: If you have intialized the function stack in Java, then ensure you replace the values of FROM_EMAIL in line 14 and TO_EMAIL in line 16 and if the function stack is intialized in Node.js then replace the values of FROM_EMAIL in line 5 and TO_EMAIL in line 6 in the code as instructed.

As discussed in the introduction, the function obtains the inputs for feature_name and mail_count_threshold from the user through the API, when it is invoked. It obtains the current counter value from the cache and then increments it by 1 after every invocation. It then writes the new counter value to the cache.

Note: Because we are using the default segment in Catalyst Cache, we need not configure it. You can learn more about this from the Cache help page.

If the current counter value is greater than the threshold limit specified by the user, the email alert will be sent to the address defined in the code. This information is also pushed to Catalyst Logs, with an appropriate message. You can check this from Logs under the Monitor section in the Catalyst console.

The functions directory is now configured.