--- tags: [projeto, intranet, sessao, cobranca, social-media, notifier, whatsapp] date: 2026-04-27 --- # Sessão 27/04/2026 — Múltiplas frentes Sessão longa cobrindo cobrança, social media (cronograma + demandas), notifier (proteção SYSTEM via MeshCentral) e WhatsApp LID/verifiedBizName. ## 1. Cobrança — tom amigável antes do vencimento **Problema**: cliente recebia "📋 LEMBRETE DE COBRANÇA / boleto pendente" para boleto que ainda iria vencer em 4 dias. Tom soava ofensivo para cliente em dia. **Fix em** `app/Controllers/CronCobrancaAutomatica.php:gerarMensagemConsolidada`: - Guard no início: se TODOS os pendentes têm `diasAteVencimento > 0` → delega pra nova função `gerarMensagemLembretePreVencimento` - Tom novo: "🔔 Lembrete de Pagamento / Olá Nome! 😊 / Passando para lembrar do seu boleto a vencer..." - A partir do dia do vencimento (`dias <= 0`) → mantém template antigo (cobrança) Detalhes em [[cobranca-tom-pre-vencimento-2026-04-27]]. ## 2. Social Media — Reenviar cronograma apagava campos **Bug**: função `reenviarCronograma()` em `app/Views/social_media/index.php:1501` foi escrita quando o modal "Planejamento recusado" tinha 1 textarea só. Hoje tem 3 (planejamento, legenda, hashtags), mas a função: - Lia `epConteudo` (Legenda) e mandava como `planejamento` → embaralhava - Forçava `conteudo=''` e `hashtags=''` → apagava **Fix**: usar `coletarFormData()` (mesma função do botão Salvar) que lê os 3 IDs corretos. Detalhes em [[social-reenviar-cronograma-fix-2026-04-27]]. ## 3. Hashtags solta no modal de aprovação do cliente **Local**: `app/Views/area_cliente/social/calendario.php` linha ~334. Hashtags renderizavam como `
` solto. Reformulado para usar mesmo padrão recolhível dos blocos Planejamento (amarelo) e Conteúdo (azul claro), com header "HASHTAGS" + ícone `bx-hash`, cor `#1d4ed8`. ## 4. Demanda — descrição limpa + anexo não baixava **4.1. Descrição da demanda criada por aprovação de cronograma social**: Removido "Conteúdo sugerido" e "Hashtags" da descrição (cliente aprova só o planejamento; conteúdo é trabalho do colaborador). Em `app/Libraries/SocialDemandaService.php` (2 lugares: `criarDemandasParaCronograma` linha ~94 e `criarDemandaParaPost` linha ~205), também na obs do histórico. **4.2. Anexo da demanda não baixava** (`app/Controllers/Demandas.php:downloadAnexo`): Caminho era salvo como `'uploads/demandas/...'` (relativo a `WRITEPATH`) mas o download usava `ROOTPATH . $caminho` → procurava fora do `writable/`. Trocado por `WRITEPATH` com fallback pro caso de registros antigos com prefixo "writable/". ## 5. Demanda → Aprovação não disparava WhatsApp + status não mudava **Sintoma**: usuário (Jesiel Telles) atendia demanda atrelada a planejamento aprovado, finalizava, empurrava pra "Aguardando aprovação". Mas no calendário o post continuava em "aceito", não chegava WhatsApp pro cliente. **Causa**: `SocialDemandaService::onDemandaConcluida` (`app/Libraries/SocialDemandaService.php:252`) tinha early return em `if ($midiasExistentes > 0) return true;`. Quando o post já tinha mídia anexada manualmente (caso do Jesiel — anexou via modal antes de empurrar a demanda), retornava ANTES de: - Marcar `aprovacao_status='pendente'` - Gerar `aprovacao_token` - Vincular `social_post_redes` - Enviar WhatsApp pro cliente **Fix**: trocou o `return true` por flag `$pularCopia = $midiasExistentes > 0;` que só pula o **bloco de cópia de mídias** mas continua o restante do fluxo (token + redes + WhatsApp). **Caso atual reparado manualmente**: post 210 (cliente Jesiel Telles - Teste, demanda 2092) — SQL setou `aprovacao_status=pendente` + token de 4h. ## 6. WhatsApp LID — `verifiedBizName` ignorado no caminho LID **Sintoma**: contato `LID 91466328...` aparecia como nome no chat. Era na verdade conta WhatsApp Business "Atos Comercial". **Investigação**: log do Baileys (`pm2 logs api-teste2`) mostrava: ``` [LID] 91466328182835@lid -> UNKNOWN pushName=none extra={"verifiedBizName":"Atos Comercial",...} ``` WhatsApp Business **não envia `pushName`** — envia `verifiedBizName`. O webhook PHP usava esse campo APENAS no caminho normal `@s.whatsapp.net`. No caminho LID (`@lid`), ignorava `verifiedBizName` e caía em `'LID ' . substr($lidValue, 0, 8) . '...'`. **Fix em** `app/Controllers/WhatsApp.php:handleIncomingWebhookMessage`: ```php $nomeReal = $pushName ?: $verifiedBizName; // usado em todos os pontos LID ``` 3 pontos atualizados (criação, update LID existente, update contato genérico). Também detecção expandida de "nome temporário" (regex pega `LID xxx...`, `lid_xxx`, dígitos puros, igual ao phone). Fallback adicional: cache `whatsapp_lid_names` quando nem `pushName` nem `verifiedBizName` chegam. **Aprendizado importante**: NUNCA assumir "WhatsApp esconde". Sempre olhar o log real do Baileys (`pm2 logs api-teste2 --lines 1000 | grep "[LID]"`) — ele mostra todos os campos disponíveis no payload. ## 7. Varredura retroativa LID/phone Tentativa de recuperar nomes antigos via: - 217 LIDs do `contacts_cache.json` do Baileys → 0 matches (banco não tinha o LID populado) - 126 phones do mesmo cache → 1 match (atualizado) - 1 LID via `whatsapp_lid_names` → atualizado **Sobraram 240 contatos com `nome=phone_number`**. Esses não estão em nenhum cache nem em `clientes`. Vão se atualizar automaticamente quando enviarem nova mensagem com `pushName`/`verifiedBizName` (graças ao fix do regex). ## 8. Notifier — proteção SYSTEM via MeshCentral (v1.8.2 → v1.8.4) **Problema**: Erick (atendente, sem admin local, máquina 10.0.0.20) conseguia fechar o Notifier via Task Manager. **v1.8.2**: Defesa em camadas: - Watchdog VBS: 15s → **5s** - 2 Scheduled Tasks user redundantes (1 com nome camuflado), interval 1min, `Duration P9999D` - Monitor interno re-instala tasks a cada 30s **v1.8.3**: Notificações refinadas: - Demandas: lembrete a cada **10 minutos** (era 60s — chato) - Chat / WhatsApp / Social: **uma vez só** (alerta rápido) **v1.8.4 — DEFINITIVA**: Proteção SYSTEM via MeshCentral. - Aproveita que o MeshAgent já está rodando como SYSTEM em todas as máquinas - Notifier solicita ao servidor → mesh-share-api dispara `meshctrl runcommand --powershell` no node alvo → MeshAgent SYSTEM baixa script de `/api/notifier/protection-script` e executa - Script cria task SYSTEM em `\Microsoft\Windows\Maintenance\GoTechBR Watcher` que reaplica as 2 tasks user a cada 1min - **0 prompt UAC, 0 interação do atendente** - Atendente **não pode deletar** task SYSTEM (precisa admin) **Endpoints novos**: - `GET /api/notifier/protection-script` (público) — serve PS1 do `writable/downloads/` - `POST /api/notifier/instalar-protecao` (autenticada) — pega `mesh_node_id` do heartbeat e dispara - `POST :8002/install-protection` no mesh-share-api — executa via meshctrl **Arquivos novos**: - `writable/downloads/notifier-protection.ps1` - `desktop-notifier/gotech_notifier/protection.py` **ATENÇÃO**: ainda não validei se a v1.8.4 chegou em todas as máquinas e se a task SYSTEM foi instalada — usuário pode confirmar via `schtasks /Query /TN "Microsoft\Windows\Maintenance\GoTechBR Watcher"` em qualquer máquina. Detalhes completos em [[notifier-defesa-reforcada-2026-04-27]]. ## Arquivos modificados (principais) | Arquivo | Mudança | |---------|---------| | `app/Controllers/CronCobrancaAutomatica.php` | Tom amigável pré-vencimento (gerarMensagemLembretePreVencimento) | | `app/Views/social_media/index.php` | reenviarCronograma usa coletarFormData | | `app/Views/area_cliente/social/calendario.php` | Bloco hashtags recolhível | | `app/Libraries/SocialDemandaService.php` | $pularCopia em vez de early return + descrição limpa | | `app/Controllers/Demandas.php` | downloadAnexo usa WRITEPATH com fallback ROOTPATH | | `app/Controllers/WhatsApp.php` | $nomeReal = pushName ?: verifiedBizName + regex temp expandido | | `app/Controllers/Api.php` | notifierProtectionScript + instalarProtecaoNotifier | | `app/Config/Routes.php` | 2 rotas novas pra protection | | `desktop-notifier/gotech_notifier/__init__.py` | Bumps 1.8.1 → 1.8.4 | | `desktop-notifier/gotech_notifier/watchdog.py` | 5s + 2 tasks redundantes + Duration P9999D | | `desktop-notifier/gotech_notifier/notifier.py` | Demandas 60s → 600s | | `desktop-notifier/gotech_notifier/toast.py` | Social adicionado a "uma vez só" | | `desktop-notifier/gotech_notifier/protection.py` | NOVO - solicita protection ao servidor | | `desktop-notifier/gotech_notifier/main.py` | Chama protection.request_system_protection | | `writable/downloads/notifier-protection.ps1` | NOVO - script SYSTEM | | `writable/downloads/GoTechBR-Notifier.zip` | v1.8.4 (32MB, MD5 04a8e583...) | | `/root/mesh_share_api.js` (Baileys) | Endpoint /install-protection | ## Lições aprendidas 1. **Nunca assumir "X é impossível por design"** sem olhar os logs reais. O caso do `verifiedBizName` foi um errinho meu — quase mandei o usuário editar manualmente quando o nome já chegava no payload do Baileys. Sempre `pm2 logs ... | grep` antes de concluir. 2. **Catch-22 do Windows admin**: pra criar task SYSTEM precisa admin uma vez. A solução foi aproveitar uma camada que JÁ estava como SYSTEM (o MeshAgent), em vez de tentar elevar o Notifier. Reuso > nova permissão. 3. **Early returns "sutis" são minas**: o `return true` no `onDemandaConcluida` parecia uma otimização ("já tem mídia, não precisa copiar"), mas estava pulando 70% do que a função deveria fazer. Quando uma função tem N efeitos colaterais (atualizar status + token + redes + WhatsApp), early return só pode ser usado se TODOS já foram feitos. 4. **Comentários ficam fósseis**: o "epConteudo no modo 3 é o PLANEJAMENTO" no `reenviarCronograma` era verdade no passado. Quando o modal evoluiu para 3 campos separados, ninguém atualizou a função. Comentários explicando "X significa Y" envelhecem rápido. ## Relacionados - [[cobranca-tom-pre-vencimento-2026-04-27]] - [[social-reenviar-cronograma-fix-2026-04-27]] - [[notifier-defesa-reforcada-2026-04-27]] - [[preferencias-usuario]]