---
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]]