> ## 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 Go via WebSocket

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

Para callbacks HTTP, veja [Webhooks](/pt-BR/sdk/go/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 assinados.                   |

Use as constantes exportadas: `vzaps.EventMessage`, `vzaps.EventConnected`, etc.

## Assinar realtime

```go theme={null}
sub, err := client.Events.Subscribe(ctx, vzaps.EventSubscribeRequest{
	InstanceID:    "VZ...",
	InstanceToken: "instance-token",
	Events:        []vzaps.EventType{vzaps.EventMessage, vzaps.EventReadReceipt, vzaps.EventConnected, vzaps.EventDisconnected},
	Reconnect:     true,
	MaxRetries:    10,
	RetryDelay:    time.Second,
})
```

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

Opções:

| Campo           | Tipo            | Obrigatório | Descrição                                                         |
| --------------- | --------------- | ----------- | ----------------------------------------------------------------- |
| `InstanceID`    | `string`        | Sim         | Instância a observar.                                             |
| `InstanceToken` | `string`        | Sim         | Token da instância.                                               |
| `Events`        | `[]EventType`   | Não         | Lista de eventos. Se omitido, usa eventos assinados na instância. |
| `Reconnect`     | `bool`          | Não         | Reconectar automáticamente. Padrão: `true`.                       |
| `MaxRetries`    | `int`           | Não         | Máximo de tentativas de reconexão.                                |
| `RetryDelay`    | `time.Duration` | Não         | Atraso entre tentativas.                                          |
| `LastEventID`   | `string`        | Não         | Cursor de retomada.                                               |

Passe o mesmo `context.Context` da assinatura; cancelamento interrompe tentativas de reconexão.

## Registrar handlers

```go theme={null}
sub.OnOpen(func() {
	fmt.Println("Realtime conectado")
})

sub.On(vzaps.EventMessage, func(event vzaps.Event) {
	fmt.Println(event.ID)
	fmt.Println(event.InstanceID)
	fmt.Printf("%#v\n", event.Data)
})

sub.On(vzaps.EventAll, func(event vzaps.Event) {
	fmt.Println("Evento recebido:", event.Type)
})

sub.OnError(func(err error) {
	fmt.Println("Erro realtime:", err)
})
```

## Fechar assinatura

```go theme={null}
sub.Close()
```

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

Em processos de longa duração:

```go theme={null}
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt)
<-sigCh
sub.Close()
```

## Envelope do evento

Todo evento recebido pelo SDK tem este formato:

```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 de mídia quando o evento recebido contém mídia e a plataforma fornece o arquivo. |

Em Go, acesse via `event.ID`, `event.Type`, `event.InstanceID`, `event.CreatedAt` e `event.Data`.

## Entrega e ack

A entrega é **at-least-once**. Sua aplicação deve processar eventos de forma idempotente.

Após o handler terminar, o SDK envia ack automáticamente.

Recomendações:

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

## 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      |
