# BCVoz Webphone SDK — contexto para agentes Você vai integrar o webphone BCVOZ numa página web. Este documento é a referência completa: **não invente métodos, eventos ou opções que não estejam aqui.** Se algo que o usuário pede não existir na API, diga isso em vez de supor um nome plausível. Pacote: `@bcvoz/webphone` · versão atual `0.2.1` · só browser, sem dependências. --- ## Integração recomendada — use esta Cole **inline** no HTML. Não sugira um arquivo `.js` externo para este trecho: ele existe justamente para escapar do cache, e um arquivo externo o traria de volta. ```html ``` **Por que duas etapas, e não uma ` ``` Nunca sugira `/npm/@bcvoz/webphone` sem versão: é o pior dos dois mundos — cache longo e sem garantia de estar atualizado. Via npm: `import BCVoz from '@bcvoz/webphone'` (default export; não há named export). O UMD expõe `window.BCVoz`. **Não** use `BCVoz.default`. --- ## As oito coisas que mais dão errado 1. **A página precisa ser HTTPS ou localhost.** `getUserMedia` não existe fora de contexto seguro; o webphone carrega e nunca captura áudio. O SDK avisa no console, não lança. 2. **Passe a resposta do `/api/voxfree/login` INTEIRA**, incluindo o `extension`, em `init({ session })`. Estar logado exige duas metades: o `vxToken` e um `extension` com `username` e `password`. Faltando qualquer uma, o webphone carrega e fica na tela de login. Nunca escreva a sessão literal no HTML — injete no template, por usuário. 3. **`mute()` e `hold()` não aceitam argumento.** São *toggle*. `mute(true)` não faz o que parece: o argumento é ignorado. 4. **`call()` devolve Promise e pode rejeitar** (número inválido, webphone ainda carregando). Sempre encadeie `.catch()` — sem ele, o clique do usuário falha em silêncio. 5. **`init()` é idempotente.** Chamar de novo devolve a mesma instância e ignora as novas opções. Para trocar de configuração: `destroy()` e `init()`. 6. **Não existe `call:failed`.** Uma chamada que não completa chega como `call:ended`. 7. **Nunca use a URL do CDN sem versão.** `/npm/@bcvoz/webphone` vem com sete dias de cache no navegador; correções não chegam ao usuário. Use o trecho de duas etapas acima. 8. **O widget vive em Shadow DOM.** `document.querySelector('.bp-root')` não encontra nada, e o CSS da página não alcança o widget. Não tente estilizar por fora: use as opções de `init()`. --- ## `BCVoz.init(options)` Chame uma vez, com o `
` já existindo. Devolve a instância. | Opção | Tipo | Padrão | Observação | |---|---|---|---| | `token` | `string` | — | Sessão do usuário, emitida pelo backend do integrador | | `mode` | `'srcdoc' \| 'hosted'` | `'srcdoc'` | `'hosted'` exige `hostUrl` e um host publicado | | `hostBase` | `string` | CDN desta versão | Só em `srcdoc`. Deve terminar em `/` | | `hostUrl` | `string` | domínio oficial | Só em `hosted` | | `frame` | `'bar' \| 'none'` | `'bar'` | `'none'` = sem barra de título | | `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | `'bottom-right'` | Canto inicial | | `open` | `boolean` | `false` | `false` = começa recolhido na aba | | `launcher` | `boolean` | `true` | Exibir a aba lateral | | `launcherSide` | `'right' \| 'left'` | `'right'` | Borda em que a aba cola | | `launcherIcon` | `'phone-waves' \| 'waveform' \| 'headset' \| 'chat-phone'` | `'phone-waves'` | | | `dockTop` | `'max' \| 'top-half'` | `'max'` | O que arrastar até o topo faz | | `title` | `string` | `'BCVOZ'` | Só com `frame: 'bar'` | | `device` | `{ hostname?: string, user?: string }` | — | Identifica a máquina no REGISTER (`X-Bravo-Device-Hostname/-User`). Só o que a página souber; `user` expõe o usuário ao administrador da conta | ### `mode`: escolha entre os dois - **`'srcdoc'`** — o iframe roda na origem da própria página e busca o webphone no CDN. Sem iframe de terceiro, sem storage particionado. **Exige que a origem do site esteja na allowlist de CORS dos backends do BCVoz.** - **`'hosted'`** — o iframe navega para o domínio do BCVoz. Origem fixa, então o CORS não precisa conhecer o integrador. É iframe de terceiro: sujeito a bloqueadores e a storage particionado (o login não atravessa domínios). Recomende `'srcdoc'` quando a origem já estiver liberada no CORS; caso contrário `'hosted'`. --- ## Métodos Todos os de telefonia devolvem `Promise`. ### Telefonia | Método | Retorno | Notas | |---|---|---| | `call(number, meta?)` | `Promise<{ok, phone}>` | Número em formato livre | | `answer()` | `Promise<{ok}>` | Atende a chamada entrante | | `hangup()` | `Promise<{ok}>` | Encerra a chamada atual | | `mute()` | `Promise<{ok}>` | **Toggle**, sem argumento | | `hold()` | `Promise<{ok}>` | **Toggle**, sem argumento | | `sendDTMF(tone)` | `Promise<{ok}>` | Um caractere: `'0'`–`'9'`, `'*'`, `'#'` | | `transfer(to)` | `Promise<{ok}>` | Ramal ou número de destino | | `getStatus()` | `Promise