Notification model in event-driven integrations

Learn how to design a notification strategy for Event-Driven architectures.

This document describes an implementation suggestion of a centralized notification mechanism for event-driven integrations on the Digibee Integration Platform. The goal is to ensure that important events, especially errors, are communicated in a reliable and scalable way, allowing systems and users to respond appropriately.

For more details on event-driven integrations on the Digibee Integration Platform, read the following articles:

Scenario

In an asynchronous integration environment, events can be triggered by multiple systems, requiring a robust mechanism to notify consumer systems or end users. The notification model proposed in this document addresses these challenges by considering:

  • Low latency upon delivery of the notification.

  • Delivery guarantee with resend attempts.

  • Flexibility for sending via different channels (email, webhook, queue, and so on).

  • Observability for event tracking.

  • Error handling with centralized repository and predefined rules.

Architecture

The implementation of the notification model follows an event-based architecture, where:

  1. Event trigger: Any business pipeline can trigger the pipeline save-notification-event via Digibee event called notification-event.

  2. Notification storage: The pipeline save-notification-event inserts or updates record in the notification-store Object Store, ensuring that duplicate messages are not stored within the defined time interval.

  3. Processing and sending the notification: A second pipeline, send-notification-timer, periodically consults the records stored in the notification-store and sends notifications based on established rules.

  4. Delivery to destination: Notifications are sent to your preferred systems, such as alert systems (Dynatrace, Datadog, Grafana, email) or ticket opening systems (ServiceNow, Zendesk, Jira).

Flow diagrams

Implementation at Digibee

Pipeline configuration

  1. save-notification-event pipeline:

    • Receives an event notification-event.

    • Checks if the message already exists in the notification-store.

    • Inserts a new record or updates an existing one, increasing the occurrence counter.

    • Defines the waiting time before sending the alert.

  2. send-notification-timer pipeline:

    • Retrieves records from notification-store paging the search every 500 records.

    • Applies criticality rules to define the destination of the notification.

    • Calculates shipping time based on alertWaitTime.

    • Sends the notification to the appropriate system.

Example of payloads

Event entry notification-event (Example for ServiceNow and Dynatrace)
{
  "titleError": "Example: Failure of integration of products",
  "message":"code of error + message",
  "pipelineName":"name do pipeline",
  "lastPipelineKey": "pipeline key",
  "stageIntegracao": "Which stage do flow occurred the error",
  "dataHora": "timestamp",
  "criticality": 1,
  "tempoEsperaAlerta": "1",
  "servicenow":{
    "variables":{
      "assignment_group": "",
      "u_type_closure": "",
      "urgency": "",
      "cmdb_ci": "",
      "business_service": "",
      "subcategory": ""
    }
  },
  "dynatrace":{
    "startTime": "",
    "properties":{
      "step": ""
    }
  }
}
Storage in notification-store
{
  "message":"code of error + message",
  "pipelineName":"name do pipeline",
  "stageIntegracao": "Which stage do flow occurred the error",
  "titleError": "Example: Failure of integration of products",
  "lastPipelineKey": "pipeline key",
  "dataHora": "timestamp",
  "criticality": 1,
  "qtdeOcorrencias": 1,
  "limiteAlert": "calculated",
  "servicenow":{
    "variables":{
      "assignment_group": "",
      "u_type_closure": "",
      "urgency": "",
      "cmdb_ci": "",
      "business_service": "",
      "subcategory": ""
    }
  },
  "dynatrace": {
    "startTime": "",
    "properties": {
      "step": ""
    }
  }
}

Pipeline spec examples

