# @jussimirvfx/meta-pixel-tracking

Sistema completo de tracking do Meta Pixel (Pixel + CAPI) para landing pages com **setup automático**, **backend plug-and-play** e **Advanced Matching otimizado**.

## 🆕 **ATUALIZAÇÃO CRÍTICA v1.10.5**

### ✅ **Advanced Matching Corrigido**
- **Bug crítico corrigido**: Advanced Matching agora funciona 100%
- **Taxa de correspondência**: Melhoria significativa na precisão de targeting
- **Performance**: Otimização automática de campanhas restaurada

### 🔧 **Atualização Obrigatória**
```bash
npm install @jussimirvfx/meta-pixel-tracking@latest
```

### 📊 **Resultado Esperado**
```javascript
// Logs agora mostram:
hasEmail: true, hasPhone: true, hasName: true
// Advanced Matching ativo no Meta Events Manager
```

## 🚀 Instalação e Setup Automático

### ⚡ Setup Completo (Recomendado)

```bash
# 1. Instalar o package
npm install @jussimirvfx/meta-pixel-tracking

# 2. Setup automático completo (API routes + servidor)
npx @jussimirvfx/meta-pixel-tracking

# 3. Configurar credenciais no .env
cp .env.example .env
# Edite .env com suas credenciais do Meta Pixel

# 4. Iniciar servidor de desenvolvimento
npm run dev:meta
```

**Arquivos criados automaticamente:**
- `api/get-ip.js` - Captura IP real do cliente
- `api/meta-conversions.js` - API route do Meta Conversions
- `dev-server-full.js` - Servidor Express completo
- `.env.example` - Template de variáveis de ambiente
- `README-integration.md` - Documentação específica do projeto

### 🔧 Scripts Disponíveis

```bash
npm run setup:meta      # Setup completo
npm run dev:meta        # Servidor de desenvolvimento
npm run dev:meta:prod   # Servidor de produção
```

## ⚡ Configuração Automática (Recomendado)

### 1. Configurar variáveis de ambiente

```env
VITE_META_PIXEL_ID=seu_pixel_id
VITE_META_API_ACCESS_TOKEN=seu_access_token
VITE_META_TEST_EVENT_CODE=seu_test_code
```

### 2. Usar no App (Zero Configuração)

```tsx
// index.tsx - Configuração automática
import { AutoMetaPixelProvider, AutoMetaPixel } from '@jussimirvfx/meta-pixel-tracking'

ReactDOM.createRoot(document.getElementById('root')).render(
  <AutoMetaPixelProvider>
    <App />
    <AutoMetaPixel />
  </AutoMetaPixelProvider>
)
```

**Pronto!** O Meta Pixel será configurado e inicializado automaticamente.

## 🔧 Configuração Manual (Opcional)

### ⚠️ IMPORTANTE: Configure sempre ANTES de usar qualquer componente ou hook do package!

```tsx
// index.tsx - Configuração manual
import { configureMetaPixel, MetaPixelProvider, MetaPixel } from '@jussimirvfx/meta-pixel-tracking'

// 1. Configure o package ANTES de usar qualquer componente
configureMetaPixel({
  PIXEL_ID: import.meta.env.VITE_META_PIXEL_ID,
  ACCESS_TOKEN: import.meta.env.VITE_META_API_ACCESS_TOKEN,
  TEST_EVENT_CODE: import.meta.env.VITE_META_TEST_EVENT_CODE,
})

// 2. Adicione o MetaPixelProvider no seu App
ReactDOM.createRoot(document.getElementById('root')).render(
  <MetaPixelProvider>
    <App />
    <MetaPixel pixelId={import.meta.env.VITE_META_PIXEL_ID} />
  </MetaPixelProvider>
)
```

### 📋 Passos Obrigatórios:

