All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
186 lines
5.5 KiB
Python
186 lines
5.5 KiB
Python
"""
|
|
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())
|