Voltar para Documentação

SDK Web do Reachy

Identifique visitantes, registre contatos e eventos, acompanhe sessões e origens de tráfego e habilite web push no seu site.

Visão geral

Com o SDK instalado, cada visitante do seu site recebe uma identidade persistente, o reachyID. A partir dela o Reachy monta a linha do tempo do contato: páginas vistas, origem da visita, eventos do seu negócio, cadastro, inscrição em web push. Esses dados alimentam Públicos, Jornadas e Campanhas.

Como funciona

  1. Você adiciona um script ao site com o passcode do seu projeto.
  2. O SDK identifica o visitante, abre uma sessão e passa a registrar navegação e origem (UTMs) sozinho.
  3. Quando o visitante se cadastra, o site chama createContact e o visitante vira um contato no Reachy.
  4. Em cada ação importante (formulário concluído, compra, clique em oferta), o site envia um evento com trackEvent.

Tudo chega ao Reachy em segundos e aparece na aba Contacts do projeto.

O que cada chamada vira no Reachy

No siteNo Reachy
createContactUm contato no projeto, com nome, e-mail, telefone, campos customizados e preferências de comunicação por canal
trackEvent e eventos automáticosEventos na linha do tempo do contato, filtráveis em Públicos e usáveis como gatilho em Jornadas
properties do contatoCampos do contato, para filtro e personalização de mensagens
UTMs da visitaOrigem da sessão, enviada em todo evento
identifyVínculo do visitante a um ID do seu sistema
Web pushNavegador do visitante vinculado ao contato como dispositivo
DescadastroPágina de descadastro no seu site que atualiza as preferências do contato

Requisitos

  • Um projeto no Reachy e permissão para criar passcodes.
  • Acesso ao código do site, ou a um gerenciador de tags como o Google Tag Manager.
  • Site em HTTPS (obrigatório para web push; recomendado para o resto).

O SDK pesa cerca de 73 KB, carrega de forma assíncrona e não atrasa a página. Ele funciona em sites estáticos, WordPress, aplicações React, Next.js, Vue e qualquer outra tecnologia que renderize HTML no navegador.

Antes de começar: o passcode

O passcode é a chave que liga o site ao projeto no Reachy. Todo contato e evento enviados com ele caem nesse projeto.

  1. Entre no Reachy e confira no topo que o projeto ativo é o que vai receber os contatos.
  2. Vá em Settings e abra a aba Passcodes.
  3. Clique em Adicionar Passcode, dê um nome que identifique o site (ex.: site-institucional, quiz-cartao), escolha se expira e confirme.
  4. Copie o passcode exibido. Ele aparece uma única vez; se fechar sem copiar, gere outro e apague o anterior.

Boas práticas

  • Um passcode por site ou funil. Assim você desativa um sem afetar os outros e sabe de onde cada contato veio.
  • Guarde o passcode como variável de ambiente do site ou no gerenciador de senhas do time, não em documentos soltos.
  • O passcode vai no HTML da página, portanto é visível para quem inspecionar o site. Ele só permite enviar dados para o projeto, nunca ler. Não o reutilize em servidores ou outras integrações.
  • Para testar sem misturar dados, crie um projeto de testes com o próprio passcode.

Detalhes de criação, expiração e revogação em Passcodes.

Início rápido

Em cerca de 15 minutos o site envia page views sozinho, cadastra um contato e dispara um evento que aparece no Reachy.

1Instale o script

Cole o bloco em todas as páginas, antes do </head>, trocando o passcode pelo do seu projeto.

Snippet de instalação
<script>
  window.reachy = window.reachy || { event: [], config: [], session: [], privacy: [], identify: [], login: [], queue: [] };
  window.reachy.queue.push({ type: 'config', data: {
    passcode: 'YOUR_PASSCODE'
  }});
</script>
<script async src="https://sdk.reachy.io/sdk.js"></script>

Ao carregar, o SDK lê a configuração em window.reachy.queue, cria a instância global window.MySDK e envia o primeiro page_enter.

2Cadastre o contato

No envio do seu formulário, chame reachy.event.push com um objeto. Precisa de e-mail ou telefone.

Cadastro do contato
reachy.event.push({
  email: 'ana@email.com',
  first_name: 'Ana',
  phone: '+5511999999999',
  is_subscribed: true,                       // consent checked on the form
  properties: { source: 'quiz', plan: 'basic' }
});

3Envie um evento

Com um nome e um objeto, a mesma chamada registra um evento na linha do tempo do contato.

Evento customizado
reachy.event.push('Form Completed', {
  source: 'quiz',
  'Has a credit card?': 'Yes'
});

Cadastre o contato antes de enviar o evento de conversão, para o evento já chegar ligado à pessoa.

4Confira

Abra a página com ?reachy_debug=true no final da URL: um painel mostra o reachyID, a sessão e cada evento no momento do envio. No Reachy, em Contacts, o contato aparece em até 1 minuto com os campos e o evento na aba de atividades.

Próximos passos

Ajuste as opções de captura automática em Referência de configuração, ative web push ou integre em Next.js, Google Tag Manager e WordPress em Instalação.

Instalação por plataforma

O snippet do Início rápido funciona em qualquer site. Esta seção mostra onde colocá-lo em cada plataforma e como chamar o SDK a partir de código que roda antes de o script terminar de carregar.

HTML e sites estáticos

Cole o snippet no <head> de todas as páginas (ou no template compartilhado). Chamadas feitas depois do carregamento usam reachy.event.push, reachy.identify.push e as demais filas, ou window.MySDK direto.

Google Tag Manager

  1. Crie uma tag do tipo Custom HTML com o snippet completo.
  2. Dispare em All Pages.
  3. Publique o contêiner. Para cadastrar contatos ou enviar eventos a partir de outras tags, use window.reachy.event.push(...) nelas; a fila garante a ordem.

Next.js e React