1. **Configure o package** no seu main.tsx ou App.tsx ANTES de usar qualquer componente:
   ```tsx
   import { configureMetaPixel } from '@jussimirvfx/meta-pixel-tracking';
   configureMetaPixel({
     PIXEL_ID: import.meta.env.VITE_META_PIXEL_ID,
     ACCESS_TOKEN: import.meta.env.VITE_META_API_ACCESS_TOKEN,
     TEST_EVENT_CODE: import.meta.env.VITE_META_TEST_EVENT_CODE,
   });
   ```

2. **Adicione o MetaPixelProvider** no seu App:
   ```tsx
   import { MetaPixelProvider } from '@jussimirvfx/meta-pixel-tracking';
   <MetaPixelProvider>
     <App />
   </MetaPixelProvider>
   ```

3. **Adicione o componente MetaPixel**:
   ```tsx
   import { MetaPixel, META_PIXEL_CONFIG } from '@jussimirvfx/meta-pixel-tracking';
   <MetaPixel pixelId={META_PIXEL_CONFIG.PIXEL_ID} />
   ```

4. **Integre com o sistema de lead scoring** criado no setup automático

## 🎯 Tracking de Eventos

### Hooks (Recomendado)

```tsx
import { useMetaPixel } from '@jussimirvfx/meta-pixel-tracking'

function MyComponent() {
  const { trackLead, trackLeadQualificado } = useMetaPixel()

  const handleSubmit = async (formData) => {
    // ✅ FORMATO CORRETO - Dados do formulário
    const leadData = {
      // 📋 Dados obrigatórios para Advanced Matching
      email: formData.email,        // "user@email.com"
      phone: formData.telefone,     // "11999999999" ou "phone"
      name: formData.nome,          // "João Silva" ou "name"
      
      // 🌍 Dados geográficos (opcionais)
      city: formData.cidade,        // "São Paulo" ou "city"
      state: formData.estado,       // "SP" ou "state"
      zip: formData.cep,           // "01234567" ou "zip"
      country: formData.pais,       // "Brasil" ou "country"
      
      // 💰 Dados do evento (opcionais)
      value: 25,
      currency: 'BRL',
      content_name: 'Formulário de Contato',
      content_category: 'Lead Generation'
    }

    // Lead básico
    await trackLead(leadData)

    // Lead qualificado (se aplicável)
    if (leadScore >= 70) {
      await trackLeadQualificado({
        ...leadData,
        lead_score: leadScore,
        qualification_reason: 'High engagement',
        value: 100
      })
    }
  }

  return <button onClick={handleSubmit}>Enviar Lead</button>
}
```

### 📝 Exemplo Prático de Formulário

```tsx
import { useState } from 'react'
import { useMetaPixel } from '@jussimirvfx/meta-pixel-tracking'

function ContactForm() {
  const { trackLead } = useMetaPixel()
  const [formData, setFormData] = useState({
    nome: '',      // ou "name"
    email: '',
    telefone: '',  // ou "phone"
    cidade: '',    // ou "city" 
    estado: ''     // ou "state"
  })

  const handleSubmit = async (e) => {
    e.preventDefault()

    // ✅ Enviar com os nomes corretos dos campos
    await trackLead({
      name: formData.nome,          // Sistema aceita "name" ou "nome"
      email: formData.email,        // Campo obrigatório
      phone: formData.telefone,     // Sistema aceita "phone" ou "telefone"
      city: formData.cidade,        // Sistema aceita "city" ou "cidade"
      state: formData.estado,       // Sistema aceita "state" ou "estado"
      value: 25,
      currency: 'BRL',
      content_name: 'Formulário de Contato'
    })

    alert('Lead enviado com sucesso!')
  }

  return (
    <form onSubmit={handleSubmit}>
      <input 
        type="text" 
        placeholder="Nome completo"
        value={formData.nome}
        onChange={(e) => setFormData({...formData, nome: e.target.value})}
        required 
      />
      <input 
        type="email" 
        placeholder="Email"
        value={formData.email}
        onChange={(e) => setFormData({...formData, email: e.target.value})}
        required 
      />
      <input 
        type="tel" 
        placeholder="Telefone (11999999999)"
        value={formData.telefone}
        onChange={(e) => setFormData({...formData, telefone: e.target.value})}
        required 
      />
      <input 
        type="text" 
        placeholder="Cidade"
        value={formData.cidade}
        onChange={(e) => setFormData({...formData, cidade: e.target.value})}
      />
      <input 
        type="text" 
        placeholder="Estado (SP)"
        value={formData.estado}
        onChange={(e) => setFormData({...formData, estado: e.target.value})}
      />
      <button type="submit">Enviar</button>
    </form>
  )
}
```

