# Doxy.me Embeddable SDK

Easily embed doxy.me into your application using iframes.

```bash
npm install doxy.me
```

> **What's new in 1.2.x**
>
> - **1.2.1** — **`patientId`** on `embedPatientRoom` — forwarded as `?pid=…` for EHR / external correlation (V1 + V2). See [Patient identifier (`pid`)](#patient-identifier-pid).
> - **1.2.0** — `version: 'v1' | 'v2'` on the helpers — opt into the new V2 frontend (`/v2/sign-in`, `/v2/check-in/{slug}`)
> - **1.2.0** — `baseUrl` override — point at staging / QA / ephemeral environments
> - **1.2.0** — `username`, `autoCheckIn`, `passcode` first-class options on `embedPatientRoom` for headless patient flows
> - Patch releases remain **fully backwards compatible** — defaults match 1.1.0 behaviour

## Usage

### Basic

Embed any doxy.me URL:

```javascript
import { embedDoxyMe } from 'doxy.me';

const { iframe, destroy } = embedDoxyMe('#doxy-container', {
  url: 'https://doxy.me/sign-in',
  width: '100%',
  height: '600px',
});

// destroy(); // when done
```

### Provider sign-in

```javascript
import { embedProviderSignIn } from 'doxy.me';

embedProviderSignIn('#doxy-container', {
  width: '100%',
  height: '700px',
});
```

By default this embeds the **legacy V1 frontend** (`/sign-in`). To embed the new V2 frontend instead:

```javascript
embedProviderSignIn('#doxy-container', {
  version: 'v2',          // → https://doxy.me/v2/sign-in
  width: '100%',
  height: '700px',
});
```

### Patient room

```javascript
import { embedPatientRoom } from 'doxy.me';

embedPatientRoom('#doxy-container', 'patient-room-123', {
  width: '100%',
  height: '800px',
});
```

V2 supports nested room slugs (e.g. `clinic/room`):

```javascript
embedPatientRoom('#doxy-container', 'ourclinic/myles', {
  version: 'v2',          // → https://doxy.me/v2/check-in/ourclinic/myles
});
```

### Headless / auto check-in

Pre-fill the patient's name and skip the manual check-in steps entirely. The patient lands directly in the provider's waiting room:

```javascript
embedPatientRoom('#doxy-container', 'ourclinic/myles', {
  version: 'v2',
  username: 'Jane Doe',
  autoCheckIn: true,
});
```

URL produced:
`https://doxy.me/v2/check-in/ourclinic/myles?utm_source=embed-sdk&sdk_version=1.2.1&username=Jane%20Doe&autocheckin=true`

> Auto check-in on V1 is supported today. On V2 it requires the autocheckin feature shipped via doxyme-core MR !12913 (post-deploy to QA2 / production).

### Patient identifier (`pid`)

Pass an external patient identifier from your system — typically an EHR record ID — that doxy.me keeps available alongside the session for correlation purposes:

```javascript
embedPatientRoom('#consult', 'clinic/room', {
  version: 'v2',
  username: 'Jane Doe',
  patientId: 'ehr-9876',
  autoCheckIn: true,
});
```

The value is forwarded as `?pid=…` and is opaque to doxy.me. It is not pushed into the realtime channel and never logged in PHI-sensitive contexts. Works on both V1 (legacy OG) and V2 frontends.

### Passcode-protected rooms

If a provider has gated their room with a passcode, pass it alongside `autoCheckIn`. The passcode is auto-validated server-side; if the URL value is wrong (or absent for a passcode-required room), the patient sees the standard passcode-entry UX as a graceful fallback. Provider passcode intent is never bypassed.

```javascript
embedPatientRoom('#doxy-container', 'ourclinic/myles', {
  version: 'v2',
  username: 'Jane Doe',
  autoCheckIn: true,
  passcode: 'secret123',
});
```

### Targeting non-production environments

For staging, QA, or ephemeral environments, override the origin with `baseUrl`.

MR **!12913** (V2 autocheckin) ephemeral with a known-good room (`/mylesanclinic/triage`):

```javascript
embedPatientRoom('#doxy-container', 'mylesanclinic/triage', {
  version: 'v2',
  baseUrl: 'https://core-12913.doxy-ephemeral.me',
  username: 'Jane Doe',
  autoCheckIn: true,
});
```

Other hosts (QA2/CDN Basic Auth often blocks localhost iframes):

```javascript
embedPatientRoom('#doxy-container', 'my-room-slug', {
  version: 'v2',
  baseUrl: 'https://doxy-qa2.me',
  username: 'Jane Doe',
  autoCheckIn: true,
});
```

### Using a CSS selector

```javascript
embedDoxyMe('#doxy-container', { url: 'https://doxy.me/sign-in' });
```

### Advanced options

```javascript
embedDoxyMe('#doxy-container', {
  url: 'https://doxy.me/sign-in',
  width: '100%',
  height: '600px',
  allow: 'camera; microphone; fullscreen',
  className: 'doxy-iframe',
  id: 'doxy-iframe-1',
  style: {
    borderRadius: '8px',
    boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
  },
  onLoad: () => console.log('Doxy.me iframe loaded'),
  onError: (error) => console.error('Error loading doxy.me:', error),
});
```

## Analytics

Every iframe URL includes `utm_source=embed-sdk` and `sdk_version=<version>` automatically. No additional network requests are made — these flow through doxy.me's existing analytics.

You can append your own tracking params via `trackingParams`:

```javascript
embedDoxyMe('#doxy-container', {
  url: 'https://doxy.me/sign-in',
  trackingParams: {
    utm_campaign: 'my-app',
    utm_medium: 'embed',
  },
});
```

`trackingParams` wins on conflicts with built-in keys, so an explicit `utm_source` will override the default.

## API reference

### `embedDoxyMe(container, options)`

Generic iframe embedder.

- `container` (`HTMLElement | string`): DOM element or CSS selector
- `options.url` (string, required): URL to embed
- `options.width` / `options.height` (`string | number`, optional): iframe dimensions (defaults: `'100%'` × `'600px'`)
- `options.allow` (string, optional): iframe `allow` attribute (default: `'camera; microphone; fullscreen'`)
- `options.sandbox` (string, optional): iframe `sandbox` attribute
- `options.className`, `options.id`, `options.style` (optional): standard HTML attributes
- `options.onLoad`, `options.onError` (optional): event callbacks
- `options.trackingParams` (`Record<string, string>`, optional): extra URL params

Returns: `{ iframe: HTMLIFrameElement, destroy: () => void }`

### `embedProviderSignIn(container, options?)`

Embeds the provider sign-in page.

- All `embedDoxyMe` options except `url`
- `options.version` (`'v1' | 'v2'`, optional, default `'v1'`)
- `options.baseUrl` (string, optional, default `'https://doxy.me'`)

### `embedPatientRoom(container, roomSlug, options?)`

Embeds a patient room (waiting room / check-in flow).

- `roomSlug` (string, required): room identifier. V2 supports nested slugs (`clinic/room`).
- All `embedDoxyMe` options except `url`
- `options.version` (`'v1' | 'v2'`, optional, default `'v1'`)
- `options.baseUrl` (string, optional, default `'https://doxy.me'`)
- `options.username` (string, optional): pre-fills the patient's name
- `options.autoCheckIn` (boolean, optional): adds `?autocheckin=true`
- `options.passcode` (string, optional): adds `?passcode=…`
- `options.patientId` (string, optional): adds `?pid=…` (external / EHR correlation id)

## React example

```jsx
import { useEffect, useRef } from 'react';
import { embedPatientRoom } from 'doxy.me';

function PatientEmbed({ roomSlug, patientName }) {
  const ref = useRef(null);

  useEffect(() => {
    if (!ref.current) return;
    const { destroy } = embedPatientRoom(ref.current, roomSlug, {
      version: 'v2',
      username: patientName,
      autoCheckIn: true,
      width: '100%',
      height: '100%',
    });
    return () => destroy();
  }, [roomSlug, patientName]);

  return <div ref={ref} style={{ height: 800 }} />;
}
```

## Vanilla JS example

```html
<!doctype html>
<html>
  <head><title>Doxy.me Embed</title></head>
  <body>
    <div id="doxy-container" style="height: 800px"></div>
    <script type="module">
      import { embedPatientRoom } from 'doxy.me';
      embedPatientRoom('#doxy-container', 'patient-room-123', {
        version: 'v2',
        autoCheckIn: true,
        username: 'Jane Doe',
      });
    </script>
  </body>
</html>
```

## Demo

A runnable Vite + React reference app lives under [`demo/`](./demo). It shows both the provider sign-in and patient autocheckin flows end-to-end against any environment (production, QA2, staging, ephemeral).

```bash
cd demo
cp .env.example .env.local  # then edit VITE_DOXY_BASE_URL
npm install
npm run dev
```

## Development

```bash
npm install
npm run build  # produces dist/index.js, dist/index.esm.js, dist/index.d.ts
```

The package publishes the contents of `dist/` and `README.md` only.

## License

MIT