Carregue o SDK por um componente único no layout, com o passcode em variável de ambiente. A configuração é aplicada no onload do script via MySDK.updateConfig.

components/ReachyScripts.tsx
"use client";
import Script from "next/script";

export default function ReachyScripts({ passcode }: { passcode?: string }) {
  if (!passcode) return null;

  const config = { passcode, trackClicks: false };
  const loader = `
    window.reachy = window.reachy || { event: [], config: [], session: [], privacy: [], identify: [], login: [], queue: [] };
    var s = document.createElement('script');
    s.async = true;
    s.src = 'https://sdk.reachy.io/sdk.js';
    s.onload = function () { window.MySDK.updateConfig(${JSON.stringify(config)}); };
    document.head.appendChild(s);
  `;
  return <Script id="reachy-sdk" strategy="afterInteractive" dangerouslySetInnerHTML={{ __html: loader }} />;
}

No layout: <ReachyScripts passcode={process.env.NEXT_PUBLIC_REACHY_PASSCODE} />.

Em componentes, não chame window.reachy direto. Use um helper que espera o SDK ficar pronto (window.MySDK.initialized) e envie o evento de conversão depois do cadastro:

lib/reachy.ts
declare global { interface Window { MySDK?: any } }

// Runs fn as soon as the SDK is loaded and initialized
export function whenReady(fn: (sdk: any) => void) {
  if (typeof window === 'undefined') return;
  if (window.MySDK?.initialized) return fn(window.MySDK);
  const timer = setInterval(() => {
    if (window.MySDK?.initialized) { clearInterval(timer); fn(window.MySDK); }
  }, 50);
}

// Contact first, conversion event second
whenReady((sdk) => sdk.createContact({ email, first_name: firstName, is_subscribed: true }));
whenReady((sdk) => sdk.trackEvent('Form Completed', { source: 'quiz' }));

Vue, Angular e outros frameworks

O mesmo padrão: carregue https://sdk.reachy.io/sdk.js uma vez na inicialização da aplicação, aplique a configuração no onload com window.MySDK.updateConfig({ passcode }) e use window.MySDK nos componentes. Em aplicações de página única (SPA), o SDK detecta a troca de rota pela History API e envia page_enter a cada tela sem código extra.

WordPress e Elementor

O script precisa rodar em todas as páginas, então o lugar certo é o <head> do site, não um widget dentro de uma página. Escolha um dos caminhos e use sempre o mesmo snippet.

CaminhoRequerCobre
Elementor > Custom CodeElementor ProSite inteiro. Recomendado.
Plugin WPCode > Header & FooterPlugin gratuitoSite inteiro.
Widget HTML na páginaNadaSó aquela página. Use apenas para testes.

A primeira linha do snippet abaixo evita registrar visitas dentro do editor do Elementor, cuja URL de pré-visualização contém elementor-preview. Informe o domínio raiz em cookieDomain para o visitante ser o mesmo em www, loja. e blog..

Snippet para WordPress
<!-- Reachy SDK -->
<script>
if (location.search.indexOf('elementor-preview') === -1) {
  window.reachy = window.reachy || { event: [], config: [], session: [], privacy: [], identify: [], login: [], queue: [] };
  window.reachy.queue.push({ type: 'config', data: {
    passcode: 'YOUR_PASSCODE',
    cookieDomain: 'yoursite.com'        // root domain, without www
  }});
  var s = document.createElement('script');
  s.async = true;
  s.src = 'https://sdk.reachy.io/sdk.js';
  document.head.appendChild(s);
}
</script>

Com Elementor Pro: Elementor > Custom Code > Add New; nome Reachy SDK, Location <head>, Priority 1; cole o snippet, clique em Publish e escolha Entire Site.

Sem Elementor Pro: instale e ative o plugin WPCode; em Code Snippets > Header & Footer, cole o snippet na caixa Header e salve.

Formulários do Elementor Pro: o SDK não lê formulários sozinho. No widget Form, defina o ID de cada campo (aba Advanced) como nome, email e telefone, e adicione o código abaixo em um widget HTML da página ou no Custom Code para valer em todo o site. O envio usa sendBeacon, então o contato é criado mesmo que o formulário redirecione.

Formulário do Elementor virando contato
<script>
document.addEventListener('submit', function (e) {
  var form = e.target;
  if (!form.classList || !form.classList.contains('elementor-form')) return;
  var get = function (id) {
    var el = form.querySelector('[name="form_fields[' + id + ']"]');
    return el ? el.value.trim() : '';
  };
  var email = get('email'), phone = get('telefone');
  if (!email && !phone) return;
  reachy.login.push({
    first_name: get('nome'),
    email: email || undefined,
    phone: phone || undefined,
    is_subscribed: true,
    properties: { source: 'elementor', form: form.getAttribute('name') || form.id || 'form', page: location.pathname }
  });
  reachy.event.push('Form Completed', { page: location.pathname });
}, true);
</script>

WooCommerce: os eventos de e-commerce ficam em MySDK.ecommerce e precisam esperar a instância existir. Gere o JavaScript pelo PHP, com os dados reais do pedido, no functions.php do tema filho ou em um snippet PHP do WPCode. O mesmo padrão vale para checkoutStarted na página de checkout.

