Open-Source Cold Email & Warmup Platform
Warmbly는 메일함을 예열하고 캠페인 전송·답변 triage를 지원하는 오픈소스 콜드 이메일 플랫폼입니다
Google 지도에서 더 많은 평가와 노출을 위해 NFC 플레이트로 한 번 터치해 고객이 평가하고, 월간 위치·경쟁사·상승 전략 보고서 제공
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.
마케팅TypeScript · PLpgSQLGitHub @lucsa-dev온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
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