import streamlit as st import pandas as pd import time import os from datetime import datetime import pytz from apscheduler.schedulers.background import BackgroundScheduler from monitor_logic import run_monitor_check, diagnose_n8n_webhook # Carregar timezone da variável de ambiente (padrão: America/Sao_Paulo) TIMEZONE = os.getenv("TIMEZONE", "America/Sao_Paulo") tz = pytz.timezone(TIMEZONE) # ===== Configuração da Página (DEVE ser a primeira chamada Streamlit!) ===== st.set_page_config( page_title="Monitor Evolution API", page_icon="🤖", layout="wide" ) # Função para gerar tabela HTML customizada def gerar_tabela_html(logs): """Gera tabela HTML com estilos inline para garantir funcionamento.""" if not logs: return "" # Estilos inline estilo_tabela = "width: 100%; border-collapse: collapse; margin-top: 10px;" estilo_header = "background-color: #f0f2f6; padding: 12px 15px; text-align: center; font-weight: bold; font-size: 16px; border-bottom: 2px solid #ddd;" estilo_celula = "padding: 10px 15px; text-align: center; font-size: 14px; border-bottom: 1px solid #eee;" estilo_celula_detalhes = "padding: 10px 15px; text-align: left; font-size: 14px; border-bottom: 1px solid #eee;" html = f'' # Cabeçalho html += '' html += f'' html += f'' html += f'' html += f'' html += f'' html += '' # Corpo html += '' for log in logs: html += '' html += f'' html += f'' html += f'' html += f'' html += f'' html += '' html += '
HoraStatusWhatsAppEmailDetalhes
{log["Hora"]}{log["Status"]}{log["WhatsApp"]}{log["Email"]}{log["Detalhes"]}
' return html # ===== Inicializar estado da sessão ===== if 'logs' not in st.session_state: st.session_state['logs'] = [] if 'last_run' not in st.session_state: st.session_state['last_run'] = "Nunca" if 'intervalo_horas' not in st.session_state: st.session_state['intervalo_horas'] = 3 # ===== Função wrapper para o Scheduler gravar logs ===== def scheduled_job(): """Executa verificação agendada (roda em background thread).""" now = datetime.now(tz) print(f"[{now}] Executando verificação agendada...") status, messages, whatsapp_status, email_status = run_monitor_check() print(f"Status: {status} | WhatsApp: {whatsapp_status} | Email: {email_status}") print("\n".join(messages)) # ===== Configurar o Agendador (Singleton via cache_resource) ===== @st.cache_resource def init_scheduler(intervalo_horas): scheduler = BackgroundScheduler(timezone=TIMEZONE) # Job com intervalo configurável a partir de 00:00 scheduler.add_job( scheduled_job, 'interval', hours=intervalo_horas, start_date='2025-01-01 00:00:00' ) scheduler.start() return scheduler scheduler = init_scheduler(st.session_state['intervalo_horas']) # ===== Interface Principal ===== st.title("🤖 Monitor Evolution API + Webhook") st.markdown("---") # Métricas superiores col1, col2 = st.columns(2) with col1: st.metric(label="Última Verificação", value=st.session_state['last_run']) with col2: st.write("### Status Agendador") intervalo_atual = st.session_state['intervalo_horas'] st.success(f"✅ Ativo (a cada {intervalo_atual}h desde 00:00)") st.markdown("### Ações") # Botão de execução manual if st.button("🚀 Executar Verificação Agora", type="primary"): with st.spinner('Verificando status dos serviços...'): status, messages, whatsapp_status, email_status = run_monitor_check() now = datetime.now(tz) st.session_state['last_run'] = now.strftime("%H:%M:%S") # Adicionar ao histórico de logs timestamp = now.strftime("%H:%M:%S") entry = { "Hora": timestamp, "Status": "✅ Sucesso" if status else "❌ Erro", "WhatsApp": whatsapp_status, "Email": email_status, "Detalhes": " | ".join(messages) } st.session_state['logs'].insert(0, entry) # Adiciona no topo if status: st.success("✅ Todos os serviços estão operacionais!") else: st.error("❌ Falha detectada em um ou mais serviços. Verifique os logs.") st.markdown("---") st.markdown("### 📋 Histórico de Execuções (Sessão Atual)") if st.session_state['logs']: # Renderizar tabela HTML customizada tabela_html = gerar_tabela_html(st.session_state['logs']) st.markdown(tabela_html, unsafe_allow_html=True) else: st.info("ℹ️ Nenhuma verificação executada nesta sessão ainda.") # ===== Sidebar ===== st.sidebar.title("ℹ️ Sobre") st.sidebar.info( """ Este aplicativo monitora: 1. **Evolution API**: Verifica se a instância está online. 2. **N8N Webhook**: Verifica se o endpoint responde. **Notificações:** - ✅ **Sucesso**: Envia WhatsApp. - ❌ **Erro**: Envia Email. """ ) st.sidebar.markdown("---") # Configuração do Intervalo de Disparo st.sidebar.markdown("### ⏱️ Intervalo de Disparo") intervalo_slider = st.sidebar.slider( "Executar a cada (horas):", min_value=1, max_value=12, value=st.session_state['intervalo_horas'], step=1, help="Define o intervalo entre execuções automáticas a partir de 00:00" ) # Mostrar horários de execução baseados no intervalo horarios = [f"{h:02d}:00" for h in range(0, 24, intervalo_slider)] st.sidebar.caption(f"Horários: {', '.join(horarios)}") # Verificar se o intervalo mudou if intervalo_slider != st.session_state['intervalo_horas']: st.sidebar.warning("⚠️ Reinicie a aplicação para aplicar o novo intervalo.") st.session_state['intervalo_horas'] = intervalo_slider st.sidebar.markdown("---") # Diagnóstico N8N na Sidebar with st.sidebar.expander("🛠️ Diagnóstico N8N"): st.write("Teste isolado do Webhook N8N") if st.button("Testar Webhook N8N", key="btn_diag"): with st.spinner("Enviando POST de teste..."): success, log_data = diagnose_n8n_webhook() if success: st.success(f"✅ Status: {log_data['status_code']}") else: st.error(f"❌ Erro: {log_data.get('status_code') or log_data.get('error')}") st.json(log_data) # Informações de configuração st.sidebar.markdown("---") st.sidebar.caption(f"Intervalo atual: {st.session_state['intervalo_horas']}h")