""" SSL/TLS Connection Test for Meta WhatsApp API ============================================== This script tests SSL/TLS connectivity to Meta's API to diagnose handshake failures. """ import asyncio import ssl import certifi import httpx import sys import os from pathlib import Path sys.path.insert(0, str(Path(__file__).parent)) from dotenv import load_dotenv load_dotenv() async def test_ssl_methods(): """Test different SSL configuration methods""" test_url = "https://graph.facebook.com/v20.0/me" token = os.getenv("WHATSAPP_ACCESS_TOKEN", "") if not token: print("❌ WHATSAPP_ACCESS_TOKEN not set in .env") return headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json" } print("="*80) print("Testing SSL/TLS Connection to Meta's API") print("="*80) print(f"\nTest URL: {test_url}") print(f"Token: ***{token[-8:]}") print() # Method 1: Using certifi print("Method 1: Using certifi CA bundle") print("-" * 80) try: async with httpx.AsyncClient( verify=certifi.where(), timeout=10.0 ) as client: response = await client.get(test_url, headers=headers) print(f"✅ SUCCESS! Status: {response.status_code}") print(f" Response: {response.text[:200]}") except Exception as e: print(f"❌ FAILED: {e}") print() # Method 2: Using system certificates print("Method 2: Using system certificates (verify=True)") print("-" * 80) try: async with httpx.AsyncClient( verify=True, timeout=10.0 ) as client: response = await client.get(test_url, headers=headers) print(f"✅ SUCCESS! Status: {response.status_code}") print(f" Response: {response.text[:200]}") except Exception as e: print(f"❌ FAILED: {e}") print() # Method 3: Custom SSL context with TLS 1.2+ print("Method 3: Custom SSL context (TLS 1.2+)") print("-" * 80) try: ssl_context = ssl.create_default_context(cafile=certifi.where()) ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 ssl_context.check_hostname = True async with httpx.AsyncClient( verify=ssl_context, timeout=10.0 ) as client: response = await client.get(test_url, headers=headers) print(f"✅ SUCCESS! Status: {response.status_code}") print(f" Response: {response.text[:200]}") except Exception as e: print(f"❌ FAILED: {e}") print() # Method 4: Custom SSL context with relaxed settings print("Method 4: Custom SSL context (relaxed cipher suite)") print("-" * 80) try: ssl_context = ssl.create_default_context(cafile=certifi.where()) ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 ssl_context.check_hostname = True ssl_context.set_ciphers('DEFAULT:@SECLEVEL=1') async with httpx.AsyncClient( verify=ssl_context, timeout=10.0 ) as client: response = await client.get(test_url, headers=headers) print(f"✅ SUCCESS! Status: {response.status_code}") print(f" Response: {response.text[:200]}") except Exception as e: print(f"❌ FAILED: {e}") print() # Method 5: No verification (INSECURE - for testing only) print("Method 5: No SSL verification (INSECURE - testing only)") print("-" * 80) try: async with httpx.AsyncClient( verify=False, timeout=10.0 ) as client: response = await client.get(test_url, headers=headers) print(f"✅ SUCCESS! Status: {response.status_code}") print(f" Response: {response.text[:200]}") print(" ⚠️ WARNING: This method is INSECURE. Do not use in production!") except Exception as e: print(f"❌ FAILED: {e}") print() # System info print("="*80) print("System Information") print("="*80) print(f"Python SSL version: {ssl.OPENSSL_VERSION}") print(f"Certifi CA bundle location: {certifi.where()}") print(f"httpx version: {httpx.__version__}") # Check if CA bundle exists import os.path ca_bundle = certifi.where() if os.path.exists(ca_bundle): file_size = os.path.getsize(ca_bundle) print(f"✅ CA bundle exists ({file_size:,} bytes)") else: print(f"❌ CA bundle not found at {ca_bundle}") async def main(): print("\n" + "="*80) print("WhatsApp Cloud API - SSL/TLS Connectivity Test") print("="*80) print(""" This script tests different SSL/TLS configuration methods to identify which one works with Meta's API on your system. It will try: 1. Certifi CA bundle 2. System certificates 3. Custom SSL context with TLS 1.2+ 4. Relaxed cipher suites 5. No verification (insecure, for comparison) """) await test_ssl_methods() print("\n" + "="*80) print("Recommendation") print("="*80) print(""" Look at the results above and use the first method that succeeded. If only Method 5 (no verification) worked: - Your system certificates may be outdated - Update certifi: pip install --upgrade certifi - Update OpenSSL on your system If Methods 1-4 all failed: - Check your firewall/proxy settings - Ensure you can reach graph.facebook.com - Verify WHATSAPP_ACCESS_TOKEN is correct """) if __name__ == "__main__": asyncio.run(main())