@reachysdk/sdk
v1.0.0
Published
SDK JavaScript moderno para tracking de contatos inspirado nas melhores práticas do mercado
Readme
Reachy SDK
SDK JavaScript para tracking de contatos, eventos e e-commerce da plataforma Reachy. Roda no browser do usuario final, coleta dados de comportamento e envia para o backend Reachy via AWS Lambda.
Funcionalidades
- Multiplas estrategias de envio (sendBeacon, fetch, XHR, image pixel, iframe) com fallback automatico
- Fila offline com retry e exponential backoff
- Sessoes inteligentes (30min timeout, auto-extend, nova sessao por UTM change)
- Identidade persistente (reachyID via localStorage + cookie + fingerprint)
- Auto-tracking (page views, cliques, scroll, formularios, outbound links, tempo na pagina)
- E-commerce tracking com schema estruturado (7 eventos padronizados)
- Deduplicacao de eventos via eventId (UUID v4)
- Batching de eventos com compressao de payload
- Middleware/hooks para interceptar eventos antes do envio
- Consent mode com bloqueio de auto-tracking quando privacidade nao permitida
- Cross-domain identity via cookieDomain
- TypeScript declarations (.d.ts) incluidas
- 243 testes unitarios
Instalacao
Via CDN (recomendado)
<script type="text/javascript">
var reachy = {event:[], config:[], session:[], privacy:[], identify:[]};
reachy.config.push({
"passcode": "seu-passcode-aqui",
"debug": false
});
(function () {
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = 'https://d3t0ntrdvgmzst.cloudfront.net/reachy.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(script, s);
})();
</script>Via NPM
npm install @reachysdk/sdkimport { createSDK } from '@reachysdk/sdk';
const sdk = createSDK({
passcode: 'seu-passcode-aqui',
debug: true
});Uso
Criar contato
// Via API de fila (funciona antes do SDK carregar)
reachy.login.push({
first_name: 'Joao Silva',
email: '[email protected]',
phone: '+55 11 99999-9999',
properties: {
utm_source: 'google',
plan: 'pro'
},
is_subscribed: true
});
// Via API direta (apos SDK carregar)
await sdk.createContact({
first_name: 'Joao Silva',
email: '[email protected]',
phone: '+55 11 99999-9999',
properties: { utm_source: 'google' },
is_subscribed: true
});Eventos customizados
// Via fila
reachy.event.push('Button Clicked', {
button_id: 'cta_hero',
page: 'landing'
});
// Via API direta
await sdk.trackEvent('Form Submitted', {
form_name: 'contact',
fields: 5
});Identify
Vincula o reachyID a um ID externo (CRM, sistema interno) sem criar contato:
// Via fila
reachy.identify.push('crm-user-42', { company: 'Acme Corp', plan: 'enterprise' });
// Via API direta
await sdk.identify('crm-user-42', { company: 'Acme Corp', plan: 'enterprise' });E-commerce
API estruturada com schema padronizado para cada tipo de evento:
// Produto visualizado
await sdk.ecommerce.productViewed({
product_id: 'SKU-1001',
name: 'Camiseta Preta P',
price: 79.90,
currency: 'BRL',
category: 'roupas',
brand: 'Reachy Wear'
});
// Adicionado ao carrinho
await sdk.ecommerce.addedToCart({
product_id: 'SKU-1001',
name: 'Camiseta Preta P',
price: 79.90,
quantity: 2
});
// Checkout iniciado
await sdk.ecommerce.checkoutStarted({
order_id: 'ORD-789',
total: 159.80,
payment_method: 'pix',
items: [
{ product_id: 'SKU-1001', name: 'Camiseta Preta P', price: 79.90, quantity: 2 }
]
});
// Pedido finalizado
await sdk.ecommerce.orderCompleted({
order_id: 'ORD-789',
total: 159.80,
shipping: 15.00,
tax: 0,
currency: 'BRL',
payment_method: 'pix',
coupon: 'BLACKFRIDAY',
items: [
{ product_id: 'SKU-1001', name: 'Camiseta Preta P', price: 79.90, quantity: 2 }
]
});
// Outros
await sdk.ecommerce.removedFromCart({ product_id: 'SKU-1001', quantity: 1 });
await sdk.ecommerce.cartViewed({ cart_id: 'abc', items: [...], total: 159.80 });
await sdk.ecommerce.couponApplied({ coupon: 'BLACKFRIDAY', discount: 50.00 });Middleware
Intercepta eventos antes do envio. Retornar null bloqueia o evento:
// Adicionar metadata em todos os eventos
sdk.use((payload) => {
payload.event.data.app_version = '2.1.0';
payload.event.data.environment = 'production';
return payload;
});
// Filtrar usuarios internos
sdk.use((payload) => {
if (payload.event.data.email?.endsWith('@reachy.io')) return null;
return payload;
});Configuracao
const sdk = createSDK({
// Autenticacao (obrigatorio)
passcode: 'seu-passcode',
// Endpoint (ja configurado por padrao)
endpoint: 'https://...',
// Debug
debug: false, // ou ?reachy_debug=true na URL
// Identidade
autoIdentityManagement: true,
cookieDomain: '', // ex: 'example.com' para cross-subdomain
sessionTimeout: 30 * 60 * 1000, // 30 min
// Auto tracking
autoTracking: true,
trackPageViews: true,
trackUtmVisited: true,
trackClicks: true,
trackOutboundLinks: true,
trackFormSubmits: true,
trackFormFieldChanges: true,
captureFieldValues: true,
trackScrollDepth: false,
trackTimeOnPage: true,
trackPageLeave: false,
trackVisibility: false,
scrollThresholds: [25, 50, 75, 100],
// Campos sensiseis (nunca capturados)
deniedFieldPatterns: ['password', 'pass', 'token', 'secret', 'credit', 'card', 'cvv', 'email', 'phone', 'cpf', 'cnpj', 'ssn'],
allowedFieldPatterns: [], // whitelist (vazio = tudo exceto denied)
// Activity tracking
activityTracking: true,
idleTimeout: 30 * 60 * 1000,
heartbeatInterval: 5 * 60 * 1000,
// Live users (page_enter/page_leave)
liveUsersEnabled: true,
// Batching (requer suporte no backend)
batchEvents: false,
batchSize: 10,
batchTimeout: 5000,
// Fila offline
queueEnabled: true,
// Privacy / Consent
respectPrivacy: false, // quando true, bloqueia auto-tracking sem consent
});API Reference
Contatos e Identidade
| Metodo | Descricao |
|--------|-----------|
| createContact(data) | Cria contato com email e/ou telefone. Gera novo reachyID se email muda. |
| identify(userId, traits) | Vincula reachyID a ID externo sem criar contato. |
| getReachyID() | Retorna o reachyID atual. |
| setReachyID(id) | Define reachyID manualmente. |
| generateNewReachyID() | Forca geracao de novo reachyID. |
| getUserData() | Retorna dados do usuario armazenados localmente. |
| getUserInfo() | Retorna informacoes completas (reachyId, userData, isRegistered, fingerprint). |
| updateUserData(data) | Merge com dados existentes. |
| isUserRegistered() | Verifica se usuario ja tem cadastro local. |
| clearUserData() | Limpa dados do usuario (mantem reachyID). |
| clearUserIdentity() | Limpa tudo (reachyID + dados + fingerprint). |
Eventos
| Metodo | Descricao |
|--------|-----------|
| trackEvent(name, data) | Envia evento customizado. |
| ecommerce.productViewed(data) | Evento product_viewed. |
| ecommerce.addedToCart(data) | Evento product_added_to_cart. |
| ecommerce.removedFromCart(data) | Evento product_removed_from_cart. |
| ecommerce.cartViewed(data) | Evento cart_viewed. |
| ecommerce.checkoutStarted(data) | Evento checkout_started. |
| ecommerce.orderCompleted(data) | Evento order_completed. |
| ecommerce.couponApplied(data) | Evento coupon_applied. |
Sessao
| Metodo | Descricao |
|--------|-----------|
| renewSession() | Forca criacao de nova sessao. |
| clearSession() | Remove sessao do storage. |
Controles
| Metodo | Descricao |
|--------|-----------|
| setDebug(enabled) | Liga/desliga logs no console. |
| setAutoTracking(enabled) | Liga/desliga auto-tracking de eventos. |
| setActivityTracking(enabled) | Liga/desliga deteccao de atividade/idle. |
| setLiveUsersEnabled(enabled) | Liga/desliga page_enter/page_leave automaticos. |
| updateConfig(config) | Atualiza configuracao em runtime. |
| updateTrackingConfig(config) | Atualiza configs de tracking e activity. |
Middleware e Privacy
| Metodo | Descricao |
|--------|-----------|
| use(fn) | Registra middleware: (payload) => payload \| null. |
| isTrackingPermitted() | Verifica se tracking esta permitido pelo consent mode. |
Informacao e Debug
| Metodo | Descricao |
|--------|-----------|
| getInfo() | Retorna estado completo do SDK (version, session, reachyID, config, features). |
| getTrackingStats() | Retorna estatisticas de tracking e activity. |
| clearQueue() | Limpa fila de eventos pendentes. |
Lifecycle
| Metodo | Descricao |
|--------|-----------|
| destroy() | Destroi a instancia: para tracking, cancela timers, remove listeners, flush batcher. |
Unsubscribe
| Metodo | Descricao |
|--------|-----------|
| resolveUnsubscribeFromUrl(options?) | Le ?u=token ou ?rid=id da URL e resolve dados do contato. |
| confirmUnsubscribeFromUrl(options?) | Confirma unsubscribe lendo parametros da URL. |
| resolveUnsubscribeByReachyId(id) | Resolve dados de unsubscribe por reachyId. |
| unsubscribeByReachyId(id, campaignId?) | Confirma unsubscribe por reachyId. |
| resolveUnsubscribeByToken(token) | Resolve dados de unsubscribe por token JWT. |
| unsubscribeByToken(token) | Confirma unsubscribe por token JWT. |
Payload
Cada evento enviado tem a seguinte estrutura:
{
"eventId": "uuid-v4",
"reachyID": "uuid-usuario",
"sdkVersion": "1.1.0",
"event": {
"name": "product_viewed",
"data": { ... }
},
"session": {
"id": "session-id",
"createdAt": 1703123456789,
"expires": 1703125256789,
"isNew": false
},
"browser": {
"userAgent": "Mozilla/5.0...",
"platform": { ... },
"screen": { ... },
"window": { ... }
},
"url": {
"current": "https://exemplo.com/pagina",
"domain": "exemplo.com",
"path": "/pagina",
"referrer": "https://google.com"
},
"utms": {
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "black_friday"
},
"timestamp": 1703123456789
}No modo batch, payloads sao comprimidos: campos comuns (browser, url, session, utms) vao no context e cada evento carrega apenas eventId, event e timestamp.
Sistema de transporte
O SDK tenta enviar por multiplas estrategias em ordem de prioridade:
sendBeacon()— nao bloqueia a pagina- Image pixel — via GET, estilo Facebook Pixel
- Fetch API — POST com
no-cors - XMLHttpRequest — fallback para browsers antigos
- iframe invisivel — ultimo recurso
Nada e enviado sem um passcode configurado. Se todas as estrategias falham, o evento vai para a fila offline com retry automatico (exponential backoff de 1s a 30s, max 5 tentativas por evento).
Regras de sessao
- Nova sessao: primeira visita, 30 minutos de inatividade, ou mudanca de
utm_source - Auto-extend: se restam menos de 5 minutos, a sessao e estendida automaticamente
- Persistencia: localStorage (dados completos) + cookie (payload minimo para evitar 431 Request Header Too Large)
Regras de identidade
reachyIDe um UUID persistido em localStorage + cookie (TTL de 1 ano)createContact()com email diferente do armazenado gera novo reachyID (dedup por email)- Contatos phone-only sempre geram novo reachyID
cookieDomainhabilita compartilhamento cross-subdomain (cookie vira source of truth)
Desenvolvimento
npm install # Instalar dependencias
npm run dev # Watch mode (Rollup)
npm run build # Build de producao (UMD + ESM + loader)
npm test # Testes (243 testes, 8 suites)
npm run lint # ESLintRodar um arquivo de teste especifico:
npx jest --testPathPattern='session.test'
npx jest --testPathPattern='ecommerce'Debug via URL: adicione ?reachy_debug=true a qualquer pagina com o SDK.
Build outputs
| Arquivo | Formato | Uso |
|---------|---------|-----|
| dist/sdk.js | UMD (minificado) | CDN, tag <script>. Global ReachySDK. |
| dist/sdk.esm.js | ESM | import via bundler. |
| dist/loader.js | IIFE (minificado) | Script de carregamento assincrono. |
| dist/sdk.d.ts | TypeScript declarations | Autocomplete e tipagem para consumidores NPM. |
Estrutura
src/
sdk.js # Classe principal ReachySDK
loader.js # Script de carregamento assincrono (CleverTap-style)
transport/
index.js # Estrategias de envio (beacon, fetch, XHR, image, iframe)
utils/
session.js # Ciclo de vida da sessao
user-identity.js # reachyID persistente + fingerprint
auto-tracking.js # Listeners de DOM (clicks, scroll, forms, etc)
activity-tracker.js # Deteccao de idle/atividade
queue.js # Fila offline com retry + backoff
batcher.js # Batching de eventos com compressao
cookie.js # Utilitarios compartilhados de cookie
logger.js # Logger centralizado (respeita debug flag)
url.js # Extracao de UTM + sessionStorage
pageview.js # SPA page view detection (History API)
privacy.js # Consent, DNT, opt-in/opt-out
browser.js # Deteccao de capabilities do browser
uuid.js # Geracao de UUID v4
debug.js # Debug dashboard (floating panel)Compatibilidade
| Browser | Versao | Status | |---------|--------|--------| | Chrome | 60+ | Completo | | Firefox | 55+ | Completo | | Safari | 12+ | Completo | | Edge | 79+ | Completo | | IE | 11 | Limitado |
Licenca
MIT
