Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def load_configurations(app):
app.config["VERSION"] = os.getenv("VERSION")
app.config["PHONE_NUMBER_ID"] = os.getenv("PHONE_NUMBER_ID")
app.config["VERIFY_TOKEN"] = os.getenv("VERIFY_TOKEN")
app.config["VERIFY_SSL"] = os.getenv("VERIFY_SSL", "true").lower() == "true"


def configure_logging():
Expand Down
14 changes: 13 additions & 1 deletion app/utils/whatsapp_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,26 @@ def send_message(data):

url = f"https://graph.facebook.com/{current_app.config['VERSION']}/{current_app.config['PHONE_NUMBER_ID']}/messages"

# Get SSL verification setting
verify_ssl = current_app.config.get("VERIFY_SSL", True)

try:
response = requests.post(
url, data=data, headers=headers, timeout=10
url, data=data, headers=headers, timeout=10, verify=verify_ssl
) # 10 seconds timeout as an example
response.raise_for_status() # Raises an HTTPError if the HTTP request returned an unsuccessful status code
except requests.Timeout:
logging.error("Timeout occurred while sending message")
return jsonify({"status": "error", "message": "Request timed out"}), 408
except requests.exceptions.SSLError as e:
logging.error(f"SSL Certificate error: {e}")
if not verify_ssl:
return jsonify({"status": "error", "message": "SSL certificate verification failed even with SSL verification disabled"}), 500
else:
return jsonify({"status": "error", "message": "SSL certificate verification failed. Set VERIFY_SSL=false for development/testing"}), 500
except requests.exceptions.ConnectionError as e:
logging.error(f"Connection error: {e}")
return jsonify({"status": "error", "message": "Connection failed - check network and SSL configuration"}), 500
except (
requests.RequestException
) as e: # This will catch any general request exception
Expand Down
3 changes: 3 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ PHONE_NUMBER_ID=""

VERIFY_TOKEN=""

# SSL Configuration (set to false only for development/testing)
VERIFY_SSL="true"

OPENAI_API_KEY=""
OPENAI_ASSISTANT_ID=""
75 changes: 75 additions & 0 deletions test_ssl_fix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env python3
"""
Test script for SSL certificate error handling.

This script tests the SSL error handling improvements made to address issue #35.
"""

import os
import sys
import requests
from unittest.mock import patch, MagicMock

# Add the app directory to the path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'app'))

def test_ssl_error_handling():
"""Test that SSL errors are properly handled."""

# Create a simple Flask app for testing
from flask import Flask
app = Flask(__name__)

# Mock the current_app configuration
mock_config = {
'ACCESS_TOKEN': 'test_token',
'VERSION': 'v18.0',
'PHONE_NUMBER_ID': 'test_phone_id',
'VERIFY_SSL': True
}

with app.app_context():
# Set the config
app.config.update(mock_config)

# Import the function after setting up context
from app.utils.whatsapp_utils import send_message

# Test with SSL error
with patch('requests.post') as mock_post:
mock_post.side_effect = requests.exceptions.SSLError("SSL certificate verification failed")

result = send_message('{"test": "data"}')

# Check that we get the expected error response
assert isinstance(result, tuple)
assert result[1] == 500
assert "SSL certificate verification failed" in result[0].json["message"]

print("✅ SSL error handling test passed!")

# Test with SSL verification disabled
mock_config['VERIFY_SSL'] = False

with app.app_context():
# Set the config
app.config.update(mock_config)

from app.utils.whatsapp_utils import send_message

with patch('requests.post') as mock_post:
mock_post.side_effect = requests.exceptions.SSLError("SSL certificate verification failed")

result = send_message('{"test": "data"}')

# Check that we get the expected error response for disabled SSL
assert isinstance(result, tuple)
assert result[1] == 500
assert "even with SSL verification disabled" in result[0].json["message"]

print("✅ SSL disabled error handling test passed!")

if __name__ == "__main__":
print("Testing SSL certificate error handling...")
test_ssl_error_handling()
print("All tests passed! 🎉")
1 change: 1 addition & 0 deletions tests/test_whatsapp_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@