Pedido concluído (functions.php)
add_action('woocommerce_thankyou', function ($order_id) {
  $order = wc_get_order($order_id);
  if (!$order) return;

  $items = [];
  foreach ($order->get_items() as $item) {
    $p = $item->get_product();
    $items[] = [
      'product_id' => $p && $p->get_sku() ? $p->get_sku() : (string) $item->get_product_id(),
      'name'       => $item->get_name(),
      'price'      => $item->get_quantity() ? (float) $item->get_total() / $item->get_quantity() : 0,
      'quantity'   => (int) $item->get_quantity(),
    ];
  }
  $data = [
    'order_id'       => (string) $order->get_order_number(),
    'total'          => (float) $order->get_total(),
    'shipping'       => (float) $order->get_shipping_total(),
    'tax'            => (float) $order->get_total_tax(),
    'currency'       => $order->get_currency(),
    'payment_method' => $order->get_payment_method(),
    'coupon'         => implode(',', $order->get_coupon_codes()) ?: null,
    'items'          => $items,
  ];
  $contact = [
    'first_name'    => $order->get_billing_first_name(),
    'email'         => $order->get_billing_email(),
    'phone'         => $order->get_billing_phone(),
    'is_subscribed' => true,
  ];
  ?>
  <script>
  reachy.login.push(<?php echo wp_json_encode($contact); ?>);
  (function wait(n) {
    if (window.MySDK && MySDK.initialized) MySDK.ecommerce.orderCompleted(<?php echo wp_json_encode($data); ?>);
    else if (n < 200) setTimeout(function () { wait(n + 1); }, 50);
  })(0);
  </script>
  <?php
});

Plugins de cache e otimização: opções que atrasam JavaScript seguram o SDK até o primeiro clique ou rolagem, e quem entra e sai sem interagir não gera page_enter. Adicione sdk.reachy.io e reachy às exclusões e limpe o cache após cada alteração.

PluginOpçãoO que fazer
WP RocketDelay JavaScript execution, Minify/Combine JSEm File Optimization, adicione sdk.reachy.io e reachy às exclusões de delay e de minificação.
LiteSpeed CacheJS Delay, JS CombineEm Page Optimization > Tuning, adicione sdk.reachy.io e reachy em JS Excludes e JS Delayed Excludes.
AutoptimizeAggregate JS, DeferExclua sdk.reachy.io e reachy em JS Optimization.
CloudflareRocket LoaderDesligue ou adicione data-cfasync="false" na tag <script> do snippet.
Qualquer cache de páginaHTML antigo em cacheLimpe o cache após cada alteração no snippet ou nos widgets HTML.

Enfileirar comandos antes de o SDK carregar

Qualquer comando pode ser colocado em window.reachy.queue antes do script, no formato { type, data }. O SDK executa tudo na ordem assim que inicia.

typedata
configobjeto de configuração
createContactdados do contato
trackEvent{ eventName, eventData }
identify{ userId, traits }
webpush{ action: 'requestPermission' | 'unsubscribe', options }
renewSession, clearSessionnenhum

Depois do carregamento, as filas nomeadas executam na hora: reachy.event.push, reachy.login.push, reachy.identify.push, reachy.webpush.push, reachy.session.push, reachy.privacy.push e reachy.config.push.

Identidade e contatos

O reachyID

Na primeira visita o SDK gera um identificador único para o navegador, o reachyID, e o guarda por 1 ano em localStorage e cookie. Todo evento leva esse ID; é por ele que o Reachy liga a navegação ao contato. Com a opção cookieDomain, o mesmo reachyID vale em todos os subdomínios do site.

Um visitante passa por dois estados:

  • Anônimo: tem reachyID, sessão e eventos, mas o Reachy ainda não sabe quem é. Aparece em métricas de tráfego, não em Contacts.
  • Identificado: depois de createContact, vira um contato com e-mail ou telefone. A partir daí os eventos entram na linha do tempo dele e ele pode receber mensagens.

Cadastrar ou atualizar um contato

createContact(data) cria o contato ou atualiza o existente. Via fila: reachy.event.push({ ... }) com um objeto, ou reachy.login.push({ ... }).

createContact
MySDK.createContact({
  email: 'ana@email.com',
  phone: '+5511999999999',
  first_name: 'Ana',
  last_name: 'Souza',
  is_subscribed: true,
  properties: { plan: 'basic', source: 'quiz', utm_source: 'google' }
});
CampoObrigatórioDescrição
emailUm dos doisE-mail do contato. É a identidade principal.
phoneUm dos doisTelefone em formato internacional (+5511999999999), com 6 dígitos ou mais. whatsapp é aceito como sinônimo.
first_name, last_nameNãoNome e sobrenome.
is_subscribedNão (padrão true)Consentimento para receber mensagens. Define as preferências por canal.
propertiesNãoObjeto com campos do contato. Use nomes em snake_case e os mesmos nomes em todos os sites.
communication_preferencesNãoControle fino por canal (ver abaixo). Se omitido, o SDK deriva de is_subscribed.

Regras:

  • Sem e-mail válido nem telefone com 6 dígitos, nada é enviado e a promessa resolve false.
  • O contato é deduplicado pelo e-mail: o mesmo e-mail enviado de novo atualiza o contato existente.
  • Quando o reachyID muda: ao cadastrar um e-mail que o navegador ainda não conhecia, ou um e-mail diferente do anterior, o SDK gera um novo reachyID para o contato. Isso evita juntar duas pessoas que usam o mesmo dispositivo. Cadastros só com telefone sempre geram um ID novo.
  • Para manter o histórico anônimo no contato, informe o e-mail ao SDK antes do cadastro com MySDK.updateUserData({ email }). O SDK reconhece o e-mail e reaproveita o reachyID, e as páginas vistas e a inscrição de web push feitas antes do formulário ficam no contato.
  • Preferências por canal derivadas de is_subscribed: e-mail fica ativo se há e-mail e consentimento; SMS e WhatsApp, se há telefone e consentimento; web push começa desativado. Para controle fino, envie communication_preferences com a lista channels:
communication_preferences
communication_preferences: {
  channels: [
    { channel: 'email', subscribed: true },
    { channel: 'sms', subscribed: false },
    { channel: 'whatsapp', subscribed: false },
    { channel: 'web_push', subscribed: true }
  ]
}

Vincular a um ID do seu sistema

identify(userId, traits) liga o reachyID a um identificador externo (CRM, ERP, login) sem criar contato. userId é uma string; traits é um objeto livre guardado localmente e enviado no evento identify.

