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("