Integração via iFrame
Guia completo para incorporar a plataforma LeoRad em sua aplicação web usando iFrame, com suporte a comunicação bidirecional em tempo real.
#1. Visão Geral
Este guia tem como objetivo orientar, de forma clara e objetiva, a integração da plataforma LeoRad com aplicações web de terceiros.
A plataforma LeoRad (app.leorad.com.br) foi desenvolvida para analisar, processar e interagir com laudos radiológicos por meio de assistentes de inteligência artificial treinados especificamente para o domínio da radiologia.
Seu principal propósito é permitir que o radiologista concentre-se na análise das imagens, reduzindo o tempo gasto na documentação dos exames e aumentando a eficiência do fluxo de trabalho.
O LeoRad oferece diferentes formas de integração com aplicações externas. Este guia detalha a integração via iFrame — indicada para sistemas web — que permite incorporar a plataforma diretamente na interface do seu sistema, com suporte a comunicação bidirecional em tempo real via postMessage.
#2. Autenticação: Entendendo o Token
Cada usuário da aplicação precisa de um token de acesso exclusivo para utilizar a plataforma LeoRad. Esse token é necessário para autenticar e identificar o usuário em todas as chamadas à aplicação.
Como obter o token
#3. Acessando a Aplicação Web
Para acessar a aplicação web do LeoRad, é utilizado um endpoint HTTPS formado pela URL base da aplicação concatenada ao token do usuário:
https://app.leorad.com.br/<TOKEN><TOKEN> pelo token exclusivo do usuário. Cada usuário possui um token individual e intransferível.Importante: O token é exclusivo para cada usuário e não pode ser compartilhado com outros usuários.
#4. Parâmetros Opcionais
É possível utilizar parâmetros de query string para personalizar a experiência do usuário diretamente pelo endpoint. Os parâmetros são opcionais e podem ser combinados conforme necessário:
https://app.leorad.com.br/<TOKEN>?part=XXX&mod=YYY&ind=ZZZ&med=WWW&sex=F&age=45&age-unit=years&prior=Urgente&contrast=true| Parâmetro | Descrição | Exemplo |
|---|---|---|
| ind ou indication | Permite enviar a indicação clínica do caso. O conteúdo será automaticamente inserido no campo de prompt do LeoRad, sem necessidade de digitação manual pelo radiologista. Também aceito com o nome indication. | ind=Dor+abdominal |
| part ou body-part | Aplica um filtro automático nas máscaras e autotextos do usuário, segmentando por parte do corpo examinada. Também aceito com o nome body-part. | part=abdome |
| mod ou model | Carrega um modelo ou template HTML diretamente no editor. O conteúdo deste parâmetro deve estar codificado com URL encoding (encodeURIComponent). Também aceito com o nome model. | mod=%3Ch1%3ETemplate%3C%2Fh1%3E |
| modz | Idêntico ao parâmetro mod, com a diferença de que o conteúdo deve ser compactado com a biblioteca lz-string (usando decompressFromEncodedURIComponent) antes de ser inserido na URL. Indicado para templates de grande tamanho. Veja o exemplo de uso da biblioteca lz-string abaixo. | modz=... |
| mea ou measures | Permite enviar medidas do exame como contexto para a criação do laudo. O conteúdo deste parâmetro deve estar codificado com URL encoding (encodeURIComponent). Também aceito com os nomes measures e mea. | mea=Rim+direito%3A+10cm |
| meaz | Idêntico ao parâmetro mea, com a diferença de que o conteúdo deve ser compactado com a biblioteca lz-string (usando decompressFromEncodedURIComponent) antes de ser inserido na URL. Indicado para conteúdos com muitas medidas. Veja o exemplo de uso da biblioteca lz-string abaixo. | meaz=... |
| sex | Sexo do paciente. Reconhece M (masculino), F (feminino) e O (outro), exibidos por extenso no idioma do usuário. Qualquer outro valor é exibido exatamente como foi enviado. | sex=F |
| age | Idade do paciente. Combine com age-unit para que a idade apareça por extenso; sozinho, o número é exibido como veio. | age=45 |
| age-unit | Unidade da idade: years, months ou days. Não aparece como item próprio — completa o valor de age (ex.: "45 anos"). | age-unit=years |
| prior | Prioridade do estudo. Texto livre, exibido exatamente como foi enviado. | prior=Urgente |
| cont ou contrast | Uso de contraste. Os valores true e false são exibidos como "Sim" e "Não"; qualquer outro valor é exibido como veio. Também aceito com o nome cont. | cont=true |
| cont-det ou contrast-details | Detalhes do uso de contraste. Não aparece como item próprio — completa o valor de contrast (ex.: "Sim — 10ml de gadolínio"). Também aceito com o nome cont-det. | cont-det=10ml+de+gadol%C3%ADnio |
| prev-exam | Exames pregressos do paciente. Texto livre, exibido exatamente como foi enviado. O conteúdo deve estar codificado com URL encoding (encodeURIComponent). | prev-exam=TC+de+abdome+em+2024 |
| prev-report | Laudo anterior do paciente, útil como contexto para comparação. Texto livre, exibido exatamente como foi enviado. O conteúdo deve estar codificado com URL encoding (encodeURIComponent). | prev-report=F%C3%ADgado+de+dimens%C3%B5es+normais... |
mod, modz, mea e meaz antes de incluí-los na URL. Utilize encodeURIComponent() no JavaScript ou o equivalente na linguagem do seu backend.Parâmetros personalizados
A lista acima não é um limite: qualquer chave e valor enviados na query string são aceitos e preservados. Chaves fora da tabela são exibidas ao radiologista com o próprio nome da chave como rótulo, o que permite levar dados do seu sistema — número do acesso, modalidade, equipamento — sem precisar de uma nova versão da integração.
https://app.leorad.com.br/<TOKEN>?accessionNumber=ACC-99123&modality=US&equipamento=GE+Logiq+E10Como os parâmetros chegam ao radiologista
Tudo o que for enviado aparece no painel Parâmetros, no cabeçalho da aplicação. Cada item tem uma caixa de seleção: marcada, o conteúdo é inserido na caixa de mensagem; desmarcada, o conteúdo é retirado — sem alterar o que o radiologista já digitou ou ditou.
ind já chega marcado, então a indicação clínica continua sendo inserida sozinha, como sempre foi. part, além de filtrar máscaras e autotextos, também é inserido automaticamente quando o usuário não desativou a importação automática. Os demais parâmetros ficam disponíveis e são inseridos apenas quando o radiologista marca.Exemplo de uso da biblioteca lz-string (parâmetros modz e meaz)
import LZString from "lz-string";
// Conteúdo original (template HTML ou medidas)
const template = "<h1>Laudo de Ultrassonografia</h1><p>Normal</p>";
const medidas = "Rim direito: 10,5cm | Rim esquerdo: 11cm";
// Compactar com lz-string
const modz = LZString.compressToEncodedURIComponent(template);
const meaz = LZString.compressToEncodedURIComponent(medidas);
// Montar a URL final
const url = `https://app.leorad.com.br/${token}?modz=${modz}&meaz=${meaz}`;npm install lz-string ou yarn add lz-string. No lado do LeoRad, o conteúdo será descompactado automaticamente com LZString.decompressFromEncodedURIComponent().#5. Integração via iFrame e Comunicação Bidirecional
A aplicação LeoRad pode ser incorporada em qualquer sistema web por meio de um <iframe>, permitindo uma integração transparente e rápida com sua interface existente.
O LeoRad utiliza a API window.postMessage para comunicação entre a aplicação pai (parent) e o iframe, possibilitando a troca de dados em tempo real e o controle da aplicação incorporada.
Código de incorporação
<iframe
allow="clipboard-write; microphone; fullscreen; encrypted-media"
src="https://app.leorad.com.br/<TOKEN>"
width="100%"
height="100%"
style="border: none;"
></iframe>Instruções de integração
- 1Substitua
<TOKEN>pelo token exclusivo do usuário autenticado em sua aplicação. - 2Os parâmetros opcionais
part,modeindpodem ser incluídos diretamente na URL do atributosrc. - 3Ajuste os atributos
widtheheightconforme necessário para se adaptar ao layout do seu sistema. - 4Personalize o estilo do iframe (bordas, sombras, arredondamento) para que ele se integre harmoniosamente à interface da sua aplicação.
Eventos postMessage disponíveis
O LeoRad suporta os seguintes eventos para comunicação bidirecional entre a aplicação pai e o iframe:
| Evento | Direção | Descrição |
|---|---|---|
| setContent | parent → iframe | Define o conteúdo HTML no editor do iFrame, substituindo completamente o conteúdo existente. |
| insertContent | parent → iframe | Insere conteúdo na posição atual do cursor no editor do iFrame, sem substituir o conteúdo existente. |
| getContent | parent → iframe | Solicita o conteúdo HTML atual do editor. Aceita o campo finish para sinalizar a finalização do laudo e acionar fluxos na aplicação pai. |
| setMeasures | parent → iframe | Envia para o LeoRad medidas para serem utilizadas na criação do laudo. |
| setBodyPart | parent → iframe | Envia a parte do corpo examinada — mesmo efeito do parâmetro de URL part (filtro de máscaras/autotextos e importação automática). |
| setSex | parent → iframe | Envia o sexo do paciente. Reconhece M, F e O, exibidos por extenso no idioma do usuário. |
| setAge | parent → iframe | Envia a idade do paciente. Aceita um valor simples (data: '45') ou um objeto { age, "age-unit" } com a unidade (years, months ou days). |
| setPriority | parent → iframe | Envia a prioridade do estudo (parâmetro prior). Texto livre. |
| setContrast | parent → iframe | Envia o uso de contraste. Aceita um valor simples (data: 'true') ou um objeto { contrast, "contrast-details" } com os detalhes. |
| setPrevExam | parent → iframe | Envia os exames pregressos do paciente (parâmetro prev-exam). |
| setPrevReport | parent → iframe | Envia o laudo anterior do paciente (parâmetro prev-report). Conteúdo em HTML é convertido para texto puro. |
| setCommand | parent → iframe | Executa um comando customizado. As frases aceitas dependem do idioma definido pela preferência do usuário. |
| loaded | iframe → parent | Emitido pelo iFrame para indicar que a aplicação LeoRad terminou de carregar e está pronta para receber interações. |
Commands disponíveis
Para o evento setCommand, os comandos aceitos incluem:
| Exemplos de comandos |
|---|
| Inicia ditado por IA (turbo). |
| Pausa ditado IA. |
| Retoma ditado IA. |
| Para ditado IA. |
| Inicia ditado convencional (realtime). |
| Para ditado convencional. |
| Inicia assistente de voz. |
| Pausa assistente. |
| Retoma assistente. |
| Para assistente. |
| Exporta/finaliza o laudo (copia ou envia ao parent). |
| Copia o laudo para o clipboard. |
| Cola conteúdo do clipboard no editor. |
| Recorta o laudo (copia + limpa editor). |
| Apaga o conteúdo do editor. |
| Busca autotexto/máscara pelo nome falado e insere no editor. |
Como usar via postMessage
O campo data enviado no evento setCommand deve ser o texto da frase/comando. O handleCommand faz o match por frase, não pelo nome técnico do comando.
const iframe = document.querySelector('iframe');
const LEORAD_ORIGIN = 'https://app.leorad.com.br';
// Define o conteúdo HTML no editor (substitui o conteúdo atual)
iframe.contentWindow.postMessage(
{ action: 'setContent', data: '<p>Conteúdo do laudo</p>' },
LEORAD_ORIGIN
);
// Solicita o conteúdo atual do editor
iframe.contentWindow.postMessage(
{ action: 'getContent' },
LEORAD_ORIGIN
);
// Envia medidas para contexto do laudo
iframe.contentWindow.postMessage(
{ action: 'setMeasures', data: 'Rim direito: 10 cm; Rim esquerdo: 10,5 cm' },
LEORAD_ORIGIN
);
// Demais parâmetros de contexto (mesmo destino dos parâmetros de URL):
// setBodyPart, setSex, setAge, setPriority, setContrast, setPrevExam, setPrevReport
iframe.contentWindow.postMessage(
{ action: 'setBodyPart', data: 'USG Abdome Total' },
LEORAD_ORIGIN
);
// setAge aceita a unidade junto ('age-unit' é opcional; valor solto também vale)
iframe.contentWindow.postMessage(
{ action: 'setAge', data: { age: '45', 'age-unit': 'years' } },
LEORAD_ORIGIN
);
// setContrast aceita os detalhes junto ('contrast-details' é opcional)
iframe.contentWindow.postMessage(
{ action: 'setContrast', data: { contrast: 'true', 'contrast-details': '10 ml de gadolínio' } },
LEORAD_ORIGIN
);
// Executa comando customizado por frase/comando textual
iframe.contentWindow.postMessage(
{ action: 'setCommand', data: 'Iniciar assistente' },
LEORAD_ORIGIN
);#5.1 Como emitir eventos para o iFrame LeoRad
Para enviar mensagens da sua aplicação ao iFrame do LeoRad, utilize o método postMessage na referência ao elemento iframe:
const iframe = document.querySelector('iframe');
const LEORAD_ORIGIN = 'https://app.leorad.com.br';
// Define o conteúdo HTML no editor (substitui o conteúdo atual)
iframe.contentWindow.postMessage(
{ action: 'setContent', data: '<p>Conteúdo do laudo</p>' },
LEORAD_ORIGIN
);
// Insere conteúdo na posição atual do cursor
iframe.contentWindow.postMessage(
{ action: 'insertContent', data: 'Texto a ser inserido' },
LEORAD_ORIGIN
);
// Solicita o conteúdo atual do editor
iframe.contentWindow.postMessage(
{ action: 'getContent' },
LEORAD_ORIGIN
);
// Solicita o conteúdo e sinaliza finalização do laudo
iframe.contentWindow.postMessage(
{ action: 'getContent', finish: true },
LEORAD_ORIGIN
);'https://app.leorad.com.br') como segundo argumento do postMessage em vez de usar '*'. Isso garante que a mensagem seja entregue exclusivamente ao domínio correto.#5.2 Como receber eventos do iFrame LeoRad
Quando o radiologista finalizar o laudo, o conteúdo será automaticamente enviado para a aplicação pai via postMessage. Outros eventos, como o carregamento inicial do iFrame, também podem ser capturados por meio de um event listener no window:
window.addEventListener('message', function(event) {
// IMPORTANTE: sempre valide a origem da mensagem antes de processá-la
if (event.origin !== 'https://app.leorad.com.br') return;
const { action, data } = event.data || {};
switch (action) {
case 'loaded':
// O iFrame do LeoRad terminou de carregar e está pronto
console.log('LeoRad carregado com sucesso');
break;
case 'getContent':
// Conteúdo do editor retornado em formato HTML
console.log('Conteúdo do laudo:', data);
// Processe o conteúdo conforme a necessidade da sua aplicação
break;
default:
console.log('Evento recebido:', action, data);
}
}, false);#6. Segurança
event.origin antes de processar qualquer mensagem recebida. Isso garante que a comunicação ocorra exclusivamente com domínios confiáveis e evita a execução de scripts maliciosos.Allowlist de origens (aplicações parent)
Para garantir maior segurança na integração, a equipe LeoRad solicita que você forneça a lista de URLs (origens) das aplicações que irão incorporar o iFrame. Essas URLs serão configuradas em uma lista de permissões (allowlist), restringindo o carregamento do conteúdo exclusivamente aos domínios autorizados.
Essa medida protege contra acessos não autorizados e garante a integridade da comunicação entre o iFrame e a aplicação integradora.
Exemplos de origens a serem fornecidas
https://app.suaempresa.com.br
https://radiologia.xyz.com#7. Exemplo Funcional
O exemplo a seguir demonstra uma integração completa em HTML e JavaScript puro, pronta para ser adaptada ao seu ambiente de desenvolvimento ou utilizada como ponto de partida para testes.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Integração LeoRad via iFrame</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: sans-serif; display: flex; flex-direction: column; height: 100vh; }
header { padding: 12px 16px; background: #111827; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
button {
padding: 8px 16px; border-radius: 6px; border: none;
background: #ef4444; color: white; cursor: pointer;
font-size: 13px; font-weight: 500;
}
button:hover { background: #dc2626; }
#leorad { flex: 1; border: none; width: 100%; }
</style>
</head>
<body>
<header>
<button onclick="setContent()">Definir Conteúdo</button>
<button onclick="insertContent()">Inserir Conteúdo</button>
<button onclick="getContent()">Obter Conteúdo</button>
<button onclick="setMeasures()">setMeasures</button>
<button onclick="setBodyPart()">setBodyPart</button>
<button onclick="setSex()">setSex</button>
<button onclick="setAge()">setAge</button>
<button onclick="setPriority()">setPriority</button>
<button onclick="setContrast()">setContrast</button>
<button onclick="setPrevExam()">setPrevExam</button>
<button onclick="setPrevReport()">setPrevReport</button>
</header>
<iframe
id="leorad"
allow="clipboard-write; microphone; fullscreen; encrypted-media"
src="https://app.leorad.com.br/<TOKEN>"
></iframe>
<script>
const iframe = document.getElementById('leorad');
const LEORAD_ORIGIN = 'https://app.leorad.com.br';
function send(payload) {
iframe.contentWindow.postMessage(payload, LEORAD_ORIGIN);
}
function setContent() {
send({ action: 'setContent', data: '<p>Laudo de exemplo inserido via integração.</p>' });
}
function insertContent() {
send({ action: 'insertContent', data: 'Texto inserido na posição do cursor.' });
}
function getContent() {
send({ action: 'getContent' });
}
function setMeasures() {
send({ action: 'setMeasures', data: 'Rim direito: 10 cm; Rim esquerdo: 10,5 cm' });
}
function setBodyPart() {
send({ action: 'setBodyPart', data: 'USG Abdome Total' });
}
function setSex() {
// Valores conhecidos: 'M', 'F', 'O' (outros passam como texto cru)
send({ action: 'setSex', data: 'F' });
}
function setAge() {
// 'age-unit' é opcional ('years', 'months', 'days'); também aceita só o valor: data: '45'
send({ action: 'setAge', data: { age: '45', 'age-unit': 'years' } });
}
function setPriority() {
send({ action: 'setPriority', data: 'Urgente' });
}
function setContrast() {
// 'contrast-details' é opcional; também aceita só o valor: data: 'true'
send({
action: 'setContrast',
data: { contrast: 'true', 'contrast-details': '10 ml de gadolínio' },
});
}
function setPrevExam() {
send({ action: 'setPrevExam', data: 'USG Abdome Total — 12/03/2025' });
}
function setPrevReport() {
send({
action: 'setPrevReport',
data: '<p>Fígado de dimensões normais, contornos regulares. Vesícula biliar sem cálculos.</p>',
});
}
window.addEventListener('message', function(event) {
if (event.origin !== LEORAD_ORIGIN) return;
const { action, data } = event.data || {};
if (action === 'loaded') {
console.log('LeoRad carregado e pronto para uso.');
} else if (action === 'getContent') {
console.log('Conteúdo do laudo recebido:', data);
alert('Laudo recebido com sucesso! Verifique o console para visualizar o conteúdo.');
}
}, false);
</script>
</body>
</html>Precisa de ajuda?
Em caso de dúvidas, sugestões ou problemas técnicos relacionados à integração, entre em contato com nossa equipe de suporte.
contato@leorad.com.br