> For the complete documentation index, see [llms.txt](https://portal-integracao.intelbras.com.br/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://portal-integracao.intelbras.com.br/catracas-ct-3000-2pb/obtendo-eventos-em-tempo-real/servidor-de-envio-de-eventos.md).

# Servidor de Envio de Eventos

## Servidor de Envio de Eventos

Por meio do servidor de envio de eventos é possível realizar a configuração de um endereço de ip, para o qual o dispositivo enviará os eventos. Todos os eventos deverão ser respondidos com o código HTTP 200, desta forma o dispositivo tem a garantia da entrega, para eventos que não sejam respondidos com este código o dispositivo irá realizar o armazenamento dos mesmos e fará a tentativa de envio destes eventos até que ocorra a resposta de status 200.

### Configurando Servidor de Envio de Eventos

#### Requisição - GET - Passo 1

<mark style="color:green;">`GET`</mark>`http://{{device_ip}}/cgi-bin/configManager.cgi?action=setConfig&Intelbras_ModeCfg.DeviceMode=1&PictureHttpUpload.Enable=true&PictureHttpUpload.UploadServerList[0].Address=192.168.1.200&PictureHttpUpload.UploadServerList[0].Port=3000&PictureHttpUpload.UploadServerList[0].Uploadpath=/notification&HTTPUploadPic.Enable=true&PictureHttpUpload.UploadServerList[0].HttpsEnable=false`

| param            | type    | description                                     |
| ---------------- | ------- | ----------------------------------------------- |
| `setConfig` \*   | String  | Comando para configuração                       |
| `Enable` \*      | Boolean | Habilita/Desabilita a função                    |
| `Address` \*     | String  | Endereço IP do Servidor (exemplo: 192.168.3.88) |
| `Port` \*        | Number  | Porta (Exemplo: 3000)                           |
| `Uploadpath` \*  | String  | Path (Exemplo: /notification)                   |
| `HttpsEnable` \* | Boolean | Habilita/Desabilita o HTTPS                     |

#### Requisição - GET - Passo 2

Ativação do modo servidor de envio de eventos (POST Events):

<mark style="color:green;">`GET`</mark>`http://{{device_ip}}/cgi-bin/configManager.cgi?action=setConfig&Intelbras_ModeCfg.DeviceMode=1`

| param        | type   | description                                                    |
| ------------ | ------ | -------------------------------------------------------------- |
| `DeviceMode` | Number | 0: StandAlone, 1: Servidor de Envio de Eventos, 2: Modo Online |

Verifique sempre as configurações de rede do seu produto, como Endereço de IP e Gateway, para garantir que o mesmo esteja acessível na rede.

#### Exemplo de Retorno - *multipart-mixed*:

```sh
--myboundary
Content-Type: text/plain
Content-Disposition: form-data; name="info"

{
   "Channel" : 0,
   "Events" : [
      {
         "Action" : "Pulse",               
         "Code" : "AccessControl",           // Código do tipo de Evento
         "Data" : {                          // Informação do Evento
            "Alive" : 100,
            "CardName" : "test",             // Nome do Usuário 
            "CardNo" : "",                   // Código do cartão em Hexadecimal 
            "CardType" : 0,                  // Tipo do Cartão 0: Ordinary card, 1: VIP card, 2: Guest card, 3: Patrol card, 4: Blocklist card, 5: Duress card
            "CreateTime" : 1581098928,       // Data da criação do Evento em Timestamp 
            "Door" : 0,                      // Porta ao qual ocorreu o acesso
            "ErrorCode" : 0,                 // Código do Erro / Motivo do Acesso negado 
            "ImageInfo" : [                  // Lista de informações da foto que é mandada junto ao evento 
               {
                  "Height" : 640,
                  "Length" : 11112,
                  "Offset" : 0,
                  "Type" : 1, ==> Foto de Contexto

                  "Width" : 360
               },
               {
                  "Height" : 480,
                  "Length" : 30313,
                  "Offset" : 11112,
                  "Type" : 0, ==> Foto do usuário
                  "Width" : 367
               },
               {
                  "Height" : 556,
                  "Length" : 12401,
                  "Offset" : 41425,
                  "Type" : 2, ==> Foto de contexto com recorte do rosto 
                  "Width" : 332
               }
            ],
            "Method" : 15,                   // Método usado na autenticação
            "ReaderID" : "1",                // Leitor usado na autenticação
            "Similarity" : 98,
            "SnapPath" : "\/var\/tmp\/partsnap8.jpg",
            "Status" : 1,                    // Status do acesso Liberado/Negado
            "Type" : "Entry",                // Tipo de Acesso Entrada/Saida
            "UTC" : 1581098928,              // UTC do acesso
            "UserID" : "6",                  // ID do Usuário
            "UserType" : 0                   // Tipo de usuário 
         },
         "Index" : 0,
         "PhysicalAddress" : "bc:32:5f:6d:46:d9"
      }
   ],
   "FilePath" : "\/mnt\/appdata1\/userpic\/SnapShot\/2020-02-07\/15\/08\/6_98_100_20200207150848425.jpg",
   "Time" : "07-02-2020 15:08:48"            // Data e hora do evento. 
}

```

#### Exemplos de Servidor

{% tabs %}
{% tab title="Python" %}

```python
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from os.path import abspath, dirname, join
import json
import os
import time
from bottle import route, request, response, run
 
save_dir = join(dirname(abspath(__file__)), "s_files")
 
save_raw_dir = join(dirname(abspath(__file__)), "s_raw_files")
 
@route('%s' % '/events', method='POST')
def do_upload():
    raw_data = request.body.read()
    raw_name = "raw_data_%s.txt" % time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime())
    with open(join(save_raw_dir, raw_name), "ab") as fp:
        fp.write(raw_data)
 
    data_list = raw_data.split(b"--myboundary\r\n")
    if data_list:
        for a_info in data_list:
            if b"Content-Type" in a_info:
                lines = a_info.split(b"\r\n")
                a_type = lines[0].split(b": ")[1]
 
                if a_type == b"image/jpeg":
                    a_name = "abc_%s.jpg" % time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime())
                    with open(join(save_dir, a_name), "wb") as fp:
                        data = b"\r\n".join(lines[3:-3])
                        fp.write(data)
                else:
                    a_name = "abc_%s.txt" % time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime())
                    with open(join(save_dir, a_name), "wb") as fp:
                        data = b"\r\n".join(lines[3:-1])
                        fp.write(data)
 
    # for file_name in request.files.keys():
    #      upload = request.files.get(file_name)
    #      save_path = join(dirname(abspath(__file__)), "s_files", file_name)
    #      if os.path.exists(save_path):
    #          os.remove(save_path)
    #      upload.save(save_path)  # appends upload.filename automatically
    return 'OK'
 
 
run(host='127.0.0.1', port=3000, debug=True)
```

{% endtab %}

{% tab title="Javascript" %}

```javascript
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
 
 
app.use(bodyParser.raw({ type: 'multipart/mixed' }));
 
app.post('/', (req, res) => {
let raw_data = req.body;
 
let data_list = raw_data.toString().split("--myboundary\r\n");
if (data_list) {
  for (let a_info of data_list) {
     if (a_info.includes("Content-Type")) {
     let lines = a_info.split("\r\n");
     let a_type = lines[0].split(": ")[1];
 
     if (a_type == "image/jpeg") {
        //pass
     } else {
        let data =lines.slice(3, -1).join("\r\n");
        console.log(data);
     }
     }
  }
}
 
res.send('OK');
});
 
app.listen(3000, '192.168.3.14', () => {
console.log('Servidor ouvindo na porta 3000 e IP 192.168.3.14!');
});
```

{% endtab %}
{% endtabs %}

### Comando para Limpar Eventos em Cache

Caso você possua muitos eventos, tanto no modo servidor de envio de eventos quanto no modo online que não foi feito a confirmação de envio ao servidor e deseja apagar todos os eventos em cache, você pode utilizar o comando abaixo.

#### Requisição - GET

<mark style="color:green;">`GET`</mark>`http://19.168.3.87/cgi-bin/recordUpdater.cgi?action=clear&name=AccessOffline`

| param      | type   | description         |
| ---------- | ------ | ------------------- |
| `clear` \* | String | Comando para Limpar |

#### Exemplo de Retorno - *text/plain*:

```sh
OK
```

#### Exemplos de Servidor

{% tabs %}
{% tab title="Python" %}

```python
import requests

device_ip = '10.1.35.144'
username = 'admin'
password = 'acesso1234'

url = "http://{}/cgi-bin/recordUpdater.cgi?action=clear&name=AccessOffline".format(
                         str(device_ip),
                     )

digest_auth = requests.auth.HTTPDigestAuth(username, password)
rval = requests.get(url, auth=digest_auth, stream=True, timeout=20, verify=False)

print(rval.text)
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://portal-integracao.intelbras.com.br/catracas-ct-3000-2pb/obtendo-eventos-em-tempo-real/servidor-de-envio-de-eventos.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
