> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vzaps.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Realtime

> Como receber eventos em tempo real com o SDK Python via WebSocket

Use `client.events` com `AsyncVZapsClient` para receber eventos da instância em tempo real sem expor uma URL pública.

Para callbacks HTTP, veja [Webhooks](/pt-BR/sdk/python/webhooks).

## Eventos comuns

| Evento                    | Descrição                                     |
| ------------------------- | --------------------------------------------- |
| `Message`                 | Nova mensagem recebida ou evento de mensagem. |
| `ReadReceipt`             | Atualização de leitura/entrega.               |
| `Presence`                | Presença do usuário.                          |
| `ChatPresence`            | Presença no chat.                             |
| `HistorySync`             | Sincronização de histórico.                   |
| `Connected`               | Instância conectada ao WhatsApp.              |
| `Disconnected`            | Instância desconectada.                       |
| `GroupParticipantsAdd`    | Participantes adicionados ao grupo.           |
| `GroupParticipantsRemove` | Participantes removidos do grupo.             |
| `All`                     | Todos os eventos inscritos.                   |

## Assinar o realtime

```python theme={null}
import asyncio

from vzaps import AsyncVZapsClient

async def main():
    async with AsyncVZapsClient(
        client_token="seu-client-token",
        client_secret="seu-client-secret",
    ) as client:
        async with client.events.subscribe(
            instance_id="VZ...",
            instance_token="instance-token",
            events=["Message", "ReadReceipt", "Connected", "Disconnected"],
            reconnect=True,
            max_retries=10,
            retry_delay_seconds=1.0,
        ) as subscription:
            await subscription.wait_closed()

asyncio.run(main())
```

**Retorno:** `EventSubscription` — objeto com `on()`, `close()` e reconexao automatica quando configurada.

Opções:

| Campo                 | Tipo        | Obrigatório | Descrição                                                            |
| --------------------- | ----------- | ----------- | -------------------------------------------------------------------- |
| `instance_id`         | `string`    | Sim         | Instância a observar.                                                |
| `instance_token`      | `string`    | Sim         | Token da instância.                                                  |
| `events`              | `list[str]` | Não         | Lista de eventos. Se omitido, usa os eventos inscritos na instância. |
| `reconnect`           | `boolean`   | Não         | Reconecta automaticamente. Padrão: `True`.                           |
| `max_retries`         | `number`    | Não         | Máximo de tentativas de reconexão.                                   |
| `retry_delay_seconds` | `number`    | Não         | Atraso base entre tentativas.                                        |
| `last_event_id`       | `string`    | Não         | Cursor para retomar consumo.                                         |

## Registrar handlers

```python theme={null}
@subscription.on_open
async def on_open():
    print("Realtime conectado")

@subscription.on("Message")
async def on_message(event):
    print(event.id)
    print(event.instance_id)
    print(event.data)

@subscription.on("All")
async def on_all(event):
    print("Evento recebido:", event.type)

@subscription.on_error
async def on_error(error):
    print("Erro no realtime:", error)
```

## Fechar assinatura

```python theme={null}
await subscription.close()
```

**Retorno:** `Promise<void>` apos fechar o WebSocket.

Em processos de longa duração, feche no shutdown:

```python theme={null}
import signal

def shutdown():
    asyncio.create_task(subscription.close())

signal.signal(signal.SIGINT, lambda *_: shutdown())
```

## Envelope do evento

Cada evento recebido pelo SDK tem esta forma:

```json theme={null}
{
  "id": "evt_01J...",
  "type": "Message",
  "instance_id": "VZ...",
  "created_at": "2026-06-23T22:57:17.000Z",
  "data": {
    "type": "Message",
    "media_url": "https://cdn.example.com/media/image.jpg"
  }
}
```

Campos:

| Campo            | Descrição                                                                            |
| ---------------- | ------------------------------------------------------------------------------------ |
| `id`             | Identificador do evento. Use para deduplicação.                                      |
| `type`           | Tipo do evento.                                                                      |
| `instance_id`    | Instância de origem.                                                                 |
| `created_at`     | Data de criação do evento.                                                           |
| `data`           | Payload do evento.                                                                   |
| `data.media_url` | URL da mídia quando o evento recebido contém mídia e a plataforma fornece o arquivo. |

## Entrega e ack

A entrega é **at-least-once**. Sua app deve processar eventos de forma idempotente.

Após o handler terminar, o SDK envia o ack automaticamente.

Recomendações:

* guarde `event.id` se sua automação executa efeitos externos;
* ignore eventos já processados;
* use `last_event_id` ao reconectar para reduzir lacunas;
* mantenha handlers rápidos e mova trabalho longo para sua própria fila.

## Realtime ou webhook?

| Cenário                                    | Recomendação |
| ------------------------------------------ | ------------ |
| Bot, dashboard ou app com consumo imediato | Realtime     |
| Backend com URL pública e pipeline HTTP    | Webhook      |
| Não quer expor URL pública                 | Realtime     |
| Precisa reprocessar entregas via logs      | Webhook      |
