Skip to Content
Technical Articles
Author's profile photo Jose Sequeira

CPI “Monitor” Scenario: Using a NodeJS API, Groovy and Email Adapter


On another Blog (check it out here), i’ve created a NodeJS API that extracts de Brazilian Web Service status for NF-e and CT-e (find out more about them here) in JSON. Now, it makes sense to have some sort of “monitor” to notify me when there is any Offline ones. This Blog is also intended to serve as “base” knowledge for those ho have similar requirement using CPI, as CT-e is something focused only here in Brazil. So you want to play around with another Rest API, Groovy Scripts, HTML Emails, etc., it can help you out.

For monitoring CT-e using CPI, here is what we’re going to do:

Basically, we’ll create an IFlow with a Timer that will periodically execute the Rest API for CT-e, check if there is any Offline ones (using Groovy Script) and Email me if there is, using a HTML template to make it look cooler. Your final IFlow should look like these:

So let’s do it, step by step. First create an IFlow, my is named CTE_Mon:

In the first step, delete the default one and create a Timer:

My is named Check WS Status, and scheduled every 5 minutes (use in whatever time line that makes sense to you).

After that, insert a Request Response:

Making a HTTP connection to (GET).

Don’t forget to add the API’s certificate in your Tenant Keystore, like this:

After the Request Response, connect to a Script Task (Groovy), and place the below code:

import java.util.HashMap;
import groovy.json.*;
def Message processData(Message message) {
        def body = message.getBody(String.class);  
        def jsonSlurper = new JsonSlurper();
        def list = jsonSlurper.parseText(body);    
        String result="";
        Boolean IsOffline=false; //Boolean for sending the email or not...
        String Offline = "Offline"; //Simple Constant
        { // Loop Start       
            result=result + "<tr><td style=\"text-align:center\">" + it.Autorizador + "</td>";
            //Check for Offline Web Services
            if( it.Recepcao == Offline ) {
                result=result + "<td style=\"text-align:center;background-color:#FF0000\">" + it.Recepcao + "</td>";
            } else {
                result=result + "<td style=\"text-align:center\">" + it.Recepcao + "</td>";
            if( it.Retorno_Recepcao == Offline ) {
                result=result + "<td style=\"text-align:center;background-color:#FF0000\">" + it.Retorno_Recepcao + "</td>";
            } else {
                result=result + "<td style=\"text-align:center\">" + it.Retorno_Recepcao + "</td>";
            if( it.Inutilizacao == Offline ) {
                result=result + "<td style=\"text-align:center;background-color:#FF0000\">" + it.Inutilizacao + "</td>";
            } else {
                result=result + "<td style=\"text-align:center\">" + it.Inutilizacao + "</td>";
            if( it.Consulta_Protocolo == Offline ) {
                result=result + "<td style=\"text-align:center;background-color:#FF0000\">" + it.Consulta_Protocolo + "</td>";
            } else {
                result=result + "<td style=\"text-align:center\">" + it.Consulta_Protocolo + "</td>";
            if( it.RecepcaoOS == Offline ) {
                result=result + "<td style=\"text-align:center;background-color:#FF0000\">" + it.RecepcaoOS + "</td>";
            } else {
                result=result + "<td style=\"text-align:center\">" + it.RecepcaoOS + "</td>";
            if( it.Status_Servico == Offline ) {
                result=result + "<td style=\"text-align:center;background-color:#FF0000\">" + it.Status_Servico + "</td>";
            } else {
                result=result + "<td style=\"text-align:center\">" + it.Status_Servico + "</td>";
            if( it.Recepcao_Evento == Offline ) {
                result=result + "<td style=\"text-align:center;background-color:#FF0000\">" + it.Recepcao_Evento + "</td>";
            } else {
                result=result + "<td style=\"text-align:center\">" + it.Recepcao_Evento + "</td>";
            result=result + "</tr>";
        } //Loop End    
        message.setProperty("MyOffline", IsOffline);
       return message;

Basically what this script is doing is: Checking if there is any Offline status returned from the Request Response payload, and if there is setting the MyOffline property that will later be checked to decide whether sends or not the email. Also filling up a HTML body that could be used on the email. It’s really simple code here, there are many other ways to do that. šŸ™‚

After that, create a Router like this:

That will decide here, to send or not the email:

As you can see, the receiver adapter is Mail. So configured it to a SMTP account of yours:


Place your Email for destination, and configure to Text/HTML placing the code below:


<!DOCTYPE html>
table, th, td {
  border: 1px solid black;
<IMG SRC="" ALT="some text" WIDTH=100 HEIGHT=100>
<h1>SAPĀ® Cloud Platform Integration CT-e Monitor Alert</h1>

<p>Offline Web Services found now, check out the list:</p>

	<th>Retorno RecepĆ§Ć£o</th>
	<th>Consulta Protocolo</th>
	<th>Status ServiƧo</th>
	<th>RecepĆ§Ć£o Evento</th>    
<p>Your CPI Tenant.</p>

As you can see, a “part” of the HTML was done on the Groovy Script and the “main part” was done here.

Don’t forget to test your SMTP setting before the IFlow is deployed, at:



And creating your Credentials here:

So if everything is working fine, deploy your IFlow and monitor!

Testing can get a little tricky, because it’s not really normal to have offline WS for CT-e (that’s the main idea to have this monitor, to act when they do).

Basically to check, you can go to the official monitor URL:

On the date below, we had one Offline State:

The API returned Offline for them:

And i got the email, in the end it looks like these:

Mobile view:

Hope you’ve enjoyed!


Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Fatih Pense
      Fatih Pense

      Hello Jose,

      Thanks for sharing the use case and the example.