# Modelo de notificação em integrações orientadas a eventos

Este documento descreve uma sugestão de implementação de um **mecanismo de notificação centralizado** para integrações orientadas a eventos na Digibee Integration Platform. O objetivo é garantir que eventos importantes, especialmente erros, sejam comunicados de forma confiável e escalável, permitindo que sistemas e usuários respondam de maneira adequada.

{% hint style="info" %}
Para mais detalhes sobre integrações orientadas a eventos na Digibee Integration Platform, leia os seguintes artigos:

* [Arquitetura orientada a eventos](/documentation/resources/pt-br/best-practices/event-oriented-architecture.md)
* [Como usar Arquitetura orientada a eventos na Digibee Integration Platform](/documentation/resources/pt-br/use-cases/how-to-event-driven-architecture.md)
* [Estratégia de tratamento de erros em integrações orientadas a eventos](/documentation/resources/pt-br/use-cases/error-handling-strategy-in-event-driven-integrations.md)
  {% endhint %}

## Cenário

Em um ambiente de integração assíncrona, eventos podem ser disparados por diversos sistemas, exigindo um mecanismo robusto para notificar sistemas consumidores ou usuários finais. O modelo de notificação proposto neste documento aborda esses desafios considerando:

* **Baixa latência** na entrega da notificação.
* **Garantia de entrega** com tentativas de reenvio.
* **Flexibilidade** para envio via diferentes canais (email, webhook, fila, e assim por diante).
* **Observabilidade** para rastreamento de eventos.
* **Tratamento de erros** com repositório centralizado e regras predefinidas.

## Arquitetura

A implementação do modelo de notificação segue uma arquitetura baseada em eventos, onde:

1. **Disparo do evento**: Qualquer pipeline de negócio pode acionar o pipeline `save-notification-event` via evento Digibee chamado `notification-event`.
2. **Armazenamento da notificação**: O pipeline `save-notification-event` insere ou atualiza o registro no **Object Store** `notification-store`, garantindo que mensagens duplicadas não sejam armazenadas dentro do intervalo de tempo definido.
3. **Processamento e envio da notificação**: Um segundo pipeline, `send-notification-timer`, consulta periodicamente os registros armazenados no `notification-store` e realiza o envio das notificações com base nas regras estabelecidas.
4. **Entrega ao destino**: As notificações são enviadas para os sistemas de sua preferência, como sistemas de alerta (Dynatrace, Datadog, Grafana, e-mail) ou sistemas de abertura de tickets (ServiceNow, Zendesk, Jira).

## Diagrama de fluxo

<figure><img src="/files/qoCoWZ0M2an7Kzh7NkDW" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/LrM0zTo73zPKGJpfA7j3" alt=""><figcaption></figcaption></figure>

## Implementação na Digibee

### Configuração dos pipelines

1. **Pipeline `save-notification-event`**:
   * Recebe um evento `notification-event.`
   * Verifica se a mensagem já existe no `notification-store.`
   * Insere um novo registro ou atualiza um existente, incrementando o contador de ocorrências.
   * Define o tempo de espera antes do envio do alerta.
2. **Pipeline `send-notification-timer`**:
   * Recupera registros do `notification-store` paginando a busca a cada 500 registros.
   * Aplica regras de criticidade para definir o destino da notificação.
   * Calcula o horário de envio com base no `tempoEsperaAlerta.`
   * Envia a notificação ao sistema adequado.

### Exemplo de payloads

<details>

<summary>Entrada do evento <code>notification-event</code> (Exemplo para ServiceNow e Dynatrace)</summary>

```json
{
  "tituloErro": "Exemplo: Falha de integração de produtos",
  "mensagem":"código de erro + mensagem",
  "pipelineName":"nome do pipeline",
  "lastPipelineKey": "pipeline key",
  "etapaIntegracao": "Qual etapa do fluxo ocorreu o erro",
  "dataHora": "timestamp",
  "criticidade": 1,
  "tempoEsperaAlerta": "1",
  "servicenow":{
    "variables":{
      "assignment_group": "",
      "u_type_closure": "",
      "urgency": "",
      "cmdb_ci": "",
      "business_service": "",
      "subcategory": ""
    }
  },
  "dynatrace":{
    "startTime": "",
    "properties":{
      "step": ""
    }
  }
}

```

</details>

<details>

<summary>Armazenamento no <code>notification-store</code></summary>

```json
{
  "mensagem":"código de erro + mensagem",
  "pipelineName":"nome do pipeline",
  "etapaIntegracao": "Qual etapa do fluxo ocorreu o erro",
  "tituloErro": "Exemplo: Falha de integração de produtos",
  "lastPipelineKey": "pipeline key",
  "dataHora": "timestamp",
  "criticidade": 1,
  "qtdeOcorrencias": 1,
  "limiteAlert": "calculado",
  "servicenow":{
    "variables":{
      "assignment_group": "",
      "u_type_closure": "",
      "urgency": "",
      "cmdb_ci": "",
      "business_service": "",
      "subcategory": ""
    }
  },
  "dynatrace": {
    "startTime": "",
    "properties": {
      "step": ""
    }
  }
}

```

</details>

### Exemplos de pipeline specs

<details>

<summary>Trigger: Scheduler | Nome do pipeline: send-notification-timer</summary>

```json
{
  "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__": ""
      }
    ]
  }
}
```

</details>

<details>

<summary>Trigger: Event | Nome do evento: save-notification-event</summary>

```json
{
  "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"
      }
    ]
  }
}
```

</details>

## Estratégia de reprocessamento e regras de notificação

* **Evitar duplicidade:** Não pode haver mensagens repetidas no mesmo pipeline dentro do intervalo definido.
* **Atualização de registros existentes:** Se a chave já existir, o contador de ocorrências é incrementado.
* **Tempo para envio:** O publicador define o tempo de espera.
* **Criticidade define o destino:**
  * **Nível 1:** Apenas chamado (ex: ServiceNow)
  * **Nível 2:** Apenas alerta (ex: Dynatrace)
  * **Nível 3:** Alerta + chamado (ex: Dynatrace e ServiceNow)

## Observabilidade e monitoramento

Para garantir a confiabilidade das notificações, recomenda-se:

* **Logging estruturado** para rastrear eventos e erros.
* **Métricas** como taxa de sucesso e tempo de resposta.
* **Alertas** para falhas recorrentes.

## Conclusão

Este modelo de notificação garante a **entrega confiável e escalável de mensagens de erro** em arquiteturas orientadas a eventos. Com a Digibee, é possível implementar esse modelo de forma flexível e integrada aos sistemas existentes, permitindo automação e rastreabilidade completa das notificações críticas.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.digibee.com/documentation/resources/pt-br/best-practices/notification-model-in-event-driven-integrations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