identify
MySDK.identify('crm-42', { plan: 'pro', company: 'Acme' });
// or, via queue:
reachy.identify.push('crm-42', { plan: 'pro' });

Consultar e limpar a identidade

  • getReachyID() retorna o ID atual; getUserData() retorna o que o SDK guardou do contato; isUserRegistered() diz se já houve cadastro neste navegador (útil para esconder o formulário).
  • clearUserData() apaga os dados locais e mantém o reachyID; clearUserIdentity() apaga tudo, inclusive o ID. Use em logout de áreas restritas e em pedidos de esquecimento.

Eventos

Eventos são o registro do que o visitante faz. Alguns o SDK envia sozinho; os do seu negócio você envia com uma linha. Todos entram na linha do tempo do contato e podem filtrar Públicos e disparar Jornadas.

Eventos customizados

trackEvent
MySDK.trackEvent('Form Completed', { source: 'quiz', plan: 'basic' });
// or, via queue:
reachy.event.push('Form Completed', { source: 'quiz' });
  • O nome é livre e vai exatamente como escrito. 'Form Completed' e 'form_completed' são eventos diferentes.
  • Use o mesmo nome em todos os sites e canais; Públicos e Jornadas filtram pelo nome exato.
  • As propriedades são um objeto livre. Prefira snake_case e os mesmos nomes usados em properties do contato.
  • Nada precisa ser cadastrado antes no Reachy: o evento aparece assim que chega.
  • Cadastre o contato antes do evento de conversão, para o evento já chegar ligado à pessoa.

Exemplo: evento nomeado em um botão. O evento automático click já registra qualquer clique, mas um evento com nome próprio é melhor como gatilho de Jornada ou filtro de Público, porque não depende do seletor do elemento. Dê um id ao botão e use um listener no document, que sobrevive a re-renderizações:

Evento nomeado em um botão
<script>
document.addEventListener('click', function (e) {
  var target = e.target.closest('#cta-main');
  if (!target) return;
  reachy.event.push('CTA Clicked', {
    button: 'cta-main',
    text: (target.textContent || '').trim(),
    page: location.pathname
  });
});
</script>

Eventos automáticos

EventoQuando é enviadoDadosOpção
page_enterA cada página aberta, inclusive troca de rota em SPAurl, domain, path, title, referrertrackPageViews (ligada)
UTM VisitedPágina aberta com parâmetros UTM na URLutm_source, utm_medium, utm_campaign, utm_term, utm_contenttrackUtmVisited (ligada)
clickClique em qualquer elementoelement (tag, id, text, href, type), positiontrackClicks (ligada)
outbound_clickClique em link para outro domíniourl, text, target, rel, link, currenttrackOutboundLinks (ligada)
time_on_pageAo sair da páginatotal_time, time_since_last_activity, is_activetrackTimeOnPage (ligada)
user_idle / user_activity_resumed30 minutos sem atividade / retornotempo paradoactivityTracking (ligada)
page_leaveAo sair da páginaurl, domain, path, titletrackPageLeave (desligada)
scroll_depthAo atingir 25, 50, 75 e 100% da páginapercentual atingidotrackScrollDepth (desligada)
page_hidden / page_visibleTroca de aba e retornotimestamptrackVisibility (desligada)
create_contact, identifyChamadas de createContact e identifydados do contato / userId e traitssempre
web_push_subscribed, web_push_permission_denied, web_push_unsubscribed, web_push_syncCiclo do web pushinscrição e permissãosempre

Sites com muito tráfego costumam desligar trackClicks para manter a linha do tempo enxuta. Formulários: envios e mudanças de campo contam como atividade do visitante e mantêm a sessão viva; para registrar as respostas, envie um evento customizado no submit, como no Início rápido.

E-commerce

Sete métodos com schema padronizado, em MySDK.ecommerce. Cada um envia um evento com nome fixo, o que permite relatórios e jornadas prontas para loja.

MySDK.ecommerce
MySDK.ecommerce.productViewed({ product_id: 'SKU-1001', name: 'Black T-shirt', price: 79.9, currency: 'BRL', category: 'clothing' });
MySDK.ecommerce.addedToCart({ product_id: 'SKU-1001', name: 'Black T-shirt', price: 79.9, quantity: 2 });
MySDK.ecommerce.checkoutStarted({ order_id: 'ORD-789', total: 159.8, payment_method: 'pix', items: [{ product_id: 'SKU-1001', name: 'Black T-shirt', price: 79.9, quantity: 2 }] });
MySDK.ecommerce.orderCompleted({ order_id: 'ORD-789', total: 159.8, shipping: 15, tax: 0, currency: 'BRL', payment_method: 'pix', coupon: 'WELCOME10', items: [{ product_id: 'SKU-1001', name: 'Black T-shirt', price: 79.9, quantity: 2 }] });
MétodoEventoCampos
productViewedproduct_viewedproduct_id, name, price, currency, category, brand, variant, list_name, position
addedToCartproduct_added_to_cartproduct_id, name, price, quantity, currency
removedFromCartproduct_removed_from_cartproduct_id, name, price, quantity
cartViewedcart_viewedcart_id, items, total, currency
checkoutStartedcheckout_startedorder_id, total, payment_method, items
orderCompletedorder_completedorder_id, total, shipping, tax, currency, payment_method, coupon, items
couponAppliedcoupon_appliedcoupon, discount

currency assume BRL quando omitida; items é uma lista de { product_id, name, price, quantity }.

Sessão e UTMs

Sessão

Uma sessão agrupa a visita de um mesmo visitante. Ela dura 30 minutos e é estendida automaticamente enquanto houver atividade. Uma sessão nova começa em três situações:

  • primeira visita ao site;
  • 30 minutos sem atividade;
  • mudança de utm_source entre uma página e outra, ou seja, o visitante voltou por outra origem.

