From 464f9d44261eff139233d1320e521e1721b8ce61 Mon Sep 17 00:00:00 2001 From: wander Date: Fri, 27 Mar 2026 00:14:30 -0300 Subject: [PATCH] Ajuste 24 Horas --- monitor_logic.py | 570 +++++++++++++++++++++++------------------------ 1 file changed, 285 insertions(+), 285 deletions(-) diff --git a/monitor_logic.py b/monitor_logic.py index 8461fa9..c70bb76 100644 --- a/monitor_logic.py +++ b/monitor_logic.py @@ -1,285 +1,285 @@ -import os -import requests -import smtplib -from email.mime.text import MIMEText -from datetime import datetime -import pytz -from dotenv import load_dotenv - -# Carregar variáveis de ambiente -load_dotenv() - -# Configurações -EVOLUTION_API_URL = os.getenv("EVOLUTION_API_URL") -EVOLUTION_INSTANCE_ID = os.getenv("EVOLUTION_INSTANCE_ID") -EVOLUTION_API_TOKEN = os.getenv("EVOLUTION_API_TOKEN") -EVOLUTION_SENDER_INSTANCE = os.getenv("EVOLUTION_SENDER_INSTANCE", "Wander") -N8N_WEBHOOK_URL = os.getenv("N8N_WEBHOOK_URL") -WHATSAPP_NUMBER = os.getenv("WHATSAPP_NUMBER") -SMTP_SERVER = os.getenv("SMTP_SERVER", "smtp-mail.outlook.com") -SMTP_PORT = int(os.getenv("SMTP_PORT", 587)) -SMTP_EMAIL = os.getenv("SMTP_EMAIL") -SMTP_PASSWORD = os.getenv("SMTP_PASSWORD") -EMAIL_TO = os.getenv("EMAIL_TO") - -# Timezone configurável via variável de ambiente -TIMEZONE = os.getenv("TIMEZONE", "America/Sao_Paulo") -tz = pytz.timezone(TIMEZONE) - -def get_now(): - """Retorna datetime atual com timezone configurado.""" - return datetime.now(tz) - -def get_headers(): - return { - "apikey": EVOLUTION_API_TOKEN, - "Authorization": f"Bearer {EVOLUTION_API_TOKEN}", - "Content-Type": "application/json" - } - -def send_email_error(error_details): - """Envia email de erro caso algo falhe.""" - try: - now = get_now() - subject = "🚨 ERRO - Monitor Evolution API" - body = f"Falha no monitoramento.\nHorário: {now.strftime('%d/%m/%Y %H:%M:%S')}\n\nDetalhes do Erro:\n{error_details}" - - msg = MIMEText(body) - msg['Subject'] = subject - msg['From'] = SMTP_EMAIL - msg['To'] = EMAIL_TO - - # Ler configuração de segurança (Default: STARTTLS) - smtp_security = os.getenv("SMTP_SECURITY", "STARTTLS").upper() - - if smtp_security == "SSL": - server = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) - else: - server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT) - if smtp_security == "STARTTLS": - server.starttls() - - with server: - server.login(SMTP_EMAIL, SMTP_PASSWORD) - server.send_message(msg) - - return True, "Email de erro enviado com sucesso." - except Exception as e: - return False, f"Falha ao enviar email: {str(e)}" - -def send_whatsapp_success(): - """Envia mensagem de sucesso via Evolution API.""" - try: - url = f"{EVOLUTION_API_URL}/message/sendText/{EVOLUTION_SENDER_INSTANCE}" - - now = get_now() - message_text = ( - f"✅ *MONITOR OK*\n\n" - f"📅 Data: {now.strftime('%d/%m/%Y')}\n" - f"🕐 Horário: {now.strftime('%H:%M:%S')}\n\n" - f"• Evolution API: Online\n" - f"• Webhook Instância: Habilitado\n" - f"• Webhook N8N: Funcionando\n\n" - f"Todos os serviços operacionais." - ) - - payload = { - "number": WHATSAPP_NUMBER, - "text": message_text - } - - # A Evolution API às vezes aceita apikey no header ou como query param, - # mas o padrão aqui é usar o header configurado. - response = requests.post(url, json=payload, headers=get_headers(), timeout=10) - - if response.status_code == 200 or response.status_code == 201: - return True, "WhatsApp de sucesso enviado." - else: - return False, f"Falha ao enviar WhatsApp: {response.text}" - - except Exception as e: - return False, f"Erro na requisição WhatsApp: {str(e)}" - -def run_monitor_check(): - """Executa o fluxo de verificação completo.""" - log_messages = [] - whatsapp_status = "-" - email_status = "-" - - # Passo 1: Verificar Health Evolution API - try: - # Endpoint correto: /instance/connectionState/{instanceName} - # Usa o nome da instância (EVOLUTION_SENDER_INSTANCE) e não o ID - health_url = f"{EVOLUTION_API_URL}/instance/connectionState/{EVOLUTION_SENDER_INSTANCE}" - resp_health = requests.get(health_url, headers=get_headers(), timeout=10) - - if resp_health.status_code == 200: - # Validar se a instância está realmente conectada (state: open) - try: - data = resp_health.json() - instance_data = data.get('instance', {}) - state = instance_data.get('state') or data.get('state') - - if state == 'open': - log_messages.append("✅ Evolution API Online") - else: - # Estado não é 'open' (ex: close, closed, connecting) = ERRO! - error_msg = f"Evolution API Desconectada (State: {state})" - log_messages.append(f"❌ {error_msg}") - - # Enviar email de erro - email_ok, _ = send_email_error(error_msg) - email_status = "Sucesso" if email_ok else "Erro" - - return False, log_messages, whatsapp_status, email_status - - except Exception as json_err: - # Se falhar ler JSON mas deu 200 OK, verificar se é HTML - raw_text = resp_health.text.strip() - if raw_text.startswith(' Enviar WhatsApp - # Se está tudo OK, email de erro não é enviado, então mantemos email_status como "-" ou podemos por "N/A" - # O usuário pediu "Sucesso ou Error". Se não enviou nada, talvez "-" seja melhor que "Error". - - success, msg = send_whatsapp_success() - if success: - log_messages.append(f"✅ {msg}") - whatsapp_status = "Sucesso" - return True, log_messages, whatsapp_status, email_status - else: - # Se falhar enviar o whats, é um erro também? - whatsapp_status = "Erro" - - # O fluxo original manda email de erro se o check falhar. - # Se o envio do whats falhar, vamos mandar email - error_msg = f"Serviços Online, mas falha ao enviar WhatsApp: {msg}" - log_messages.append(f"⚠️ {error_msg}") - - email_ok, _ = send_email_error(error_msg) - email_status = "Sucesso" if email_ok else "Erro" - - return False, log_messages, whatsapp_status, email_status - -def diagnose_n8n_webhook(): - """Realiza um teste detalhado do Webhook N8N para diagnóstico.""" - try: - url = N8N_WEBHOOK_URL - now = get_now() - payload = {"check": "diagnosis_ping", "timestamp": str(now)} - - # Preparar log - log = { - "url": url, - "method": "POST", - "payload_sent": payload, - "status_code": None, - "response_body": None, - "headers_received": None, - "error": None - } - - response = requests.post(url, json=payload, timeout=10) - - log["status_code"] = response.status_code - log["response_body"] = response.text - log["headers_received"] = dict(response.headers) - - if response.status_code == 200: - return True, log - else: - return False, log - - except Exception as e: - log["error"] = str(e) - return False, log - -if __name__ == "__main__": - # Teste rápido se rodar direto - status, logs, wa_status, em_status = run_monitor_check() - print(f"Status: {status}") - print(f"WhatsApp: {wa_status} | Email: {em_status}") - print("\n".join(logs)) +import os +import smtplib +from datetime import datetime +from email.mime.text import MIMEText +from pathlib import Path + +import pytz +import requests +from dotenv import load_dotenv + + +# Carrega .env sempre pelo caminho do projeto (independente do CWD) +BASE_DIR = Path(__file__).resolve().parent +load_dotenv(dotenv_path=BASE_DIR / ".env") + + +EVOLUTION_API_URL = os.getenv("EVOLUTION_API_URL") +EVOLUTION_INSTANCE_ID = os.getenv("EVOLUTION_INSTANCE_ID") +EVOLUTION_API_TOKEN = os.getenv("EVOLUTION_API_TOKEN") +EVOLUTION_SENDER_INSTANCE = os.getenv("EVOLUTION_SENDER_INSTANCE", "Wander") +N8N_WEBHOOK_URL = os.getenv("N8N_WEBHOOK_URL") +WHATSAPP_NUMBER = os.getenv("WHATSAPP_NUMBER") +SMTP_SERVER = os.getenv("SMTP_SERVER", "smtp-mail.outlook.com") +SMTP_PORT = int(os.getenv("SMTP_PORT", 587)) +SMTP_EMAIL = os.getenv("SMTP_EMAIL") +SMTP_PASSWORD = os.getenv("SMTP_PASSWORD") +EMAIL_TO = os.getenv("EMAIL_TO") + +TIMEZONE = os.getenv("TIMEZONE", "America/Sao_Paulo") +tz = pytz.timezone(TIMEZONE) + + +def _normalize_env(value): + if value is None: + return None + cleaned = value.strip() + return cleaned if cleaned else None + + +def _required_env_missing(): + required = { + "EVOLUTION_API_URL": _normalize_env(EVOLUTION_API_URL), + "EVOLUTION_API_TOKEN": _normalize_env(EVOLUTION_API_TOKEN), + "EVOLUTION_SENDER_INSTANCE": _normalize_env(EVOLUTION_SENDER_INSTANCE), + "N8N_WEBHOOK_URL": _normalize_env(N8N_WEBHOOK_URL), + "SMTP_EMAIL": _normalize_env(SMTP_EMAIL), + "SMTP_PASSWORD": _normalize_env(SMTP_PASSWORD), + "EMAIL_TO": _normalize_env(EMAIL_TO), + "WHATSAPP_NUMBER": _normalize_env(WHATSAPP_NUMBER), + } + return [name for name, value in required.items() if not value] + + +def get_now(): + return datetime.now(tz) + + +def get_headers(): + token = _normalize_env(EVOLUTION_API_TOKEN) or "" + return { + "apikey": token, + "Authorization": f"Bearer {token}", + "Content-Type": "application/json", + } + + +def send_email_error(error_details): + try: + now = get_now() + subject = "ERRO - Monitor Evolution API" + body = ( + "Falha no monitoramento.\n" + f"Horario: {now.strftime('%d/%m/%Y %H:%M:%S')}\n\n" + f"Detalhes do Erro:\n{error_details}" + ) + + msg = MIMEText(body) + msg["Subject"] = subject + msg["From"] = SMTP_EMAIL + msg["To"] = EMAIL_TO + + smtp_security = os.getenv("SMTP_SECURITY", "STARTTLS").upper() + + if smtp_security == "SSL": + server = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) + else: + server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT) + if smtp_security == "STARTTLS": + server.starttls() + + with server: + server.login(SMTP_EMAIL, SMTP_PASSWORD) + server.send_message(msg) + + return True, "Email de erro enviado com sucesso." + except Exception as exc: + return False, f"Falha ao enviar email: {exc}" + + +def send_whatsapp_success(): + try: + base_url = (_normalize_env(EVOLUTION_API_URL) or "").rstrip("/") + sender_instance = _normalize_env(EVOLUTION_SENDER_INSTANCE) or "Wander" + url = f"{base_url}/message/sendText/{sender_instance}" + + now = get_now() + message_text = ( + "MONITOR OK\n\n" + f"Data: {now.strftime('%d/%m/%Y')}\n" + f"Horario: {now.strftime('%H:%M:%S')}\n\n" + "• Evolution API: Online\n" + "• Webhook Instancia: Habilitado\n" + "• Webhook N8N: Funcionando\n\n" + "Todos os servicos operacionais." + ) + + payload = {"number": WHATSAPP_NUMBER, "text": message_text} + response = requests.post(url, json=payload, headers=get_headers(), timeout=10) + + if response.status_code in (200, 201): + return True, "WhatsApp de sucesso enviado." + return False, f"Falha ao enviar WhatsApp: {response.text}" + except Exception as exc: + return False, f"Erro na requisicao WhatsApp: {exc}" + + +def run_monitor_check(): + log_messages = [] + whatsapp_status = "-" + email_status = "-" + + missing_env = _required_env_missing() + if missing_env: + log_messages.append(f"❌ Configuracao ausente no .env: {', '.join(missing_env)}") + return False, log_messages, whatsapp_status, email_status + + base_url = (_normalize_env(EVOLUTION_API_URL) or "").rstrip("/") + sender_instance = _normalize_env(EVOLUTION_SENDER_INSTANCE) or "Wander" + webhook_n8n_url = _normalize_env(N8N_WEBHOOK_URL) + + # Passo 1: Health Evolution API + try: + health_url = f"{base_url}/instance/connectionState/{sender_instance}" + resp_health = requests.get(health_url, headers=get_headers(), timeout=10) + + if resp_health.status_code == 200: + try: + data = resp_health.json() + instance_data = data.get("instance", {}) + state = instance_data.get("state") or data.get("state") + + if state == "open": + log_messages.append("✅ Evolution API Online") + else: + error_msg = f"Evolution API Desconectada (State: {state})" + log_messages.append(f"❌ {error_msg}") + email_ok, _ = send_email_error(error_msg) + email_status = "Sucesso" if email_ok else "Erro" + return False, log_messages, whatsapp_status, email_status + except Exception: + raw_text = (resp_health.text or "").strip().lower() + if raw_text.startswith("