### 🔑 Nomes de Campos Aceitos

O sistema aceita **nomes em português E inglês** para máxima compatibilidade:

| Dado | Nome em Português | Nome em Inglês | Obrigatório |
|------|------------------|-----------------|-------------|
| **Email** | `email` | `email` | ✅ Sim |
| **Telefone** | `telefone` | `phone` | ✅ Sim |
| **Nome** | `nome` | `name` | ✅ Sim |
| **Cidade** | `cidade` | `city` | ❌ Opcional |
| **Estado** | `estado` | `state` | ❌ Opcional |
| **CEP** | `cep` | `zip` | ❌ Opcional |
| **País** | `pais` | `country` | ❌ Opcional |

```tsx
// ✅ Ambos os formatos funcionam:

// Formato português
await trackLead({
  nome: 'João Silva',
  telefone: '11999999999',
  cidade: 'São Paulo',
  estado: 'SP'
})

// Formato inglês  
await trackLead({
  name: 'João Silva',
  phone: '11999999999', 
  city: 'São Paulo',
  state: 'SP'
})

// Formato misto (também funciona)
await trackLead({
  name: 'João Silva',
  telefone: '11999999999',
  city: 'São Paulo',
  estado: 'SP'
})
```

### 📱 Formato do Telefone

O sistema aceita vários formatos de telefone:

```tsx
// ✅ Todos estes formatos funcionam:
phone: '11999999999'      // Sem formatação (recomendado)
phone: '(11) 99999-9999'  // Com formatação
phone: '+5511999999999'   // Com código do país
phone: '11 99999-9999'    // Com espaços
```

**O sistema automaticamente:**
- Remove caracteres especiais: `(`, `)`, `-`, espaços
- Adiciona código do país (55) se não estiver presente
- Faz hash SHA-256 do número normalizado

### APIs Diretas (Sem Hooks)

```tsx
import { trackLeadWithData, trackCustomEvent } from '@jussimirvfx/meta-pixel-tracking'

// Tracking de lead com dados customizados
await trackLeadWithData({
  name: 'João Silva',
  email: 'joao@email.com',
  store_type: 'boutique',
  lead_score: 75
}, true) // true = lead qualificado

// Tracking de evento customizado
await trackCustomEvent('Purchase', {
  value: 150.00,
  currency: 'BRL',
  content_name: 'Produto X'
}, {
  userData: {
    email: 'cliente@email.com',
    name: 'Cliente'
  },
  onSuccess: () => console.log('Evento enviado!'),
  onError: (error) => console.error('Erro:', error)
})
```

## 📊 Debug e Logs

O package inclui um sistema completo de logs para debug. Para ativar:

```javascript
// Método 1: Parâmetro na URL
// Acesse: https://seusite.com/?debug=true

// Método 2: LocalStorage
localStorage.setItem('meta-pixel-debug', 'true')

// Método 3: Console aberto
// Simplesmente abra o console (F12)
```

**Interface de logs disponível:**
```javascript
// Ver todos os logs
window._metaPixelLogs.getLogs()

// Ver logs por categoria
window._metaPixelLogs.getLogsByCategory('PAGE_VIEW')
window._metaPixelLogs.getLogsByCategory('LEAD')

// Ativar/desativar logs
window._metaPixelLogs.enable()
window._metaPixelLogs.disable()
```

📖 **Documentação completa:** [DEBUG.md](./DEBUG.md)