A sessão é guardada no navegador e sobrevive a recarregamentos e trocas de aba. Com cookieDomain, vale para todos os subdomínios. Todo evento leva o bloco session com id, createdAt, expires e isNew (verdadeiro só no primeiro evento da sessão).

MySDK.renewSession() força uma sessão nova e MySDK.clearSession() encerra a atual. Via fila: reachy.session.push('renew') e reachy.session.push('clear').

Atividade

O SDK observa mouse, teclado, rolagem e toque. Após 30 minutos sem nada (idleTimeout) envia user_idle; quando o visitante volta, user_activity_resumed. Ao sair da página envia time_on_page com o tempo total e se o visitante estava ativo nos últimos 30 segundos.

UTMs e atribuição

  • Na entrada, o SDK lê utm_source, utm_medium, utm_campaign, utm_term e utm_content da URL e os guarda para a visita inteira. As páginas seguintes continuam atribuídas à mesma origem mesmo sem parâmetros na URL.
  • Todo evento leva o bloco utms com esses valores.
  • Quando a página tem UTMs, o SDK envia o evento UTM Visited. Use-o para medir origem de tráfego em Públicos e para disparar Jornadas por campanha.
  • Para gravar a origem no contato, e não só nos eventos, inclua as UTMs em properties no createContact.

Web push

Com web push, o Reachy envia notificações ao navegador do visitante mesmo com o site fechado. O SDK cuida do pedido de permissão, da inscrição e do vínculo com o contato.

Pré-requisitos

  1. Site em HTTPS.
  2. Canal Web Push configurado no projeto do Reachy, com textos, ícone e regras do aviso de permissão. O SDK busca essa configuração sozinho.
  3. O arquivo reachy-sw.js, baixado de https://sdk.reachy.io/reachy-sw.js, hospedado na raiz do seu site, em /reachy-sw.js. O navegador exige que o service worker venha do próprio domínio. Outro caminho pode ser indicado em pushServiceWorkerPath.

Pedir permissão

push.requestPermission
const result = await MySDK.push.requestPermission();
if (result.status === 'subscribed') {
  // browser subscribed and linked to the visitor
}
// or, via queue:
reachy.webpush.push('requestPermission');

O que acontece:

  1. O SDK confere suporte do navegador e a permissão atual.
  2. Mostra o soft prompt, um aviso do próprio Reachy com os textos do painel, antes do pedido nativo. Se o visitante dispensar, o aviso só volta após um intervalo: pushPromptCooldownDays do snippet, senão o valor do painel, senão 3, 7 e 30 dias a cada dispensa.
  3. Pede a permissão nativa do navegador, registra o service worker e cria a inscrição.
  4. Envia a inscrição ao Reachy, ligada ao reachyID.

Quando o seu próprio site já pergunta ao visitante (uma etapa do formulário, por exemplo), pule o aviso do Reachy com requestPermission({ skipSoftPrompt: true }).

Estados retornados em result.status:

StatusSignificado
subscribedInscrito. result.subscription traz os dados da inscrição.
defaultO visitante fechou o pedido nativo sem responder.
deniedPermissão negada, agora ou anteriormente.
soft_prompt_dismissedDispensou o aviso do Reachy.
soft_prompt_cooldownAviso em intervalo após dispensa anterior.
unsupportedNavegador sem suporte.
no_passcode, config_unavailablePasscode ausente ou canal não configurado no projeto.

A chamada nunca lança exceção; trate pelo status.

Exibição automática

Se o canal no painel tiver exibição automática ligada, com condição de páginas vistas ou segundos na página, o SDK mostra o soft prompt sozinho, uma vez por carregamento, sem código no site. pushAutoShow: false no snippet desliga esse comportamento.

Depois da inscrição

  • A cada página o SDK reenvia a inscrição (pushAutoResync) para manter o vínculo com o contato.
  • MySDK.push.unsubscribe() cancela a inscrição; push.getSubscription() e push.getPermission() consultam o estado; push.isSupported() responde se o navegador suporta.
  • Para o contato ficar marcado como alcançável por web push, peça a permissão depois do cadastro ou envie communication_preferences com web_push ativo no createContact.

Eventos

web_push_subscribed, web_push_permission_denied, web_push_unsubscribed e web_push_sync. Servem como gatilho de Jornada, por exemplo uma notificação de boas-vindas logo após a inscrição.

Notificações

O service worker recebe a notificação (título, texto, ícone, imagem, botões e URL definidos na campanha), exibe no sistema do visitante e, no clique, abre a URL e registra o clique no Reachy. Não é preciso editar o arquivo.

Cross-domain

Quando o visitante passa de um site para outro, o navegador não compartilha cookies nem localStorage entre domínios diferentes, e o segundo site o veria como um visitante novo. O SDK resolve isso de duas formas, conforme o caso.

CasoSolução
Subdomínios do mesmo domínio (app.seusite.com e blog.seusite.com)cookieDomain
Domínios diferentes (seusite.com e outrosite.com)crossDomainLinker

Subdomínios: cookieDomain

Configure cookieDomain: '.seusite.com' nos dois sites. O cookie passa a ser a fonte da identidade e da sessão, e nada muda nas URLs.

cookieDomain
window.reachy.queue.push({ type: 'config', data: { passcode: 'YOUR_PASSCODE', cookieDomain: '.yoursite.com' } });

Domínios diferentes: o linker

O site de origem acrescenta três parâmetros à URL de destino (_rcy_uid, _rcy_sid, _rcy_ts). O site de destino lê os parâmetros, confere o prazo, adota a mesma identidade e sessão e limpa a URL sem recarregar a página. É o mesmo mecanismo do parâmetro _gl do Google Analytics.

Configure nos dois sites, com o mesmo paramPrefix:

