Open-Source Cold Email & Warmup Platform
Warmbly is the open-source platform for cold email: warm your mailboxes, send campaigns, and triage every reply. Run it on our cloud or self-host the whole thing.
Mais avaliações e mais destaque no Google Maps: placa com NFC para o cliente avaliar em um toque e um relatório por mês com sua posição, seus concorrentes e o que fazer para subir.
Translation pending
MarketingTypeScript · PLpgSQLGitHub @lucsa-devOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Painel para administrar os links gravados em TAGs NFC e QR Codes de cartões vendidos a negócios locais:
@perfil) ou a um site.Cada link ganha um endereço público https://seu-dominio.com.br/{negocio}/{link}, que conta o acesso, salva os dados do dispositivo e redireciona para a URL de destino.
| Camada | Tecnologia |
|---|---|
| App | Next.js 16 (App Router, Server Actions, proxy.ts) |
| UI | Tailwind CSS v4 + shadcn/ui (Base UI) + temas por variáveis CSS |
| Backend | Supabase (Auth, Postgres, RLS) |
| Testes | Vitest |
| Deploy | Vercel |
...?s=qr, para separar a origem nas estatísticas./comecar: busca o negócio no Google, mostra diagnóstico, meta, prazo estimado e kit recomendado, e captura o contato. Os pedidos aparecem em Painel → Pedidos, onde um clique cria o negócio e o link de avaliação./c/{codigo}), PDF de impressão com o QR de cada peça (gráfica: frente e verso em sequência; ou folhas A4) e CSV com os links para gravar nos chips NFC./relatorio/{token}, não indexado) para mandar ao dono pelo WhatsApp.GOOGLE_PLACES_API_KEY): a mesma busca feita de 25 pontos ao redor do negócio (grade 5×5, 600 m entre os pontos) pela Text Search da Places API, pedindo só o campo places.id.expires_at (30 dias), deixam de aparecer depois disso e são apagados pelo cron diário /api/cron/limpeza. Os dados da Apify não expiram.npm install
cp .env.example .env.local # preencha as variáveis
npm run dev
supabase/migrations/20261003000000_init.sql de uma destas formas:
supabase link --project-ref SEU_REF e depois npm run db:push.| Variável | Descrição |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | URL do projeto Supabase |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Chave publicável (sb_publishable_...) ou a antiga anon |
SUPABASE_SECRET_KEY | Chave secreta (sb_secret_...) ou a antiga service_role. Usada só no servidor, nas rotas públicas de redirecionamento e Pix |
NEXT_PUBLIC_SITE_URL | Domínio usado nos links das TAGs e QR Codes (ex.: https://cartoes.com.br) |
IP_HASH_SALT | Texto aleatório para anonimizar IPs (openssl rand -hex 32) |
GOOGLE_PLACES_API_KEY | Opcional. Google Places API (New): busca do negócio no quiz e na ativação. Sem ela, os formulários pedem nome e cidade |
APIFY_TOKEN | Token da Apify. Fonte das métricas do Google Maps (painel, Evolução, cron) via scraper |
APIFY_MAPS_ACTOR | Opcional. Actor do scraper (padrão compass~crawler-google-places) |
NEXT_PUBLIC_WHATSAPP_NUMBER | WhatsApp da TopTap (55 + DDD + número), usado no fim do quiz |
OPENAI_API_KEY | Chave da OpenAI para a análise do perfil no Google. Sem ela, o painel mostra só o checklist |
OPENAI_MODEL | Opcional. Modelo da análise (padrão gpt-5-mini) |
CRON_SECRET | Segredo do cron semanal /api/cron/google (a Vercel envia no cabeçalho Authorization) e do webhook da Apify |
Se NEXT_PUBLIC_SITE_URL não estiver definida, o sistema usa o domínio de produção da Vercel (VERCEL_PROJECT_PRODUCTION_URL).
/comecar)APIFY_TOKEN, a pessoa digita nome e cidade e clica em Buscar no Google (scraper da Apify, de 15 a 60 s, até 3 resultados). Cada busca fica em cache por 7 dias (maps_searches) e há limite de 5 buscas por hora por visitante. Sem nenhuma das duas, cadastro manual.leads e o cliente pode enviar o resumo pelo WhatsApp.O progresso é salvo a cada etapa (status quiz) e vira lead ao receber o WhatsApp. Kit, valor e prazo são recalculados no servidor. Preços em src/lib/pricing.ts; regras da projeção em src/lib/quiz.ts (PROJECTION: 26 dias × 1% dos clientes avaliando, ajuste com dados reais).
Painel → Cartões → Gerar lote (ex.: 50 cartões)
→ Imprimir (PDF com QR único por peça) → gráfica
→ Links (CSV) → gravar cada chip NFC na ordem
Cliente abre a peça (/c/k7m2p9qa)
├─ em branco → /c/k7m2p9qa/ativar → busca no Google → cria negócio + link de avaliação
│ → coleta do Google Maps + análise da IA (after())
└─ ativada → conta o acesso e redireciona para a avaliação (igual aos links normais)
g.page/r/.../review). Se o mesmo link (ou Place ID) já existir, a peça entra no mesmo negócio com o próprio link./conta)Na ativação, o dono informa e-mail e WhatsApp. Ele vira membro do negócio (business_members) e recebe um link mágico por e-mail. A área /conta mostra o plano, o histórico de relatórios mensais, as peças e os links, só para leitura. O primeiro membro entra ativo; quem chega depois fica aguardando a liberação no painel (página do negócio → Acesso do cliente). O painel /dashboard é só para quem está em admins; os outros usuários são levados para /conta.
Configuração no Supabase (Authentication):
https://toptap.com.br).supabase/templates/magic_link.html. O botão aponta para
{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email, que abre direto a /conta
em qualquer navegador (o modelo padrão manda o token no # da URL, que o app não lê).
Mesmo com o modelo padrão (em inglês), o link funciona: o Supabase volta com a sessão no # da URL e o
componente SessionFromHash (layout raiz) grava a sessão e abre a /conta.
Os outros modelos (Confirm signup, Invite user, Reset password, Change email address e Reauthentication)
ficam em supabase/templates/ com o mesmo visual, e os assuntos em supabase/config.toml. Os botões também
apontam para /auth/confirm (com type=signup, invite, recovery ou email_change). Como o app não tem
tela de nova senha, o de recuperação só faz o login.O Google Maps Scraper da Apify busca cada negócio (por Place ID ou por "Nome, Cidade - UF") e traz nota, avaliações, distribuição de estrelas, total de fotos, horário, contato e as 20 avaliações mais recentes (com a resposta do dono).
Ativação / "Atualizar dados" → execução síncrona (até ~4 min) → place_snapshots (+ place_id no negócio)
Cron semanal (segunda, 6h) → 1 execução com todos os clientes → Apify chama /api/apify/webhook → place_snapshots
TAG NFC → /padaria/avaliacao ─┐
QR Code → /padaria/avaliacao?s=qr ─┤→ busca link ativo → 302 para a URL de destino
└→ after(): grava o acesso em link_visits
(gatilho incrementa links.click_count)
after()), então o cliente não espera o banco.Cache-Control: no-store, para que nenhum acesso deixe de ser contado.SHA-256(salt + IP), o que basta para contar visitantes únicos (LGPD)./{negocio}/{link}/pix, que gera o BR Code conforme o manual do Banco Central.src/app/globals.css, nos blocos :root (claro) e .dark (escuro), no padrão de variáveis do shadcn/ui. Para mudar o visual, troque os valores ali.next-themes).src/components/brand/logo.tsx e arquivos originais em public/brand/.npm test # roda uma vez
npm run test:watch # modo observação
npm run typecheck
npm run lint
Os testes unitários ficam em src/lib/__tests__ e cobrem:
| Módulo | O que é testado |
|---|---|
slug | geração de endereços (acentos, símbolos), validação, slugs reservados |
urls | URL da TAG/QR, domínio base, normalização de destino (@perfil, sem https://, protocolos inválidos) |
user-agent | detecção de navegador/app, sistema, tipo de aparelho, fabricante e robôs |
visit | IP via proxy, hash do IP, origem NFC/QR, idioma, geolocalização da Vercel |
redirect | decisão de redirecionamento, página Pix, 404, registro adiado do acesso |
pix | CRC16, BR Code (incluindo o exemplo oficial do Banco Central), chaves CPF/CNPJ/telefone/e-mail/aleatória |
analytics | totais, únicos, série diária no fuso de São Paulo, agrupamento "Outros", períodos |
validation | formulários de negócio, link e login |
csv | escape RFC 4180 e proteção contra injeção de fórmulas |
src/
app/
[business]/[link]/route.ts redirecionamento público + contagem
[business]/[link]/pix/page.tsx página Pix Copia e Cola
dashboard/ painel (negócios, links, estatísticas, CSV)
login/ login
components/
dashboard/ formulários, QR Code, gráficos
theme/ provedores e seletor de tema
ui/ componentes shadcn/ui
lib/ regras de negócio (testadas) e clientes Supabase
proxy.ts sessão e proteção do /dashboard
supabase/migrations/ schema, RLS e gatilhos