# Dora IOBridge Node

Generic WebSocket bridge between web clients and Dora dataflow.

## Dora Outputs (WebSocket → Dora)

| Output      | Type   | Description              |
|-------------|--------|--------------------------|
| `text_out`  | string | Text from clients        |
| `audio_out` | bytes  | WAV audio from clients   |
| `data_out`  | JSON   | Generic data from clients|

## Dora Inputs (Dora → WebSocket)

| Input       | Type   | Description              |
|-------------|--------|--------------------------|
| `text_in`   | string | Text to broadcast        |
| `audio_in`  | bytes  | WAV audio to broadcast   |
| `data_in`   | JSON   | Generic data to broadcast|

## Environment Variables

| Variable  | Default   | Description  |
|-----------|-----------|--------------|
| `WS_HOST` | `0.0.0.0` | Bind address |
| `WS_PORT` | `8765`    | Listen port  |

## WebSocket Endpoint

```text
ws://{WS_HOST}:{WS_PORT}
```

Default: `ws://0.0.0.0:8765`

## WebSocket Protocol

### Client → Server

| Type    | Field     | Description           |
|---------|-----------|-----------------------|
| `text`  | `content` | Text string           |
| `audio` | `content` | Base64-encoded WAV    |
| `data`  | `payload` | Any JSON object       |
| `ping`  | -         | Health check          |

Examples:

```json
{"type": "text", "content": "hello world"}
{"type": "audio", "content": "UklGRi4AAABXQVZFZm10..."}
{"type": "data", "payload": {"key": "value"}}
{"type": "ping"}
```

### Server → Client

| Type    | Field     | Description           |
|---------|-----------|-----------------------|
| `text`  | `content` | Text string           |
| `audio` | `content` | Base64-encoded WAV    |
| `data`  | `payload` | Any JSON object       |
| `pong`  | -         | Response to ping      |
| `error` | `message` | Error description     |

Examples:

```json
{"type": "text", "content": "response text"}
{"type": "audio", "content": "UklGRi4A...", "format": "wav"}
{"type": "data", "payload": {"objects": [...]}}
{"type": "pong"}
{"type": "error", "message": "Invalid JSON"}
```

## Dataflow Example

```yaml
- id: iobridge
  build: uv pip install -e dora_iobridge
  path: dora_iobridge/dora_iobridge/main.py
  env:
    WS_HOST: "0.0.0.0"
    WS_PORT: "8765"
  inputs:
    text_in: voice/voice_out
    data_in: voice/scene_update
  outputs:
    - text_out
```

## Testing

```bash
# Install websocat
sudo apt install websocat

# Connect
websocat ws://localhost:8765

# Send text
{"type": "text", "content": "hello"}

# Ping
{"type": "ping"}
```