## 🚨 Troubleshooting - Problemas Comuns

### ❌ Dados não chegam no Meta Events Manager

**Problema:** Os dados de email, telefone ou nome não aparecem no Meta.

**Solução:** Verifique os nomes dos campos:

```tsx
// ❌ INCORRETO - Nomes de campos incorretos
await trackLead({
  user_name: 'João',    // ❌ Deveria ser 'name' ou 'nome'  
  user_email: 'j@j.com', // ❌ Deveria ser 'email'
  telephone: '11999'     // ❌ Deveria ser 'phone' ou 'telefone'
})

// ✅ CORRETO
await trackLead({
  name: 'João Silva',      // ✅ ou 'nome'
  email: 'joao@email.com', // ✅ sempre 'email'
  phone: '11999999999'     // ✅ ou 'telefone'
})
```

## 🎯 **Advanced Matching - Funcionamento**

### ✅ **Como Funciona**

O sistema automaticamente processa e envia dados de usuário para **melhorar a taxa de correspondência** no Meta:

```javascript
// Dados enviados automaticamente para Meta CAPI:
{
  em: [hashEmail(email)],           // Email hasheado
  ph: [hashPhone(phone)],           // Telefone hasheado  
  fn: [hashFirstName(name)],        // Primeiro nome hasheado
  ln: [hashLastName(name)],         // Sobrenome hasheado
  ct: [hashValue(city)],            // Cidade hasheada
  st: [hashValue(state)],           // Estado hasheado
  zp: [hashValue(zip)],             // CEP hasheado
  country: [hashValue(country)]     // País hasheado
}
```

### 📊 **Resultado Esperado**

Após enviar um evento, você deve ver nos logs:

```javascript
[META PIXEL - CONVERSION_API] - Dados de usuário preparados: {
  event: "LeadQualificado",
  hasEmail: true,     // ✅ Email processado
  hasPhone: true,     // ✅ Telefone processado
  hasName: true,      // ✅ Nome processado
  userDataKeys: ['em', 'ph', 'fn', 'ln', 'client_user_agent', 'client_ip_address', 'fbp', 'fbc']
}
```

### 🔍 **Verificar no Meta Events Manager**