Trigger: Scheduler | Pipeline name: send-notification-timer
{
  "meta": {
    "e8e9e28e-c047-4591-9ad9-324dd4f7e425": {
      "position": {
        "x": 195,
        "y": 75
      }
    },
    "755c8909-8a1f-4b98-88c2-ae693fbb3ef5": {
      "position": {
        "x": 405,
        "y": 75
      }
    },
    "dcc24676-159c-4a93-aa9e-931d13ce1b3c": {
      "position": {
        "x": 600,
        "y": 75
      }
    },
    "0718a765-dcf7-42df-b959-a04b024f834d": {
      "position": {
        "x": 795,
        "y": 75
      }
    },
    "b185a262-9813-4bde-8287-b8cf500f3a62": {
      "position": {
        "x": 1245,
        "y": 0
      }
    },
    "9d2331d2-7842-494b-9be1-c6a4f2ce52e7": {
      "position": {
        "x": 1455,
        "y": 0
      }
    },
    "d7be81fd-d35f-4ee9-a56d-2c1e10989bbc": {
      "position": {
        "x": 1650,
        "y": 0
      }
    },
    "95792095-5b05-4d54-b65c-6b329884d159": {
      "position": {
        "x": 1845,
        "y": 0
      }
    },
    "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6": {
      "position": {
        "x": 2055,
        "y": 0
      }
    },
    "158d4027-f8c9-4274-a5bc-45064f6a81ed": {
      "position": {
        "x": 1245,
        "y": 150
      }
    },
    "eaf2e26f-a933-4f92-9f95-2caec4c69f04": {
      "position": {
        "x": 1455,
        "y": 150
      }
    },
    "6265f91e-daaf-4424-ad9e-f7af9aa8c63d": {
      "position": {
        "x": 0,
        "y": 225
      }
    }
  },
  "flowSpec": {
    "disconnected-root:2bc39e21-f496-451b-9649-76f2ff6074e7": [
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Delete notification-store +7 days",
        "params": {
          "operation": "DELETE_BY_QUERY",
          "objectStore": "notification-store",
          "query": "{\n    \"dataHora\": { $lt: {{ SUMDATE(NOW(), \"DAY\", -7) }} }\n}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "e8e9e28e-c047-4591-9ad9-324dd4f7e425"
      },
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Delete notification-store +7 days",
        "params": {
          "logLevel": "INFO",
          "message": "Delete notification-store +7 days: {{ message.$ }}"
        },
        "id": "755c8909-8a1f-4b98-88c2-ae693fbb3ef5"
      },
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Find notification-store",
        "params": {
          "operation": "FIND_BY_QUERY",
          "objectStore": "notification-store",
          "query": "{\n    \"limitAlert\": { $lt: {{ NOW() }} }\n}",
          "limit": "500",
          "skip": "0",
          "sort": "{}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "dcc24676-159c-4a93-aa9e-931d13ce1b3c"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "target": "Success notification-store (1)",
            "jsonPath": "$.[?(@.rowCount > 0)]",
            "__documentation__": ""
          }
        ],
        "otherwise": "Fail Find notificarion-store (1)",
        "id": "0718a765-dcf7-42df-b959-a04b024f834d"
      }
    ],
    "Success notification-store (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Success Find notification-store",
        "params": {
          "logLevel": "INFO",
          "message": "Success Find notification-store"
        },
        "id": "b185a262-9813-4bde-8287-b8cf500f3a62"
      },
      {
        "type": "transformer",
        "stepName": "Transformer (JOLT)",
        "transformSpec": [
          {
            "operation": "shift",
            "spec": {
              "data": [
                "&",
                "temp"
              ]
            }
          },
          {
            "operation": "shift",
            "spec": {
              "data": {
                "*": {
                  "criticidade": {
                    "1|2": {
                      "@2": "data[]"
                    }
                  }
                }
              },
              "temp": {
                "*": {
                  "criticidade": {
                    "3": {
                      "@2": [
                        "temp[]",
                        "temp[]"
                      ]
                    }
                  }
                }
              }
            }
          },
          {
            "operation": "shift",
            "spec": {
              "data": "&",
              "temp": {
                "*": "data[]"
              }
            }
          },
          {
            "operation": "shift",
            "spec": {
              "data": [
                "data",
                "data2"
              ]
            }
          },
          {
            "operation": "shift",
            "spec": {
              "data": {
                "*": {
                  "$": "data[#2].seq",
                  "tituloErro": "data[#2].&",
                  "mensagem": "data[#2].&",
                  "pipelineName": "data[#2].&",
                  "lastPipelineKey": "data[#2].&",
                  "etapaIntegracao": "data[#2].&",
                  "dataHora": "data[#2].&",
                  "criticidade": "data[#2].&",
                  "tempoEsperaAlerta": "data[#2].&",
                  "servicenow": "data[#2].&",
                  "dynatrace": "data[#2].&",
                  "limitAlert": "data[#2].&",
                  "qtdeOcorrencias": "data[#2].&",
                  "_oId": "data[#2].&"
                }
              }
            }
          },
          {
            "operation": "modify-overwrite-beta",
            "spec": {
              "data": {
                "*": {
                  "seq": "=toInteger"
                }
              }
            }
          }
        ],
        "id": "9d2331d2-7842-494b-9be1-c6a4f2ce52e7"
      },
      {
        "type": "connector",
        "name": "json-transformer-connector",
        "stepName": "JSON Transformer",
        "params": {
          "actions": "[{\"desc\":\"Description\",\"type\":\"edit\",\"props\":[{\"root\":false,\"path\":\"data\",\"keyValueStringEdit\":\"{\\\"criticidade\\\":\\\"{{ IF(EQUALTO(item.criticidade,3),IF(EQUALTO(MOD(item.seq,2),0.0),2,1),item.criticidade) }}\\\"}\",\"keyRemove\":\"\",\"keyValueToRemovePropWithCondition\":\"\"}]},{\"desc\":\"Description\",\"type\":\"remove\",\"props\":[{\"root\":false,\"path\":\"data\",\"keyRemove\":[\"seq\"],\"keyValueToRemovePropWithCondition\":\"\"}]}]",
          "failOnError": false
        },
        "id": "d7be81fd-d35f-4ee9-a56d-2c1e10989bbc"
      },
      {
        "type": "session-management",
        "stepName": "Put data",
        "operation": "PUT",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "data"
        ],
        "id": "95792095-5b05-4d54-b65c-6b329884d159"
      },
      {
        "type": "connector",
        "name": "for-each-connector",
        "stepName": "For Each data",
        "params": {
          "jsonPath": "$.data",
          "itemIdentifier": "",
          "parallel": false,
          "failOnError": false,
          "onProcess": "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6-onProcessTrack",
          "onException": "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6-onExceptionTrack"
        },
        "id": "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6"
      }
    ],
    "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6-onProcessTrack": [
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "request",
        "params": {
          "json": "{\n    \"request\": {{ message.$ }},\n    \"_oId\": {{ message._oId }}\n}",
          "failOnError": false
        },
        "id": "c8877f16-e81e-4a9f-8cdf-dfc9d361503b"
      },
      {
        "type": "session-management",
        "stepName": "Put _oId",
        "operation": "PUT",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "_oId"
        ],
        "id": "f1cb864a-e929-40f9-8db9-53769bec0e5c"
      },
      {
        "type": "connector",
        "name": "block-execution-connector",
        "stepName": "Send Customer Sistem",
        "params": {
          "onProcess": "290da7bf-fbab-4c42-8c1e-d5739b0c154a-onProcessTrack",
          "onException": "290da7bf-fbab-4c42-8c1e-d5739b0c154a-onExceptionTrack"
        },
        "id": "290da7bf-fbab-4c42-8c1e-d5739b0c154a",
        "description": "Block for to send the request for ServiceNow or Dynatrace"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "target": "Success Send",
            "jsonPath": "$.[?(@.success == true)]",
            "__documentation__": ""
          }
        ],
        "otherwise": "Fail Send ServiceNow|Dynatrace (1)",
        "id": "dc02a67b-ae79-4f35-8f5a-3972d542ce1a"
      }
    ],
    "290da7bf-fbab-4c42-8c1e-d5739b0c154a-onProcessTrack": [
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "target": "Criticidade 1",
            "jsonPath": "$.[?(@.request.criticidade == 1)]",
            "__documentation__": ""
          }
        ],
        "otherwise": "Criticidade 2",
        "id": "0458512a-0acf-4ed6-b057-b57ba665a845"
      }
    ],
    "Criticidade 1": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Sistem 1",
        "params": {
          "logLevel": "INFO",
          "message": "Sistem 1|Criticidade: {{ message.request.criticidade }}"
        },
        "id": "0c0bc38a-27de-4a33-8f42-9159ea86a3cb"
      }
    ],
    "Criticidade 2": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Sistem 2",
        "params": {
          "logLevel": "INFO",
          "message": "Sistem 2|Criticidade: {{ message.request.criticidade }}"
        },
        "id": "199422c1-e293-412d-aaa0-0a7fbd69e81c"
      }
    ],
    "Success Send": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Success Sent Sistem",
        "params": {
          "logLevel": "INFO",
          "message": "Success Sent Sistem"
        },
        "id": "a652992f-690a-4c17-a5e9-be2d93c3b87e"
      },
      {
        "type": "session-management",
        "stepName": "Get _oId",
        "operation": "GET",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "_oId"
        ],
        "id": "1176936e-5a03-4bcb-a0ce-1832b6392159"
      },
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Delete notification-store",
        "params": {
          "operation": "DELETE",
          "objectStore": "notification-store",
          "objectId": "{{ message._oId }}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "a1ade107-bb49-45c4-b945-7a014b7278c9"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "target": "Success Delete ObjStore (1)",
            "jsonPath": "$.[?(@.updateCount > 0)]",
            "__documentation__": ""
          }
        ],
        "otherwise": "Fail Delete ObjStore (1)",
        "id": "a3a527cc-2b8c-4fca-b7e1-827818b7e803"
      }
    ],
    "Success Delete ObjStore (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Success Delete ObjStore",
        "params": {
          "logLevel": "INFO",
          "message": "Success Delete ObjStore"
        },
        "id": "ca9d769c-25a0-4c17-b82f-d53a29f0d332"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "success true",
        "params": {
          "json": "{\n    \"success\": true\n}",
          "failOnError": false
        },
        "id": "b797fdb1-9a57-4840-821c-a24a623fbfe8"
      }
    ],
    "Fail Delete ObjStore (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Fail Delete ObjStore",
        "params": {
          "logLevel": "ERROR",
          "message": "Fail  Delete ObjStore {{ message.$ }}"
        },
        "id": "ac4b8a02-51d9-41d4-97ab-4d04728bfafb"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "success true",
        "params": {
          "json": "{\n    \"success\": true\n}",
          "failOnError": false
        },
        "id": "af7d02b7-1e08-4ee6-823a-94146c0f6945"
      }
    ],
    "Fail Send ServiceNow|Dynatrace (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Fail Sent ServiceNow/Dynatrace",
        "params": {
          "logLevel": "ERROR",
          "message": "Fail Sent ServiceNow/Dynatrace"
        },
        "id": "f6171366-3394-4628-a349-bb1ffe373814"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "success false",
        "params": {
          "json": "{\n    \"success\": false\n}",
          "failOnError": false
        },
        "id": "719e5f44-744d-4263-af9f-ad4422be6a83"
      }
    ],
    "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6-onExceptionTrack": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Error For Each",
        "params": {
          "logLevel": "ERROR",
          "message": "Error For Each {{ message.$ }}"
        },
        "id": "6d5ac53a-58f4-4369-a6b5-0b67188f39c3"
      }
    ],
    "Fail Find notificarion-store (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Not Found notification-store",
        "params": {
          "logLevel": "WARN",
          "message": "Not Found notification-store"
        },
        "id": "158d4027-f8c9-4274-a5bc-45064f6a81ed"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "JSON Generator",
        "params": {
          "json": "{\n    \"message\": \"Registers not found in notification-store.\",\n    \"dateTime\": {{ FORMATDATE(NOW(),\"timestamp\",\"dd/MM/yyyy HH:mm:ss\",\"pt-BR\",\"GMT-3\") }}\n}",
          "failOnError": false
        },
        "id": "eaf2e26f-a933-4f92-9f95-2caec4c69f04"
      }
    ],
    "disconnected-root:3f84c991-d096-4afd-9283-8a87a2e1cddb": [
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "Find notification-store",
        "params": {
          "json": "{\n  \"data\": [\n    {\n      \"tituloErro\": \"Exemplo: Falha de integração de produtos\",\n      \"mensagem\": \"código de erro + mensagem\",\n      \"pipelineName\": \"nome do pipeline\",\n      \"lastPipelineKey\": \"pipeline key\",\n      \"etapaIntegracao\": \"Qual etapa do fluxo ocorreu o erro\",\n      \"dataHora\": 1692020829906,\n      \"criticidade\": 1,\n      \"tempoEsperaAlerta\": 1,\n      \"servicenow\": {\n        \"variables\": {\n          \"assignment_group\": \"\",\n          \"u_type_closure\": \"\",\n          \"urgency\": \"\",\n          \"cmdb_ci\": \"\",\n          \"business_service\": \"\",\n          \"subcategory\": \"\"\n        }\n      },\n      \"dynatrace\": {\n        \"timeout\": \"\",\n        \"properties\": {\n          \"step\": \"\"\n        }\n      },\n      \"limitAlert\": 1692024429906,\n      \"qtdeOcorrencias\": 16,\n      \"_oId\": \"7d874ba1-7dd4-4880-8afb-de041b8ef649\"\n    },\n    {\n      \"tituloErro\": \"Exemplo: Falha de integração de produtos\",\n      \"mensagem\": \"código de erro + mensagem\",\n      \"pipelineName\": \"nome do pipeline\",\n      \"lastPipelineKey\": \"pipeline key\",\n      \"etapaIntegracao\": \"Qual etapa do fluxo ocorreu o erro\",\n      \"dataHora\": 1692020829906,\n      \"criticidade\": 3,\n      \"tempoEsperaAlerta\": 1,\n      \"servicenow\": {\n        \"variables\": {\n          \"assignment_group\": \"\",\n          \"u_type_closure\": \"\",\n          \"urgency\": \"\",\n          \"cmdb_ci\": \"\",\n          \"business_service\": \"\",\n          \"subcategory\": \"\"\n        }\n      },\n      \"dynatrace\": {\n        \"timeout\": \"\",\n        \"properties\": {\n          \"step\": \"\"\n        }\n      },\n      \"limitAlert\": 1692024429906,\n      \"qtdeOcorrencias\": 16,\n      \"_oId\": \"7d874ba1-7dd4-4880-8afb-de041b8ef649\"\n    },\n    {\n      \"tituloErro\": \"Exemplo: Falha de integração de produtos\",\n      \"mensagem\": \"código de erro + mensagem\",\n      \"pipelineName\": \"nome do pipeline\",\n      \"lastPipelineKey\": \"pipeline key\",\n      \"etapaIntegracao\": \"Qual etapa do fluxo ocorreu o erro\",\n      \"dataHora\": 1692020829906,\n      \"criticidade\": 3,\n      \"tempoEsperaAlerta\": 1,\n      \"servicenow\": {\n        \"variables\": {\n          \"assignment_group\": \"\",\n          \"u_type_closure\": \"\",\n          \"urgency\": \"\",\n          \"cmdb_ci\": \"\",\n          \"business_service\": \"\",\n          \"subcategory\": \"\"\n        }\n      },\n      \"dynatrace\": {\n        \"timeout\": \"\",\n        \"properties\": {\n          \"step\": \"\"\n        }\n      },\n      \"limitAlert\": 1692024429906,\n      \"qtdeOcorrencias\": 16,\n      \"_oId\": \"7d874ba1-7dd4-4880-8afb-de041b8ef649\"\n    }\n  ],\n  \"rowCount\": 3\n}",
          "failOnError": false
        },
        "id": "6265f91e-daaf-4424-ad9e-f7af9aa8c63d",
        "__documentation__": ""
      }
    ]
  }
}
Trigger: Event | Event: notification-event
{
  "meta": {
    "634e4658-0bf8-4d51-a2f0-9f49b1773d21": {
      "position": {
        "x": 195,
        "y": 75
      }
    },
    "0923c0da-1662-4ed8-a90d-62b1c64bf45a": {
      "position": {
        "x": 400,
        "y": 75
      }
    },
    "a0fba1b5-66a7-4d85-b19b-673063d528db": {
      "position": {
        "x": 600,
        "y": 75
      }
    },
    "419107c2-aa79-4c11-80a1-b6d032824659": {
      "position": {
        "x": 800,
        "y": 75
      }
    },
    "1a914487-be66-4c4f-8268-d20476c33d37": {
      "position": {
        "x": 1000,
        "y": 75
      }
    },
    "6cd53565-b6c5-4fe7-945d-5eaf21287072": {
      "position": {
        "x": 1450,
        "y": 0
      }
    },
    "93a0465b-a939-40a2-af3e-e5b32bda3061": {
      "position": {
        "x": 1650,
        "y": 0
      }
    },
    "b5f6d727-72ea-4272-9c2c-6cc0cde483b9": {
      "position": {
        "x": 1850,
        "y": 0
      }
    },
    "4015ccfe-df27-4554-8cdc-4fc5311f8bd3": {
      "position": {
        "x": 2050,
        "y": 0
      }
    },
    "4f6fc79d-72f9-41e9-bfa5-1f8a81d4850b": {
      "position": {
        "x": 2250,
        "y": 0
      }
    },
    "65ecf8db-6aaa-4409-b032-57a1450c69a8": {
      "position": {
        "x": 2450,
        "y": 0
      }
    },
    "a948890b-e52a-4bee-854f-294a9f14528d": {
      "position": {
        "x": 1450,
        "y": 150
      }
    },
    "0d4065ac-2801-4c50-94f9-c6224d4fc272": {
      "position": {
        "x": 1650,
        "y": 150
      }
    },
    "9ddf92c8-b8c4-4599-8238-8aea39d8ae9a": {
      "position": {
        "x": 1850,
        "y": 150
      }
    },
    "15714b58-3223-47bc-b0a2-acdbe7f9f00c": {
      "position": {
        "x": 2050,
        "y": 150
      }
    },
    "5415eeb8-1242-49d9-b95c-e192f7ea2e9b": {
      "position": {
        "x": 2250,
        "y": 150
      }
    },
    "614f85c5-4137-4a93-926e-89b8c0238cc3": {
      "position": {
        "x": 2450,
        "y": 150
      }
    },
    "78a22097-4485-4810-aa04-fc488568751c": {
      "position": {
        "x": 0,
        "y": 225
      }
    }
  },
  "flowSpec": {
    "disconnected-root:d43c4651-80c1-4594-9f64-91ff52edc963": [
      {
        "type": "transformer",
        "stepName": "Transformer (JOLT)",
        "transformSpec": [
          {
            "operation": "shift",
            "spec": {
              "*": "payload.&"
            }
          },
          {
            "operation": "modify-overwrite-beta",
            "spec": {
              "payload": {
                "limitAlert": 0,
                "qtdeOcorrencias": 1
              }
            }
          }
        ],
        "id": "634e4658-0bf8-4d51-a2f0-9f49b1773d21"
      },
      {
        "type": "validator",
        "stepName": "Validator (JSON Schema)",
        "validationSpec": {
          "schema": "http://json-schema.org/draft-04/schema#",
          "additionalProperties": false,
          "definitions": {},
          "id": "validate-schema-form",
          "properties": {
            "payload": {
              "type": "object",
              "properties": {
                "tituloErro": {
                  "type": "string"
                },
                "mensagem": {
                  "type": "string"
                },
                "pipelineName": {
                  "type": "string"
                },
                "etapaIntegracao": {
                  "type": "string"
                },
                "dataHora": {
                  "type": "number"
                },
                "criticidade": {
                  "type": "number"
                },
                "tempoEsperaAlerta": {
                  "type": "number"
                }
              },
              "required": [
                "tituloErro",
                "mensagem",
                "pipelineName",
                "lastPipelineKey",
                "etapaIntegracao",
                "dataHora",
                "criticidade",
                "tempoEsperaAlerta"
              ]
            }
          },
          "required": [
            "payload"
          ],
          "type": "object"
        },
        "id": "0923c0da-1662-4ed8-a90d-62b1c64bf45a"
      },
      {
        "type": "session-management",
        "stepName": "Put payload",
        "operation": "PUT",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "payload"
        ],
        "id": "a0fba1b5-66a7-4d85-b19b-673063d528db"
      },
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Find notification-store",
        "params": {
          "operation": "FIND_BY_QUERY",
          "objectStore": "notification-store",
          "expireAfterSeconds": 0,
          "query": "{\n    \"pipelineName\": {{ message.payload.pipelineName }},\n    \"mensagem\": {{ message.payload.mensagem }},\n    \"etapaIntegracao\": {{ message.payload.etapaIntegracao }}\n}",
          "limit": "0",
          "skip": "0",
          "sort": "{}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "419107c2-aa79-4c11-80a1-b6d032824659"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "target": "Success Find notificarion-store (1)",
            "jsonPath": "$.[?(@.rowCount > 0)]",
            "__documentation__": ""
          }
        ],
        "otherwise": "Fail Find notificarion-store (1)",
        "id": "1a914487-be66-4c4f-8268-d20476c33d37"
      }
    ],
    "Success Find notificarion-store (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Success Find notification-store",
        "params": {
          "logLevel": "INFO",
          "message": "Success Find notification-store"
        },
        "id": "6cd53565-b6c5-4fe7-945d-5eaf21287072"
      },
      {
        "type": "transformer",
        "stepName": "Increment qtdeOcorrencias",
        "transformSpec": [
          {
            "operation": "shift",
            "spec": {
              "data": {
                "0": {
                  "_oId": "_oId",
                  "qtdeOcorrencias": "qtdeOcorrencias"
                }
              }
            }
          }
        ],
        "id": "93a0465b-a939-40a2-af3e-e5b32bda3061"
      },
      {
        "type": "session-management",
        "stepName": "Get payload",
        "operation": "GET",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "payload"
        ],
        "id": "b5f6d727-72ea-4272-9c2c-6cc0cde483b9"
      },
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Instert notification-store",
        "params": {
          "operation": "UPDATE",
          "objectStore": "notification-store",
          "objectId": "{{ message._oId }}",
          "query": "",
          "document": "{\n    $set:{\n        \"lastPipelineKey\": {{ message.payload.lastPipelineKey }},\n        \"dataHora\": {{ message.payload.dataHora }},\n        \"qtdeOcorrencias\": {{ TOINT(SUM(message.qtdeOcorrencias,1)) }}\n    }\n}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "4015ccfe-df27-4554-8cdc-4fc5311f8bd3"
      },
      {
        "type": "connector",
        "name": "assert-connector-v2",
        "stepName": "Assert V2",
        "params": {
          "condition": "{{ GREATERTHAN( message.updateCount, 0) }}",
          "errorMessage": "Error to Update Object Store: notification-store",
          "internalErrorMessage": "Internal Error",
          "errorCode": 500,
          "failOnError": true
        },
        "id": "4f6fc79d-72f9-41e9-bfa5-1f8a81d4850b"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "JSON Generator",
        "params": {
          "json": "{\n    \"message\": \"Success to Update notification-store.\"\n}",
          "failOnError": false
        },
        "id": "65ecf8db-6aaa-4409-b032-57a1450c69a8"
      }
    ],
    "Fail Find notificarion-store (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Fail Find notification-store",
        "params": {
          "logLevel": "INFO",
          "message": "Failed Find notification-store"
        },
        "id": "a948890b-e52a-4bee-854f-294a9f14528d"
      },
      {
        "type": "session-management",
        "stepName": "Get payload",
        "operation": "GET",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "payload"
        ],
        "id": "0d4065ac-2801-4c50-94f9-c6224d4fc272"
      },
      {
        "type": "connector",
        "name": "json-transformer-connector",
        "stepName": "Calcule limitAlert (in Minutes)",
        "params": {
          "actions": "[{\"type\":\"edit\",\"desc\":\"Calculate limitAlert\",\"props\":[{\"path\":\"payload\",\"keyValueStringEdit\":\"{\\\"limitAlert\\\":\\\"{{ SUMDATE(message.payload.dataHora, \\\\\\\"MINUTE\\\\\\\", message.payload.tempoEsperaAlerta, \\\\\\\"UTC\\\\\\\") }}\\\"}\"}]}]",
          "failOnError": false
        },
        "id": "9ddf92c8-b8c4-4599-8238-8aea39d8ae9a"
      },
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Instert notification-store",
        "params": {
          "operation": "INSERT",
          "objectStore": "notification-store",
          "objectId": "{{ UUID() }}",
          "document": "{{ message.payload }}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "15714b58-3223-47bc-b0a2-acdbe7f9f00c"
      },
      {
        "type": "connector",
        "name": "assert-connector-v2",
        "stepName": "Assert V2",
        "params": {
          "condition": "{{ GREATERTHAN( message.updateCount, 0) }}",
          "errorMessage": "Error to Update Object Store: notification-store",
          "internalErrorMessage": "Internal Error",
          "errorCode": 500,
          "failOnError": true
        },
        "id": "5415eeb8-1242-49d9-b95c-e192f7ea2e9b"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "JSON Generator",
        "params": {
          "json": "{\n    \"message\": \"Success to Insert notification-store.\"\n}",
          "failOnError": false
        },
        "id": "614f85c5-4137-4a93-926e-89b8c0238cc3"
      }
    ],
    "disconnected-root:a5dc82f0-714d-46f8-82ae-d5305557775b": [
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "Payload",
        "params": {
          "json": "{\n  \"tituloErro\": \"Exemplo: Falha de integração de produtos\",\n  \"mensagem\": \"código de erro + mensagem\",\n  \"pipelineName\": \"nome do pipeline2\",\n  \"lastPipelineKey\": \"pipeline key\",\n  \"etapaIntegracao\": \"Qual etapa do fluxo ocorreu o erro\",\n  \"dataHora\": {{ NOW() }},\n  \"criticidade\": 3,\n  \"tempoEsperaAlerta\": 60,\n  \"servicenow\": {\n    \"variables\": {\n      \"assignment_group\": \"\",\n      \"u_type_closure\": \"\",\n      \"urgency\": \"\",\n      \"cmdb_ci\": \"\",\n      \"business_service\": \"\",\n      \"subcategory\": \"\"\n    }\n  },\n  \"dynatrace\": {\n    \"timeout\": \"\",\n    \"properties\": {\n      \"step\": \"\"\n    }\n  }\n}",
          "failOnError": false
        },
        "id": "78a22097-4485-4810-aa04-fc488568751c"
      }
    ]
  }
}

Reprocessing strategy and notification rules

  • Avoid duplication: Repeated messages are not allowed in the same pipeline within the defined interval.

  • Updating existing records: If the key already exists, the occurrence counter is incremented.

  • Shipping time: The publisher defines the waiting time.

  • Criticality defines the destination:

    • Level 1: Call only (ex: ServiceNow)

    • Level 2: Alert only (ex: Dynatrace)

    • Level 3: Alert + call (ex: Dynatrace and ServiceNow)

Observability and monitoring

To ensure the reliability of notifications, it’s recommended:

  • Structured logging to track events and errors.

  • Metrics such as success rate and response time.

  • Alerts for recurring failures.

Conclusion

This notification model ensures reliable and scalable delivery of error messages in event-driven architectures. With Digibee, it’s possible to implement this model in a flexible and integrated way with existing systems, allowing automation and complete traceability of critical notifications.

Last updated

Was this helpful?