# Especificação Completa - Cliente Windows NoIdle ## 📋 Visão Geral O cliente Windows deve monitorar e enviar para o servidor: 1. **Aplicativos ativos** (window_title, application_name) 2. **Histórico de navegação** (URLs do Chrome/Edge) 3. **Eventos de sessão** (logon/logoff do Windows) --- ## 🔌 Endpoints da API ### Base URL ``` https://admin.noidle.tech ``` --- ## 1️⃣ Registrar Atividade (Aplicativos) **Endpoint:** `POST /api/activity/log` **Frequência:** A cada 5-10 segundos (quando há mudança de aplicativo/janela) **Headers:** ``` Content-Type: application/json ``` **Body:** ```json { "device_id": "DEV-1762999424206-0BJR2Q", "window_title": "Documento - Word", "application_name": "WINWORD.EXE", "idle_time_seconds": 0, "urls": [ { "url": "https://example.com/page", "title": "Example Page", "browser": "Chrome" } ] } ``` **Campos Obrigatórios:** - `device_id` (string): ID único do dispositivo - `window_title` (string): Título da janela ativa (NÃO pode ser "System Idle" ou vazio) - `application_name` (string): Nome do executável (ex: "chrome.exe", "WINWORD.EXE", "notepad.exe") - `idle_time_seconds` (number): Tempo em segundos que o usuário está inativo (0 = ativo) **Campos Opcionais:** - `urls` (array): Array de objetos com histórico de navegação (ver seção 2) **⚠️ IMPORTANTE:** - **NÃO** envie `window_title = "System Idle"` ou `application_name = "[IDLE]"` quando o usuário está realmente usando um aplicativo - Se o usuário estiver inativo por mais de 30 segundos, aí sim pode enviar `idle_time_seconds > 0` - Capture o título real da janela e o executável real usando APIs do Windows **Exemplo de Resposta:** ```json { "success": true, "message": "Atividade registrada" } ``` --- ## 2️⃣ Histórico de Navegação (Chrome/Edge) **Endpoint:** `POST /api/activity/log` (mesmo endpoint, campo `urls`) **Frequência:** A cada vez que uma nova URL é visitada no navegador **Como Capturar:** - Use a API do Chrome/Edge para monitorar abas abertas - Capture URLs de todas as abas ativas - Envie no array `urls` dentro do mesmo POST de atividade **Estrutura do Array `urls`:** ```json { "urls": [ { "url": "https://www.google.com/search?q=exemplo", "title": "exemplo - Pesquisa Google", "browser": "Chrome" }, { "url": "https://github.com/user/repo", "title": "user/repo · GitHub", "browser": "Chrome" } ] } ``` **Campos:** - `url` (string): URL completa visitada - `title` (string): Título da página/aba - `browser` (string): "Chrome" ou "Edge" **⚠️ IMPORTANTE:** - Envie URLs de TODAS as abas abertas, não apenas a ativa - Atualize a lista sempre que uma nova aba for aberta ou fechada - Não envie URLs vazias ou inválidas --- ## 3️⃣ Eventos de Sessão (Logon/Logoff) **Endpoint:** `POST /api/activity/session` **Frequência:** Imediatamente quando ocorre logon ou logoff **Headers:** ``` Content-Type: application/json ``` **Body para LOGON:** ```json { "device_id": "DEV-1762999424206-0BJR2Q", "event_type": "logon", "username": "Sergio.Dev" } ``` **Body para LOGOFF:** ```json { "device_id": "DEV-1762999424206-0BJR2Q", "event_type": "logoff", "username": "Sergio.Dev" } ``` **Campos Obrigatórios:** - `device_id` (string): ID único do dispositivo - `event_type` (string): "logon" ou "logoff" - `username` (string): Nome do usuário do Windows **Como Capturar:** - Use eventos do Windows: `SessionSwitch`, `SessionLock`, `SessionUnlock` - Monitore o evento de logon do sistema operacional - Capture o username do usuário logado **Exemplo de Resposta:** ```json { "success": true, "message": "Evento logon registrado" } ``` --- ## 4️⃣ Heartbeat (Opcional mas Recomendado) **Endpoint:** `POST /api/devices/heartbeat` **Frequência:** A cada 30-60 segundos **Body:** ```json { "device_id": "DEV-1762999424206-0BJR2Q" } ``` **Nota:** O heartbeat é opcional se você estiver enviando atividades regularmente, mas ajuda a manter o dispositivo marcado como ativo. --- ## 🔧 Implementação Técnica ### Capturar Window Title e Application Name (C#/PowerShell) ```csharp using System; using System.Runtime.InteropServices; using System.Text; [DllImport("user32.dll")] static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); [DllImport("user32.dll")] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId); // Obter janela ativa IntPtr hwnd = GetForegroundWindow(); StringBuilder windowTitle = new StringBuilder(256); GetWindowText(hwnd, windowTitle, 256); // Obter processo uint processId; GetWindowThreadProcessId(hwnd, out processId); Process process = Process.GetProcessById((int)processId); string appName = process.ProcessName + ".exe"; ``` ### Capturar URLs do Chrome (PowerShell) ```powershell # Usar Chrome DevTools Protocol ou ler histórico do Chrome # Alternativa: usar extensão do Chrome que envia dados via API local ``` ### Capturar Eventos de Sessão (C#) ```csharp using Microsoft.Win32; SystemEvents.SessionSwitch += (sender, e) => { if (e.Reason == SessionSwitchReason.SessionLock) { // Logoff ou bloqueio } else if (e.Reason == SessionSwitchReason.SessionUnlock) { // Logon ou desbloqueio } }; ``` --- ## ✅ Checklist de Implementação - [ ] Cliente captura `window_title` real (não "System Idle") - [ ] Cliente captura `application_name` real (exe do processo) - [ ] Cliente envia atividades a cada 5-10 segundos quando há mudança - [ ] Cliente monitora e envia URLs do Chrome/Edge - [ ] Cliente detecta eventos de logon/logoff do Windows - [ ] Cliente envia eventos de sessão imediatamente - [ ] Cliente trata erros de rede e faz retry - [ ] Cliente valida dados antes de enviar --- ## 🐛 Troubleshooting ### Problema: Apenas "System Idle" aparece nas atividades **Solução:** Verifique se o código está capturando a janela ativa corretamente. Use `GetForegroundWindow()` e não confie em valores padrão. ### Problema: URLs não aparecem **Solução:** Verifique se o array `urls` está sendo enviado no POST `/api/activity/log` e se contém dados válidos. ### Problema: Eventos de sessão não aparecem **Solução:** Verifique se o cliente está escutando eventos do Windows corretamente e se está fazendo POST para `/api/activity/session`. --- ## 📞 Suporte Para problemas técnicos, verifique: 1. Logs do cliente (console/arquivo de log) 2. Logs do servidor: `pm2 logs pointcontrol-api` 3. Resposta HTTP dos endpoints (status code, mensagem de erro)