crossDomainLinker
window.reachy.queue.push({ type: 'config', data: {
  passcode: 'YOUR_PASSCODE',
  crossDomainLinker: {
    hosts: ['othersite.com'],   // domains this site hands the identity to
    paramPrefix: '_rcy',
    ttlMs: 120000
  }
}});
OpçãoPadrãoDescrição
hosts[]Domínios para os quais este site decora links. O match é por sufixo: outrosite.com cobre www.outrosite.com. Vazio desliga a decoração.
paramPrefix_rcyPrefixo dos parâmetros. Origem e destino precisam usar o mesmo.
ttlMs120000Validade dos parâmetros em milissegundos (2 minutos).
enabledtrueDesliga tudo quando false.
stripUrltrueRemove os parâmetros da URL após a leitura.

Como usar

  • Links <a href> e formulários para os domínios em hosts são decorados automaticamente no clique.
  • Redirecionamentos por JavaScript precisam de MySDK.decorate(url) antes de navegar. A função devolve a URL com os parâmetros quando o destino está em hosts, ou a URL original caso contrário, e nunca lança exceção.
decorate
window.location.href = MySDK.decorate('https://othersite.com/thank-you');

Limites: os parâmetros valem por 2 minutos; o vínculo acontece só na navegação iniciada no site de origem (quem digita a URL do destino chega como visitante novo); o linker mantém o mesmo visitante, mas não substitui o cadastro.

Privacidade e consentimento

O que o SDK coleta

  • Identidade e sessão: reachyID, sessão, UTMs, URL, referrer.
  • Navegador: user agent, plataforma, tamanho de tela e janela. Não há fingerprint no que é enviado.
  • Comportamento: os eventos automáticos listados em Eventos.
  • Dados do contato (e-mail, telefone, nome, campos): apenas quando o site chama createContact, trackEvent ou identify de propósito.

O que o SDK não coleta

  • Valores digitados em formulários. Envios e mudanças de campo contam só como atividade; nenhum valor sai do navegador.
  • Campos sensíveis nem são lidos: qualquer campo cujo nome, id ou tipo contenha password, pass, token, secret, credit, card, cvv, email, phone, cpf, cnpj ou ssn. A lista pode ser estendida em deniedFieldPatterns.

Modo de consentimento

Para sites que exigem aceite de cookies antes de qualquer rastreio, inicie o SDK com respectPrivacy: true. Nesse modo os eventos automáticos ficam bloqueados até o visitante consentir, e o sinal Do Not Track do navegador é respeitado. Chamadas feitas pelo seu código (createContact, trackEvent) continuam funcionando, porque é o site quem decide chamá-las.

Consentimento com banner de cookies
// in the snippet
window.reachy.queue.push({ type: 'config', data: { passcode: 'YOUR_PASSCODE', respectPrivacy: true } });

// when the visitor accepts in the cookie banner
MySDK.updateConfig({ respectPrivacy: false });

// if the visitor declines, also turn off automatic capture
MySDK.setAutoTracking(false);

MySDK.isTrackingPermitted() informa se a captura automática está liberada no momento.

Esquecimento

MySDK.clearUserIdentity() apaga reachyID, dados locais e fingerprint do navegador; MySDK.clearSession() encerra a sessão. A exclusão do contato no Reachy é feita pelo painel.

Consentimento de mensagens

É um assunto separado do rastreio: is_subscribed e communication_preferences no createContact dizem ao Reachy se o contato pode receber e-mail, SMS, WhatsApp e web push. Envie true apenas com opt-in real do visitante, e false quando ele não marcou o aceite.

Página de descadastro

Os e-mails enviados pelo Reachy levam um link de descadastro. Por padrão ele abre uma página do Reachy; com o SDK você pode ter a página no seu próprio site, com a sua marca. O link traz um token (?u=token) ou o ID do contato (?rid=id), e o SDK resolve e confirma o descadastro a partir dele.

Fluxo

  1. Ao abrir a página, chame MySDK.resolveUnsubscribeFromUrl(). Ela lê os parâmetros e devolve { email_masked }, por exemplo a***@email.com, para a página mostrar "Descadastrar a***@email.com?".
  2. No botão de confirmar, chame MySDK.confirmUnsubscribeFromUrl(). O Reachy atualiza as preferências do contato, registra o evento channel_unsubscribed na linha do tempo e atribui o descadastro à campanha ou jornada que enviou o e-mail.
  3. Mostre a confirmação. Se o link for inválido ou tiver expirado, a chamada resolve sem dados e a página deve mostrar uma mensagem orientando a usar o link mais recente.
Página de descadastro
const info = await MySDK.resolveUnsubscribeFromUrl();
if (!info) { showExpiredLink(); return; }
showQuestion(info.email_masked);

confirmButton.onclick = async () => {
  const ok = await MySDK.confirmUnsubscribeFromUrl();
  ok ? showSuccess() : showExpiredLink();
};

Métodos

MétodoParâmetrosRetorno
resolveUnsubscribeFromUrl(options?)options.tokenParam (padrão u), options.ridParam (padrão rid){ email_masked } ou null
confirmUnsubscribeFromUrl(options?)os mesmos, mais options.campaignParam (padrão campaign)true em sucesso
resolveUnsubscribeByToken(token)token do link{ email_masked } ou null
unsubscribeByToken(token)token do linktrue em sucesso
resolveUnsubscribeByReachyId(reachyId)ID do contato{ email_masked } ou null
unsubscribeByReachyId(reachyId, campaignId?)ID do contato e, opcional, a campanha para atribuiçãotrue em sucesso

O token identifica contato e envio e tem validade, por isso é a forma preferida. Os nomes dos parâmetros são configuráveis para quem já tem uma URL de descadastro com outro formato.

Referência de configuração

Toda opção entra no objeto data do snippet ou em MySDK.updateConfig(config) a qualquer momento. O que não for informado usa o padrão.

