Publicidade

Inteligência Editorial + Comercial

Camada adicionada ao pipeline automático do Portal Ao Vivo. Complementa o fluxo existente (coleta -> resumo IA -> imagem -> publicação -> redes sociais) sem substituí-lo: se o Gemini não estiver disponível, tudo funciona via regras locais.

Escopo

Novo foco

Novo foco (2026): o portal agora publica APENAS conteúdo que gere clientes — matérias sobre eventos ou com potencial comercial (patrocínio, transmissão, esporte com apelo). Política, polícia, crime, acidentes, falecimentos, concurso público e curiosidades são descartados pelo pipeline. A prospecção (commercial_prospecting.py) gera uma fila de aprovação (data/outbox.json) para o diretor comercial decidir manualmente.

Arquitetura

config/commercial_rules.json     -> triggers, alvos, parágrafos comerciais, lead
config/social_rules.json         -> pesos de priorização, CTAs, hashtags
config/prospecting_rules.json    -> janelas, clientes, serviços, rascunhos, pesos
scripts/analyze_article.py       -> análise (IA via Gemini ou regras locais)
scripts/event_detector.py        -> detecção de evento + leads
scripts/commercial_radar.py      -> TOP OPORTUNIDADES (ranking por lead_score)
scripts/commercial_prospecting.py-> prospecção inteligente (janela/prioridade/rascunho)
scripts/summarize.py             -> resumo com parágrafo comercial opcional
scripts/publish.py               -> frontmatter expandido (compatível Jekyll)
scripts/social_poster.py         -> ordenação por prioridade + legendas estruturadas
scripts/social_poster.py         -> interesse_comercial(): filtra SOCIAL por evento/foco
scripts/pipeline.py              -> integração das etapas 1/8 a 8/8 (filtro de foco ETAPA 3)
data/commercial_leads.json       -> oportunidades comerciais consolidadas
data/outbox.json                 -> fila de aprovação (envio sempre manual)
data/pending_social.json         -> fila social (purge por interesse_comercial)
scripts/test_commercial_intelligence.py -> testes obrigatórios (7 casos)
scripts/test_prospecting.py      -> testes obrigatórios de prospecção (10 cenários)

Filtro de foco (publica só o que gera clientes)

Em scripts/pipeline.py, logo após a análise (ETAPA 3), cada matéria passa por interesse_comercial(analise):

O social_poster.py aplica o mesmo conceito (interesse_comercial) na fila social: itens antigos sem análise só são publicados se o título indicar evento/patrocínio, e conteúdo negativo (crime/falecimento/previsão do tempo/ concurso/política) é sempre bloqueado, mesmo que uma análise antiga tenha atribuído score comercial alto. Editais de convocação de servidores são descartados; licitações/festivais de pratos típicos passam.

A pesquisa viral de curiosidades (research_viral) está desativada no pipeline por fugir do foco comercial.

Scores (0 a 10)

Score Significado
editorial_score Valor jornalístico/regional da notícia
commercial_score Potencial comercial (0-4 neutro, 5-6 editorial, 7-8 discreto, 9-10 CTA direto)
instagram_score Potencial de engajamento/formatos (Reel, Stories, Carousel)

Regra principal: NOTÍCIA > PROPAGANDA. Quanto maior o score comercial, mais suave e contextual é a menção.

Radar de oportunidades comerciais (lead_score)

Cada lead recebe um lead_score (0 a 10, 1 casa decimal) que pondera:

Fator Peso Como mede
commercial_score 0.30 /10
proximidade 0.25 janela ideal 1-15 dias (60d < 15d)
porte 0.15 público esperado / porte
tipo do evento 0.08 campeonato, festival, feira, congresso…
cidade 0.05 cidade monitorada da região
recorrência 0.05 evento tradicional/anual (Festa do Café, jubileu)
patrocinadores 0.05 presença de patrocinadores/marcas
organizador 0.02 organizador identificável
transmissão 0.03 potencial de transmissão
conteúdo 0.02 potencial Instagram/editorial

Exemplo prático (mesmo score comercial):

scripts/commercial_radar.py imprime o ranking no log do pipeline e em um passo dedicado do GitHub Actions:

 1. Festa do Café [Patrocínio] - 8.8 (em 15d, novo)
 2. Leilão agropecuário [Vazante] - 8.4 (em 7d, contatado)
 ...

Prospecção inteligente (janela e prioridade de contato)

scripts/commercial_prospecting.py responde a duas perguntas por lead: QUEM contratar e QUANDO prospectar. É um enriquecimento acoplado ao lead (não depende de terceiros) e é só rascunho: NUNCA envia mensagem.

Preenchimento automático (enriquecimento)

Toda nova notícia registrada passa por enriquecer_lead() (chamado dentro de event_detector.registrar_lead()):

Janelas por tipo (config/prospecting_rules.json -> windows)