1. Acesse: [Meta Events Manager](https://business.facebook.com/events_manager2/list/pixel/your-pixel-id)
2. Vá em **"Test Events"**
3. Procure por eventos com **"Advanced Matching"** ativo
4. Verifique se aparece: **"Email Hashed 100% of total events"**

### 🚨 **Se Advanced Matching não funcionar**

**Problema:** Logs mostram `hasEmail: false`, `hasPhone: false`

**Soluções:**

1. **Verificar nomes dos campos:**
```tsx
// ✅ CORRETO
await trackLead({
  name: 'João Silva',      // ✅ 'name' ou 'nome'
  email: 'joao@email.com', // ✅ sempre 'email'
  phone: '11999999999'     // ✅ 'phone' ou 'telefone'
})
```

2. **Verificar se dados não estão vazios:**
```tsx
// ❌ INCORRETO - Dados vazios
await trackLead({
  name: '',           // ❌ Vazio
  email: '   ',       // ❌ Só espaços
  phone: undefined    // ❌ Undefined
})
```

3. **Atualizar para versão mais recente:**
```bash
npm install @jussimirvfx/meta-pixel-tracking@latest
```

### ❌ Eventos não aparecem no Meta

**Problema:** Nenhum evento chega no Meta Events Manager.

**Verificações:**

1. **Configuração das variáveis de ambiente:**
```bash
# Verifique se estas variáveis estão configuradas:
VITE_META_PIXEL_ID=seu_pixel_id
VITE_META_API_ACCESS_TOKEN=seu_access_token
```

2. **Console do navegador:**
```javascript
// Abra o console (F12) e verifique:
console.log('Configuração:', {
  pixelId: import.meta.env.VITE_META_PIXEL_ID,
  hasAccessToken: !!import.meta.env.VITE_META_API_ACCESS_TOKEN
})
```

3. **Logs do sistema:**
```javascript
// Ative os logs e teste:
localStorage.setItem('meta-pixel-debug', 'true')
// Depois envie um lead e veja os logs no console
```

### ❌ Telefone não é reconhecido

**Problema:** O telefone aparece no Meta mas não é reconhecido no Advanced Matching.

**Solução:** Formato do telefone deve incluir DDD:

```tsx
// ❌ INCORRETO - Sem DDD
phone: '999999999'

// ✅ CORRETO - Com DDD brasileiro
phone: '11999999999'    // São Paulo
phone: '21999999999'    // Rio de Janeiro
phone: '47999999999'    // Santa Catarina
```

### ❌ Advanced Matching baixo

**Problema:** O Meta mostra baixa qualidade no Advanced Matching.

**Solução:** Inclua mais dados do usuário:

```tsx
// ❌ Dados mínimos (match rate ~30%)
await trackLead({
  email: 'user@email.com'
})

// ✅ Dados completos (match rate ~90%+)
await trackLead({
  name: 'João Silva',           // ✅ Nome completo
  email: 'joao@email.com',      // ✅ Email válido
  phone: '11999999999',         // ✅ Telefone com DDD
  city: 'São Paulo',            // ✅ Cidade
  state: 'SP',                  // ✅ Estado
  zip: '01234567',              // ✅ CEP
  country: 'Brasil'             // ✅ País
})
```

### ❌ Eventos duplicados

**Problema:** O Meta mostra eventos em duplicata.

**Explicação:** Isso é normal! O sistema envia via:
- **Pixel do navegador** (para usuários sem adblock)
- **API de Conversões** (para máxima precisão)

O Meta automaticamente deduplica usando o Event ID. No Meta Events Manager você verá:
- ✅ Total de eventos únicos (após deduplicação)
- ℹ️ Eventos do pixel + eventos da API

### 📞 Suporte

Se o problema persistir:

1. **Ative os logs detalhados:**
```javascript
localStorage.setItem('meta-pixel-debug', 'true')
```

2. **Teste com dados simples:**
```tsx
await trackLead({
  name: 'Teste',
  email: 'teste@teste.com', 
  phone: '11999999999'
})
```

3. **Verifique no console se há erros**

4. **Confira se as variáveis de ambiente estão corretas**

## 🎯 Eventos Disponíveis

### Automáticos
- ✅ **PageView** - Enviado automaticamente ao carregar a página
- ✅ **Scroll** - Rastreamento automático em 25%, 50%, 75% e 100%

### Manuais
- ✅ **Lead** - Para leads básicos
- ✅ **LeadQualificado** - Para leads qualificados
- ✅ **Custom Events** - Para eventos personalizados

## 🔧 Funcionalidades

- ✅ **Setup Automático** - Zero configuração manual
- ✅ **Backend Plug-and-Play** - API routes e servidor criados automaticamente
- ✅ **IP Real Capturado** - Match rate 90%+ com IP real do cliente
- ✅ **Advanced Matching** - Hash SHA-256 para todos os dados
- ✅ **Deduplicação** - Event ID único entre Pixel e CAPI
- 🛡️ **Proteção Anti-AdBlock** - Funciona mesmo com bloqueadores de anúncios
- ✅ **Error Handling** - Tratamento robusto de erros
- ✅ **TypeScript** - Tipos completos incluídos
- ✅ **Logs Detalhados** - Debug completo em desenvolvimento
- ✅ **Multi-Ambiente** - Funciona em Vite, CRA, Next.js, etc.
- ✅ **Vercel Ready** - API routes prontas para deploy
- ✅ **Debug Automático** - Logs ativados automaticamente em Vercel/development

## 📊 Benefícios do Setup Automático

| Aspecto | Setup Manual | Setup Automático |
|---------|-------------|------------------|
| **Tempo** | 2-3 horas | 2 minutos |
| **IP Real** | Não disponível | ✅ Captura automática |
| **Match Rate** | 60-70% | 85-95% |
| **API Routes** | Criar manualmente | ✅ Criadas automaticamente |
| **Servidor** | Configurar Express | ✅ Pronto para usar |
| **Debug** | Configurar manualmente | ✅ Automático em Vercel |

## 📦 Exports Disponíveis

### Componentes
```tsx
import { 
  AutoMetaPixelProvider,  // Provider automático
  MetaPixelProvider,      // Provider manual
  AutoMetaPixel,          // Pixel automático
  MetaPixel               // Pixel manual
} from '@jussimirvfx/meta-pixel-tracking'
```

### Hooks
```tsx
import { 
  useMetaPixel,           // Hook principal
  useScrollTracking       // Hook de scroll
} from '@jussimirvfx/meta-pixel-tracking'
```

### APIs
```tsx
import { 
  trackCustomEvent,       // Evento customizado
  trackLeadWithData,      // Lead com dados
  safeTrack,              // Tracking seguro
  withErrorHandling       // Decorator de erro
} from '@jussimirvfx/meta-pixel-tracking'
```

### Configuração
```tsx
import { 
  configureMetaPixel,     // Configuração manual
  autoConfigureMetaPixel, // Configuração automática
  META_PIXEL_CONFIG       // Configuração atual
} from '@jussimirvfx/meta-pixel-tracking'
```

## 🚨 Troubleshooting

### Package não está funcionando?
1. **Verifique se a configuração foi feita ANTES de usar hooks:**
   ```tsx
   // ✅ CORRETO - Configure primeiro
   configureMetaPixel({...})
   
   // Depois use hooks
   const { trackLead } = useMetaPixel()
   ```

2. **Verifique se o MetaPixelProvider está envolvendo sua App:**
   ```tsx
   // ✅ CORRETO
   <MetaPixelProvider>
     <App />
   </MetaPixelProvider>
   ```

3. **Verifique se as variáveis de ambiente estão configuradas:**
   ```env
   VITE_META_PIXEL_ID=seu_pixel_id
   VITE_META_API_ACCESS_TOKEN=seu_access_token
   VITE_META_TEST_EVENT_CODE=seu_test_code
   ```

### Script setup não funciona?
```bash
# Use o comando CLI diretamente
npx @jussimirvfx/meta-pixel-tracking

# Ou execute manualmente
node node_modules/@jussimirvfx/meta-pixel-tracking/bin/meta-pixel-setup.cjs
```

### Logs não aparecem?
1. Verifique se o console está aberto
2. Adicione `?debug=true` na URL
3. Execute: `localStorage.setItem('meta-pixel-debug', 'true')`
4. Recarregue a página

### Package não funciona?
1. Verifique se as variáveis de ambiente estão configuradas
2. Use `AutoMetaPixelProvider` para configuração automática
3. Verifique os logs no console

### IP não está sendo capturado?
1. Verifique se a API route está configurada: `/api/meta/conversions`
2. Confirme se o deploy no Vercel foi realizado
3. Teste o health check: `curl https://seu-dominio.vercel.app/api/meta/conversions`
4. Verifique os logs no Vercel Dashboard

### Eventos não aparecem no Meta?
1. Verifique se o Access Token está correto
2. Confirme se o Pixel ID está configurado
3. Teste com Test Event Code primeiro
4. Verifique se o IP está sendo capturado corretamente

### Erros de TypeScript?
1. O package inclui tipos completos
2. Use `import type` para importar apenas tipos
3. Verifique se o `tsconfig.json` inclui `node_modules`

## 🎉 Resultado Final

Com o setup automático, você terá:
- ✅ **Backend completo** - API routes prontas
- ✅ **IP real capturado** - Match rate 90%+
- ✅ **Debug automático** - Logs detalhados
- ✅ **Zero retrabalho** - Setup completo em um comando
- ✅ **Vercel ready** - Deploy automático

## 📄 Licença

MIT - Veja [LICENSE](LICENSE) para detalhes. 