GrupoOpçãoPadrãoDescrição
ConexãopasscodevazioChave do projeto. Obrigatória; sem ela nada é enviado.
ConexãodebugfalseLiga o painel de depuração flutuante. Também liga com ?reachy_debug=true na URL.
ConexãoqueueEnabledtrueFila offline com reenvio automático quando a rede falha.
IdentidadeautoIdentityManagementtrueO SDK cria e persiste o reachyID sozinho.
IdentidadecookieDomaindomínio atualCompartilha identidade e sessão entre subdomínios (.seusite.com).
IdentidadecrossDomainLinkerdesligadoIdentidade entre domínios diferentes. Ver Cross-domain.
SessãosessionTimeout30 minInatividade que encerra a sessão.
SessãoliveUsersEnabledtrueEnvia page_enter e page_leave para a contagem de visitantes ao vivo.
Captura automáticaautoTrackingtrueLiga o grupo inteiro de captura automática.
Captura automáticatrackPageViewstruepage_enter em cada página, inclusive em SPAs.
Captura automáticatrackUtmVisitedtrueEvento UTM Visited quando a URL tem UTMs.
Captura automáticatrackClickstrueEvento click em botões, links e demais elementos.
Captura automáticatrackOutboundLinkstrueEvento outbound_click ao sair para outro domínio.
Captura automáticatrackScrollDepthfalseEvento scroll_depth nos limiares de scrollThresholds.
Captura automáticascrollThresholds[25, 50, 75, 100]Percentuais de rolagem que disparam scroll_depth.
Captura automáticatrackPageLeavefalseEvento page_leave ao sair da página.
Captura automáticatrackVisibilityfalseEventos page_hidden e page_visible ao trocar de aba.
Captura automáticatrackTimeOnPagetrueEvento time_on_page ao sair.
FormuláriostrackFormSubmitstrueConta envios de formulário como atividade do visitante.
FormuláriostrackFormFieldChangestrueConta mudanças em campos como atividade do visitante.
FormuláriosdeniedFieldPatternspassword, pass, token, secret, credit, card, cvv, email, phone, cpf, cnpj, ssnCampos que o SDK ignora ao observar formulários (match por nome, id ou tipo).
AtividadeactivityTrackingtrueDetecção de atividade e inatividade.
AtividadeidleTimeout30 minSem atividade por esse tempo, envia user_idle.
AtividadeheartbeatInterval5 minIntervalo do pulso que mantém a sessão viva.
PrivacidaderespectPrivacyfalseCom true, bloqueia a captura automática até haver consentimento. Ver Privacidade.
Web pushpushServiceWorkerPath/reachy-sw.jsCaminho do service worker no seu site.
Web pushpushAutoResynctrueReenvia a inscrição a cada página para manter o vínculo com o contato.
Web pushpushSoftPrompttrueMostra o aviso do Reachy antes do pedido nativo.
Web pushpushPromptCooldownDaysnullDias sem repetir o aviso após dispensa. null usa o painel ou o escalonamento 3, 7 e 30 dias; 0 desliga o intervalo.
Web pushpushAutoShowtruePermite a exibição automática do aviso conforme o painel.

Opções de transporte (batchEvents, batchSize, batchTimeout) existem para cenários específicos combinados com o suporte do Reachy; mantenha os padrões.

Referência de métodos

Todos os métodos estão em window.MySDK. Os métodos que enviam dados retornam Promise<boolean>: true quando o envio foi feito ou enfileirado, false quando os dados eram inválidos ou o envio foi bloqueado. Nenhum método lança exceção.

Contato e identidade

createContact(data) cria ou atualiza o contato. Campos em Identidade e contatos.

identify(userId, traits?) vincula o visitante a um ID externo. userId string obrigatória; traits objeto opcional.

getReachyID() retorna o reachyID atual (string).

getUserData() retorna o objeto guardado localmente (email, phone, first_name, is_subscribed, properties, externalUserId...). updateUserData(data) faz merge nesse objeto; use antes do cadastro para manter o histórico anônimo.

getUserInfo() retorna { reachyId, userData, isRegistered, fingerprint }. isUserRegistered() retorna boolean.

setReachyID(id) e generateNewReachyID() controlam o ID manualmente; uso avançado.

clearUserData() apaga os dados locais e mantém o ID. clearUserIdentity() apaga ID, dados e fingerprint.

Eventos

trackEvent(name, data?) envia um evento customizado. name string; data objeto livre.

ecommerce.productViewed(data), addedToCart(data), removedFromCart(data), cartViewed(data), checkoutStarted(data), orderCompleted(data), couponApplied(data): eventos de loja com schema fixo. Campos em Eventos.

Sessão

renewSession() força uma sessão nova. clearSession() encerra a atual.

Web push (MySDK.push)

push.isSupported() retorna boolean. push.getPermission() retorna 'default', 'granted' ou 'denied'.

push.requestPermission(options?) pede a permissão; options.skipSoftPrompt: true pula o aviso do Reachy. Retorna { status, subscription? }; estados em Web push.

push.getSubscription() retorna a inscrição atual ou null. push.unsubscribe() cancela a inscrição.

Cross-domain

decorate(url) retorna a URL com os parâmetros de identidade quando o destino está em crossDomainLinker.hosts; caso contrário, a URL original.

Descadastro

resolveUnsubscribeFromUrl(options?), confirmUnsubscribeFromUrl(options?), resolveUnsubscribeByToken(token), unsubscribeByToken(token), resolveUnsubscribeByReachyId(reachyId), unsubscribeByReachyId(reachyId, campaignId?): parâmetros e retornos em Página de descadastro.

Configuração em tempo de execução

updateConfig(config) aplica qualquer opção da Referência de configuração. updateTrackingConfig(config) aplica opções de captura e atividade e reinicia os observadores.

setDebug(bool), setAutoTracking(bool), setActivityTracking(bool), setLiveUsersEnabled(bool): atalhos para as opções correspondentes.

Middleware