Grupo monitoring prospecting_start priority_days urgent_high urgent too_late
default 90 60 30 20 7 2
festival 90 90 45 20 7 2
sports 90 45 30 20 7 2
corporate 90 60 40 20 7 2
education 90 50 25 20 7 2
religious 90 75 40 20 7 2

Classificação por dias até o evento: evento passado -> não prospectar; dias >= monitoring -> monitorar; dias <= too_late -> muito tarde; dias <= urgent -> urgente; dias <= urgent_high -> urgente; dias <= priority_days -> prioridade/urgente; dias <= prospecting_start -> prioridade; senão -> prospectar. Evento sem data -> monitorar; evento hoje -> urgente/muito_urgente.

Boost de prioridade (+1 degrau) quando o evento é recorrente (tradicional/ anual/edição) ou tem histórico nos leads (previous_event_detected) ou lead_score >= 9.

TOP PROSPECÇÃO

top_prospeccao() / print_painel_prospeccao() ordenam pelos critérios: prospecting_score (desc) e depois a escada de prioridade. Exclui eventos passados. O pipeline imprime o painel ao final e o GitHub Actions roda um passo dedicado:

Prioridade: URGENTE | Score: 8.5 | Festa do Café [Patrocínio] - em 12 dias
Prioridade: ALTO   | Score: 7.6 | Campeonato Regional [Patos de Minas] - em 30 dias

Sem conflito com o status

prospecting_priority é um campo derivado, recalculado a cada enriquecimento; não substitui o status do ciclo de vida (novo -> monitorando -> contatado -> proposta_enviada -> fechado | perdido). Re-registrar a mesma notícia preserva status/observações/histórico e atualiza prioridade, janela e rascunho.

Funil de acompanhamento (manual)

commercial_prospecting.resumo_funil() agrupa os leads ativos pelo momento de prospecção, para o diretor comercial:

Os campos contato_status e ultima_contato são de acompanhamento manual (ex.: primeiro_contato, proposta_enviada, fechado, perdido). O sistema apenas os preserva no enriquecimento, nunca os preenche nem envia nada.

Relatório diário (artefato markdown)

commercial_prospecting.gerar_relatorio_diario() grava data/prospeccao.md ao final do pipeline com: agenda de contato por prioridade, prioridade de hoje, leads perdendo o timing, eventos passados, rascunhos de abordagem (suggested_outreachnão enviados) e a fila de aprovação (outbox). O GitHub Actions faz upload do arquivo como artefato (prospeccao-diaria) e o commit do estado inclui o relatório em data/.

Outbox — fila de aprovação semi-manual (ETAPA 5)

O pipeline gera data/outbox.json — uma fila de rascunhos prontos para o diretor comercial decidir. O sistema nunca envia nada; apenas GERA a fila. Funções em commercial_prospecting:

Status possíveis: pendente, aprovado, enviado, descartado, adiado.

O relatório diário, o pipeline.py e o workflow (pipeline.yml) incluem a outbox: o workflow commita data/outbox.json junto com o estado.

Dashboard web (local-admin, aba Prospecção)

O painel de controle real é o local-admin/app.py (Flask local, gitignored). Ao adicionar a aba Prospecção ele carrega data/outbox.json do repositório (GitHub API) e permite, 100% manual: Marcar enviado, Aprovar, Adiar ou Descartar cada item — que é salvo de volta em data/outbox.json com commit to repositório. Nenhuma confirmação envia mensagem; o dashboard só registra a decisão do diretor.

Scoring pondera porte e público estimado

prospecting_score usa o fator porte/público estimado (_porte_score de event_detector): eventos grandes (ex.: 60 mil pessoas) pontuam acima de eventos pequenos com proximidade e scores semelhantes. Validado por cenário de teste (C12).

Tipos de evento (galeria)

Tipos cobertos pelo detector (_detectar_tipos) e pelas regras de prospecção: festival, festa, feira, show, rodeio, cavalgada, romaria, corrida, maratona, campeonato, torneio, exposição, agropecuária/leilão, congresso, conferência, encontro cultural, formatura, festa religiosa, inauguração, evento empresarial. Cada tipo tem cliente provável, serviços, dor, janela e rascunho próprios em config/prospecting_rules.json. status/observações/histórico e atualiza prioridade, janela e rascunho.

Ciclo de vida do lead (simples, sem CRM)

Arquivo data/commercial_leads.json com o schema:

{
  "lead_score": 8.8,
  "priority": "FORTE",
  "event_name": "Festa do Café",
  "event_type": "festa",
  "city": "Patrocínio",
  "event_date": "2026-09-25",
  "days_until_event": 15,
  "event_timing": "em_breve",
  "organizer": "Prefeitura de Patrocínio",
  "estimated_audience": 10000,
  "porte": "grande",
  "recurring": true,
  "edition": 10,
  "sponsors": [],
  "sponsors_count": 0,
  "source": "Patrocinio Online",
  "source_url": "https://...",
  "commercial_angle": "alcance",
  "suggested_services": ["transmissao ao vivo"],
  "target_customer": ["organizador de eventos"],
  "commercial_score": 8,
  "instagram_score": 8,
  "transmission_opportunity": 9,
  "status": "novo",
  "detected_at": "...",
  "updated_at": "...",
  "event_id": "...",
  "lead_id": "...",
  "recurring_event": true,
  "recurrence_pattern": "anual",
  "previous_event_detected": true,
  "organizer_type": "Prefeitura",
  "organizer_source": "Citado na notícia de ...",
  "organizer_url": "",
  "sponsors_detected": true,
  "sponsors_evidence": ["..."] ,
  "potential_client_type": ["organizador de eventos"],
  "recommended_services": ["transmissao ao vivo"],
  "commercial_need": "...",
  "contact_window": "prospectar_prioridade",
  "recommended_contact_window": "20 a 45 dias antes",
  "prospecting_priority": "urgente",
  "contact_reason": "...",
  "suggested_outreach": "...",
  "contact_history": [],
  "notes": "",
  "prospecting_score": 8.5,
  "sources": []
}

Os campos adicionados vêm da prospecção inteligente (ver seção acima). Para contact_reason/suggested_outreach serem (re)gerados automaticamente, o lead precisa estar ativo e com lead_score >= 8; prioridades antigas são atualizadas a cada novo registro da mesma notícia.

status segue o ciclo: novo (inicial) -> monitorando -> contatado -> proposta_enviada -> fechado | perdido. O pipeline NUNCA regressa o status: só cria/atualiza novo. Tipos de evento ainda não detectados foram adicionados: corrida/maratona, leilão/agropecuária, formatura, festa religiosa, conferência e inauguração.

Detecção de eventos

event_detector.detectar_evento() extrai a partir da notícia, sem inventar dados:

Leads comerciais

event_detector.registrar_lead() grava em data/commercial_leads.json quando:

  1. event_related == true E commercial_score >= lead.min_score (padrão 5).
  2. Chave única: nome do evento | cidade | data (sem duplicação).
  3. Fontes múltiplas consolidam os campos vazios do mesmo evento.

Cada lead guarda: organizador, tipo, porte, público esperado, score, ângulo, serviços sugeridos, fonte e prioridade (BAIXA/MEDIA/FORTE/MUITO FORTE).

Serviços e ângulos comerciais

Definidos em config/commercial_rules.json:

Conteúdo social

analyze_article.gerar_conteudo_social() produz (IA ou template):

CTA e hashtags por ângulo vêm de config/social_rules.json.

Priorização do Instagram

social_poster.calcular_priority_score() pondera (pesos em social_rules.json):

views (+1.0 até o teto)  +  instagram_score (x2)  +  commercial (x2)
+ regional (x1.5)        +  evento (x1.5)

postar_materias() ordena a fila por prioridade antes de postar.

Frontmatter

publish.py adiciona (sem quebrar os campos atuais):

categoria: eventos
editorial_score: 7
commercial_score: 8
instagram_score: 7
event_related: true
generate_reel: true
generate_cta: true
event_type: festival
event_types:
  - festival
commercial_angle: alcance
target_customer: ...
suggested_service: ...
reason: ...
instagram_hook: ...
instagram_script: ...
instagram_caption: ...

Como ajustar

Edite apenas os JSONs de config/; não precisa mexer no código:

Testes

python scripts/test_commercial_intelligence.py    # sem API: usa regras locais
python scripts/test_prospecting.py                # ETAPA 3: prospecção (10 cenários + ETAPAS 4 e 5)

Cobre: festival municipal futuro, final de campeonato regional, lançamento de câmera profissional, festival com público recorde, reunião administrativa, congresso empresarial regional, notícia política sem evento, classificação temporal (passado/em breve/futuro), ranking por proximidade (15 dias > 60 dias), ciclo de vida do status, radar TOP 10, conteúdo social, frontmatter e imports do pipeline antigo.

test_prospecting.py cobre os 10 cenários de prospecção (festival em 15 dias, campeonato em 30, congresso em 90, evento passado, sem data, evento recorrente, com/sem patrocinadores, empresarial e esportivo) e valida: nunca envia mensagem (só rascunho suggested_outreach), nunca inventa contato (organizador vem da notícia, organizer_url vazio), a prioridade de prospecção não substitui o status, o TOP PROSPECÇÃO é ordenado por prospecting_score, o painel imprime sem quebrar, o funil/relatório markdown são gerados, o scoring pondera porte/público e a outbox entra na fila apenas com leads fortes, preservando a decisão manual de envio (ETAPA 5).

Resultado esperado: 21 OK / 0 FALHAS em test_prospecting.py e 10 OK / 0 FALHAS em test_commercial_intelligence.py.