#!/usr/bin/env python3 """Test script to diagnose SMTP connection issues. This script tests SMTP connectivity with different configurations to help identify whether the issue is with credentials, network, ports, or TLS settings. """ import smtplib import ssl import sys from datetime import datetime from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText # Load configuration from config.yaml try: from alpine_bits_python.config_loader import load_config print("Loading configuration from config.yaml...") config = load_config() email_config = config.get("email", {}) smtp_config = email_config.get("smtp", {}) SMTP_HOST = smtp_config.get("host", "smtp.titan.email") SMTP_PORT = smtp_config.get("port", 465) SMTP_USERNAME = smtp_config.get("username", "") SMTP_PASSWORD = smtp_config.get("password", "") USE_TLS = smtp_config.get("use_tls", False) USE_SSL = smtp_config.get("use_ssl", True) FROM_ADDRESS = email_config.get("from_address", "info@99tales.net") FROM_NAME = email_config.get("from_name", "AlpineBits Monitor") # Get test recipient monitoring_config = email_config.get("monitoring", {}) daily_report = monitoring_config.get("daily_report", {}) recipients = daily_report.get("recipients", []) TEST_RECIPIENT = recipients[0] if recipients else "jonas@vaius.ai" print(f"✓ Configuration loaded successfully") print(f" SMTP Host: {SMTP_HOST}") print(f" SMTP Port: {SMTP_PORT}") print(f" Username: {SMTP_USERNAME}") print(f" Password: {'***' if SMTP_PASSWORD else '(not set)'}") print(f" Use SSL: {USE_SSL}") print(f" Use TLS: {USE_TLS}") print(f" From: {FROM_ADDRESS}") print(f" Test Recipient: {TEST_RECIPIENT}") print() except Exception as e: print(f"✗ Failed to load configuration: {e}") print("Using default values for testing...") SMTP_HOST = "smtp.titan.email" SMTP_PORT = 465 SMTP_USERNAME = input("Enter SMTP username: ") SMTP_PASSWORD = input("Enter SMTP password: ") USE_TLS = False USE_SSL = True FROM_ADDRESS = "info@99tales.net" FROM_NAME = "AlpineBits Monitor" TEST_RECIPIENT = input("Enter test recipient email: ") print() def create_test_message(subject: str) -> MIMEMultipart: """Create a test email message.""" msg = MIMEMultipart("alternative") msg["Subject"] = subject msg["From"] = f"{FROM_NAME} <{FROM_ADDRESS}>" msg["To"] = TEST_RECIPIENT msg["Date"] = datetime.now().strftime("%a, %d %b %Y %H:%M:%S %z") body = f"""SMTP Connection Test - {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} This is a test email to verify SMTP connectivity. Configuration: - SMTP Host: {SMTP_HOST} - SMTP Port: {SMTP_PORT} - Use SSL: {USE_SSL} - Use TLS: {USE_TLS} If you received this email, the SMTP configuration is working correctly! """ msg.attach(MIMEText(body, "plain")) return msg def test_smtp_connection(host: str, port: int, timeout: int = 10) -> bool: """Test basic TCP connection to SMTP server.""" import socket print(f"Test 1: Testing TCP connection to {host}:{port}...") try: sock = socket.create_connection((host, port), timeout=timeout) sock.close() print(f"✓ TCP connection successful to {host}:{port}") return True except socket.timeout: print(f"✗ Connection timed out after {timeout} seconds") print(f" This suggests a network/firewall issue blocking access to {host}:{port}") return False except socket.error as e: print(f"✗ Connection failed: {e}") return False def test_smtp_ssl(host: str, port: int, username: str, password: str, timeout: int = 30) -> bool: """Test SMTP connection with SSL.""" print(f"\nTest 2: Testing SMTP with SSL (port {port})...") try: context = ssl.create_default_context() with smtplib.SMTP_SSL(host, port, timeout=timeout, context=context) as server: print(f"✓ Connected to SMTP server with SSL") # Try to get server info server.ehlo() print(f"✓ EHLO successful") # Try authentication if credentials provided if username and password: print(f" Attempting authentication as: {username}") server.login(username, password) print(f"✓ Authentication successful") else: print(f"⚠ No credentials provided, skipping authentication") return True except smtplib.SMTPAuthenticationError as e: print(f"✗ Authentication failed: {e}") print(f" Check your username and password") return False except socket.timeout: print(f"✗ Connection timed out after {timeout} seconds") print(f" Try increasing timeout or check network/firewall") return False except Exception as e: print(f"✗ SMTP SSL failed: {e}") return False def test_smtp_tls(host: str, port: int, username: str, password: str, timeout: int = 30) -> bool: """Test SMTP connection with STARTTLS.""" print(f"\nTest 3: Testing SMTP with STARTTLS (port {port})...") try: with smtplib.SMTP(host, port, timeout=timeout) as server: print(f"✓ Connected to SMTP server") # Try STARTTLS context = ssl.create_default_context() server.starttls(context=context) print(f"✓ STARTTLS successful") # Try authentication if credentials provided if username and password: print(f" Attempting authentication as: {username}") server.login(username, password) print(f"✓ Authentication successful") else: print(f"⚠ No credentials provided, skipping authentication") return True except smtplib.SMTPAuthenticationError as e: print(f"✗ Authentication failed: {e}") return False except socket.timeout: print(f"✗ Connection timed out after {timeout} seconds") return False except Exception as e: print(f"✗ SMTP TLS failed: {e}") return False def send_test_email(host: str, port: int, username: str, password: str, use_ssl: bool, use_tls: bool, timeout: int = 30) -> bool: """Send an actual test email.""" print(f"\nTest 4: Sending test email...") try: msg = create_test_message("SMTP Test Email - AlpineBits") if use_ssl: context = ssl.create_default_context() with smtplib.SMTP_SSL(host, port, timeout=timeout, context=context) as server: if username and password: server.login(username, password) server.send_message(msg, FROM_ADDRESS, [TEST_RECIPIENT]) else: with smtplib.SMTP(host, port, timeout=timeout) as server: if use_tls: context = ssl.create_default_context() server.starttls(context=context) if username and password: server.login(username, password) server.send_message(msg, FROM_ADDRESS, [TEST_RECIPIENT]) print(f"✓ Test email sent successfully to {TEST_RECIPIENT}") print(f" Check your inbox!") return True except Exception as e: print(f"✗ Failed to send email: {e}") return False def main(): """Run all SMTP tests.""" print("=" * 70) print("SMTP Connection Test Script") print("=" * 70) print() # Test 1: Basic TCP connection tcp_ok = test_smtp_connection(SMTP_HOST, SMTP_PORT, timeout=10) if not tcp_ok: print("\n" + "=" * 70) print("DIAGNOSIS: Cannot establish TCP connection to SMTP server") print("=" * 70) print("\nPossible causes:") print("1. The SMTP server is down or unreachable") print("2. A firewall is blocking the connection") print("3. The host or port is incorrect") print("4. Network connectivity issues from your container/server") print("\nTroubleshooting:") print(f"- Verify the server is correct: {SMTP_HOST}") print(f"- Verify the port is correct: {SMTP_PORT}") print("- Check if your container/server has outbound internet access") print("- Try from a different network or machine") print(f"- Use telnet/nc to test: telnet {SMTP_HOST} {SMTP_PORT}") return 1 # Test 2 & 3: Try both SSL and TLS ssl_ok = False tls_ok = False if USE_SSL: ssl_ok = test_smtp_ssl(SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, timeout=30) # Also try common alternative ports if not ssl_ok and SMTP_PORT == 465: print("\n⚠ Port 465 failed, trying port 587 with STARTTLS...") tls_ok = test_smtp_tls(SMTP_HOST, 587, SMTP_USERNAME, SMTP_PASSWORD, timeout=30) if USE_TLS: tls_ok = test_smtp_tls(SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, timeout=30) if not ssl_ok and not tls_ok: print("\n" + "=" * 70) print("DIAGNOSIS: Cannot authenticate or establish secure connection") print("=" * 70) print("\nPossible causes:") print("1. Wrong username or password") print("2. Wrong port for the encryption method") print("3. SSL/TLS version mismatch") print("\nTroubleshooting:") print("- Verify your credentials are correct") print("- Port 465 typically uses SSL") print("- Port 587 typically uses STARTTLS") print("- Port 25 is usually unencrypted (not recommended)") return 1 # Test 4: Send actual email send_ok = send_test_email( SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, USE_SSL, USE_TLS, timeout=30 ) print("\n" + "=" * 70) if send_ok: print("✓ ALL TESTS PASSED!") print("=" * 70) print("\nYour SMTP configuration is working correctly.") print(f"Check {TEST_RECIPIENT} for the test email.") else: print("⚠ PARTIAL SUCCESS") print("=" * 70) print("\nConnection and authentication work, but email sending failed.") print("This might be a temporary issue. Try again.") return 0 if __name__ == "__main__": try: sys.exit(main()) except KeyboardInterrupt: print("\n\nTest cancelled by user") sys.exit(1)