use(fn) registra uma função chamada com os dados do evento antes de cada envio. Ela deve retornar os dados (modificados ou não) ou null para bloquear o envio.

use
MySDK.use((payload) => {
  payload.event.data.site_version = '2.1.0';   // adds a field to every event
  return payload;
});

MySDK.use((payload) => {
  if (payload.event.data.email?.endsWith('@yourcompany.com')) return null;   // skips internal users
  return payload;
});

Privacidade

isTrackingPermitted() retorna boolean. Ver Privacidade e consentimento.

Diagnóstico e ciclo de vida

getInfo() retorna { version, initialized, queueSize, batchBufferSize, session, reachyID, userData, userInfo, autoTracking, activityTracking, trackingStats, utmParams, currentUrl }; em config.passcode aparece [CONFIGURED] ou [NOT SET]. getTrackingStats() retorna contadores de eventos e atividade. clearQueue() descarta a fila offline. destroy() para a captura, remove os observadores e libera a instância.

Fila de comandos

Antes de o script carregar: window.reachy.queue.push({ type, data }) com config, createContact, trackEvent ({ eventName, eventData }), identify ({ userId, traits }), webpush ({ action, options }), renewSession e clearSession. Depois: reachy.event.push, reachy.login.push, reachy.identify.push, reachy.webpush.push, reachy.session.push, reachy.privacy.push e reachy.config.push executam imediatamente.

Depuração e checklist

Painel de depuração

Abra qualquer página do site com ?reachy_debug=true no final da URL. Um painel flutuante mostra o reachyID, a sessão atual e cada evento no momento em que é enviado, com os dados. O mesmo efeito vem de debug: true na configuração ou de MySDK.setDebug(true) no console. O painel é a ferramenta de validação: o SDK não imprime logs no console do navegador.

Console e Network

  • MySDK.getInfo() mostra versão, sessão, reachyID, UTMs, fila pendente e a configuração em uso; config.passcode aparece como [CONFIGURED] quando o passcode foi aplicado.
  • MySDK.getUserData() mostra o que o SDK guardou do contato neste navegador.
  • Na aba Network, filtre por api-sdk e recarregue a página: deve aparecer uma requisição para a API do SDK com event.name: "page_enter" no corpo da requisição. Se o site navega após o clique, marque Preserve log.

Conferir no Reachy

Em Contacts, o contato de teste aparece em até 1 minuto com os campos enviados em properties; a aba de atividades lista os eventos na ordem em que chegaram. No construtor de Públicos, aba de comportamento, o evento aparece na lista assim que chega.

Se nada chega

SintomaO que conferir
MySDK is not defined no consoleO script não está na página. Veja o código-fonte e procure sdk.reachy.io. Se não aparecer, é cache ou condição do gerenciador de tags.
getInfo() mostra passcode: "[NOT SET]"A configuração não foi aplicada. Confira o snippet (window.reachy.queue com type: 'config', dentro do mesmo <script>) ou o updateConfig no onload.
Painel mostra os eventos, mas nada aparece no ReachyO passcode é de outro projeto. Confira o projeto ativo no topo do Reachy.
Nenhuma requisição em NetworkPasscode ausente, aba dentro de um editor visual, ou bloqueador de anúncios. Teste em aba anônima sem extensões.
Site com Content Security PolicyLibere script-src https://sdk.reachy.io e connect-src https://api-sdk.reachy.io https://api.reachy.io.
Evento chegou anônimo, sem contatoO evento saiu antes do createContact. Cadastre primeiro e envie o evento depois.
Contato duplicadoDois e-mails diferentes no mesmo navegador geram IDs diferentes, por desenho. Para manter o histórico, use updateUserData({ email }) antes do cadastro.
Funciona logado, não em aba anônimaCache servindo HTML antigo. Limpe o cache do plugin e da CDN.
reachy.ecommerce is undefinedOs métodos de e-commerce ficam em MySDK.ecommerce, depois de MySDK.initialized.
Web push retorna config_unavailableO canal Web Push não está configurado no projeto.
Web push retorna unsupportedNavegador sem suporte, ou site fora de HTTPS.

Checklist antes de publicar

  • Passcode gerado no projeto certo e guardado fora do código
  • Snippet em um único lugar, cobrindo o site inteiro, carregando de https://sdk.reachy.io/sdk.js
  • MySDK.getInfo() mostra [CONFIGURED] em aba anônima
  • page_enter aparece em Network ao recarregar
  • Contato de teste chegou em Contacts com properties e is_subscribed corretos
  • Evento de conversão chegou ligado ao contato
  • Nomes de eventos e campos iguais aos usados nos outros sites
  • Opções de captura automática revisadas (trackClicks, trackScrollDepth) conforme o volume do site
  • Se usa web push: reachy-sw.js na raiz do site e canal configurado no projeto
  • Se usa banner de cookies: respectPrivacy e a liberação no aceite
  • Exclusões de cache configuradas e cache limpo
  • Contato de teste apagado ou excluído das Jornadas

Compatibilidade e versões

NavegadorVersão mínimaSuporte
Chrome60Completo
Firefox55Completo
Safari12Completo
Edge79Completo
Internet Explorer11Limitado: sem web push; envio pelos meios alternativos

Web push depende de Service Worker e da API Push: Chrome, Firefox, Edge e Safari 16.4 ou superior; no iOS, apenas com o site adicionado à tela inicial. MySDK.push.isSupported() responde em tempo de execução.

Versão

A versão atual é a 1.1.0, disponível em https://sdk.reachy.io/sdk.js. O número aparece em MySDK.getInfo().version e no campo sdkVersion de toda requisição. Atualizações são publicadas na mesma URL e mantêm compatibilidade com o snippet e com os métodos desta referência.

Histórico de versões

VersãoDestaques
1.1.0Web push com soft prompt e exibição automática; cross-domain linker; helpers de descadastro; eventos de e-commerce; fila de comandos window.reachy.queue