O projeto é uma aplicação desktop desenvolvida com Electron, focada em privacidade e funcionamento local.
- Monorepo: Organizado em dois diretórios principais:
application/: O código-fonte da aplicação Electron.website/: A landing page promocional.
- Core (Backend Local):
- Utiliza o whisper.cpp (implementação C++ do modelo Whisper da OpenAI) para realizar a transcrição de áudio.
- Isso garante performance nativa e que nenhum áudio saia da máquina do usuário (Privacidade 100%).
- Interface e UX:
- Funciona como um aplicativo de barra de menu (Tray App).
- Possui janelas flutuantes ("Overlay") para feedback visual.
- Usa Global Hotkeys (atalhos globais) para iniciar/parar a gravação, interceptados pela biblioteca
uiohook-napi.
- Fluxo de Dados:
- Usuário aperta o atalho.
- Renderer (Frontend) captura o áudio do microfone.
- Áudio é salvo temporariamente (
recording.wav). - Main Process invoca o binário
whisper-clilocalmente. - Texto transcrito é inserido diretamente no campo de texto ativo do usuário (simulando digitação via scripts de SO), sem usar a área de transferência para não sobrescrever dados do usuário.
Para transformar este aplicativo local em um serviço pago (SaaS), você precisará de três pilares principais: Provedor de Pagamento, Backend de Controle e Integração no Cliente.
Você precisa de um serviço para processar cartões e gerenciar assinaturas.
- Lemon Squeezy (Recomendado): Atua como "Merchant of Record". Eles lidam com todos os impostos globais, faturas e conformidade. Muito fácil de integrar com apps software.
- Stripe: Padrão da indústria. Mais flexível, mas exige que você lide com algumas questões fiscais.
- Paddle: Similar ao Lemon Squeezy, excelente para vendas globais de software.
Como o Whisper roda localmente, o app "funciona" sem internet. Para cobrar, você precisa validar se o usuário tem permissão para usar.
- Função: Validar chaves de licença ou logins de usuário.
- Tecnologias: Pode ser simples. Um banco de dados (Supabase, Firebase) e uma API pequena (Node.js/Express, Python/FastAPI ou Serverless Functions no Vercel/Cloudflare).
- O que armazenar:
user_idsubscription_status(active, past_due, canceled)expiration_datelicense_key(opcional, se não usar login/senha)
-
Mecanismo de Bloqueio:
- Ao iniciar, o app deve verificar se existe uma licença válida salva (
electron-store). - Se não houver, deve bloquear as funcionalidades principais (transcrição) e mostrar apenas uma tela de "Login" ou "Inserir Licença".
- Ao iniciar, o app deve verificar se existe uma licença válida salva (
-
Verificação de Licença (Online Check):
- Login: O usuário digita email/chave.
- Validação: O app envia isso para seu Backend.
- Resposta: O backend consulta o Stripe/LemonSqueezy e responde se está
ativo.
-
Segurança e Offline (Desafio de Apps Locais):
- Como bloquear alguém que desliga a internet?
- Estratégia Comum: "Token JWT com validade". Ao logar, você salva um token criptografado localmente que vale por 3 a 7 dias. O app funciona offline com esse token. Quando expira, ele força uma verificação online.
- Ofuscação: O código fonte Electron pode ser lido. Use ofuscação de código (javascript obfuscators) para dificultar que usuários removam a verificação de licença manualmente.
- Modelo de Licença (License Key): É mais simples que sistema de login completo. O usuário compra, recebe uma chave (ex:
KEY-1234), e insere no app. - Serviço: Use Lemon Squeezy com o recurso nativo de License Keys. Eles já geram a chave e oferecem uma API para você validar (
GET https://api.lemonsqueezy.com/v1/licenses/validate).- Vantagem: Você não precisa criar backend próprio no início. O Electron chama direto a API do Lemon Squeezy.
- Integração:
- Crie uma tela de "Ativação".
- No
main.js, antes detranscribe(), verifique:if (!isLicenseValid) showUpgradeDialog(); return;.
- Usuário compra no seu site -> Lemon Squeezy envia email com Chave de Licença.
- Usuário abre o App -> App pede a Chave.
- App faz request:
POST https://api.lemonsqueezy.com/v1/licenses/activate. - Se sucesso, salva a licença e a "instance_id" no
electron-store. - A cada inicialização (ou a cada X dias), o app revalida a chave silenciosamente.