Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -900,53 +900,123 @@ def send_whatsjet_message(phone_number: str, message: str, media_type: str = Non
|
|
900 |
try:
|
901 |
# Download image if it's a URL
|
902 |
if media_path.startswith("http://") or media_path.startswith("https://"):
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
908 |
else:
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
}
|
919 |
-
# Send image (no caption)
|
920 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
921 |
response = httpx.post(
|
922 |
url,
|
923 |
-
|
924 |
-
|
|
|
925 |
)
|
926 |
response.raise_for_status()
|
927 |
-
logger.info(f"[WhatsJet] Media image sent successfully to {phone_number}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
928 |
except Exception as e:
|
929 |
-
logger.
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
947 |
except Exception as e:
|
948 |
logger.error(f"[WhatsJet] Exception preparing media image: {str(e)}")
|
949 |
-
|
|
|
950 |
|
951 |
# Handle other media messages (existing logic)
|
952 |
if media_type and media_path:
|
@@ -960,26 +1030,50 @@ def send_whatsjet_message(phone_number: str, message: str, media_type: str = Non
|
|
960 |
else:
|
961 |
with open(media_path, 'rb') as f:
|
962 |
media_content = f.read()
|
963 |
-
|
964 |
-
|
965 |
-
"phone_number": phone_number,
|
966 |
-
"message_body": message,
|
967 |
-
'media_type': media_type,
|
968 |
-
'media_content': media_b64,
|
969 |
-
'media_filename': filename or os.path.basename(media_path) if not media_path.startswith('http') else filename or 'file.bin'
|
970 |
-
}
|
971 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
972 |
response = httpx.post(
|
973 |
url,
|
974 |
-
|
975 |
-
|
|
|
976 |
)
|
977 |
response.raise_for_status()
|
978 |
-
logger.info(f"[WhatsJet] Media message sent successfully to {phone_number}")
|
979 |
return True
|
|
|
980 |
except Exception as e:
|
981 |
-
logger.
|
982 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
983 |
except Exception as e:
|
984 |
logger.error(f"[WhatsJet] Exception preparing media message: {str(e)}")
|
985 |
return False
|
@@ -3637,11 +3731,15 @@ async def send_product_image_with_caption(from_number: str, product: Dict[str, A
|
|
3637 |
details = generate_veterinary_product_response(product, user_context)
|
3638 |
image_url = product.get('Images', '').strip() if 'Images' in product else ''
|
3639 |
|
|
|
|
|
|
|
3640 |
try:
|
3641 |
# First, check if we have an image URL from CSV
|
3642 |
if image_url:
|
3643 |
# Convert Google Drive link to direct download if needed
|
3644 |
if 'drive.google.com' in image_url:
|
|
|
3645 |
if '/d/' in image_url:
|
3646 |
file_id = image_url.split('/d/')[1].split('/')[0]
|
3647 |
elif 'id=' in image_url:
|
@@ -3650,27 +3748,61 @@ async def send_product_image_with_caption(from_number: str, product: Dict[str, A
|
|
3650 |
file_id = ''
|
3651 |
if file_id:
|
3652 |
image_url = f"https://drive.google.com/uc?export=download&id={file_id}"
|
|
|
3653 |
|
3654 |
# Use the public URL directly for WhatsApp API
|
3655 |
media_type = 'image/jpeg'
|
3656 |
filename = f"{product_name.replace(' ', '_')}.jpg"
|
3657 |
|
3658 |
-
#
|
3659 |
-
|
3660 |
-
|
3661 |
-
|
3662 |
-
|
3663 |
-
|
3664 |
-
|
3665 |
-
|
|
|
|
|
|
|
3666 |
|
3667 |
-
|
3668 |
-
|
3669 |
-
|
3670 |
-
|
3671 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3672 |
|
3673 |
-
# Fallback
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3674 |
image_path = get_product_image_path(product_name)
|
3675 |
if image_path and (image_path.startswith('http') or os.path.exists(image_path)):
|
3676 |
media_type = get_product_image_media_type(image_path)
|
@@ -3679,9 +3811,11 @@ async def send_product_image_with_caption(from_number: str, product: Dict[str, A
|
|
3679 |
# If it's already a public URL, use it directly
|
3680 |
if image_path.startswith('http'):
|
3681 |
media_path = image_path
|
|
|
3682 |
else:
|
3683 |
# Convert local path to public URL
|
3684 |
media_path = f"https://dreamstream-1-chatbot.hf.space/uploads/{os.path.basename(image_path).replace(' ', '%20')}"
|
|
|
3685 |
|
3686 |
success = send_whatsjet_message(
|
3687 |
from_number,
|
@@ -3692,17 +3826,18 @@ async def send_product_image_with_caption(from_number: str, product: Dict[str, A
|
|
3692 |
)
|
3693 |
|
3694 |
if success:
|
3695 |
-
logger.info(f"[Product]
|
3696 |
else:
|
3697 |
logger.warning(f"[Product] Failed to send image, sending text only: {product_name}")
|
3698 |
send_whatsjet_message(from_number, details)
|
3699 |
else:
|
3700 |
# No image available, send text only
|
|
|
3701 |
send_whatsjet_message(from_number, details)
|
3702 |
-
logger.info(f"[Product] Sent product info without image: {product_name}")
|
3703 |
|
3704 |
except Exception as e:
|
3705 |
logger.error(f"[Product] Error sending product image with caption: {e}")
|
|
|
3706 |
send_whatsjet_message(from_number, details)
|
3707 |
|
3708 |
@app.get("/test-product-image-with-caption")
|
@@ -3723,6 +3858,97 @@ async def test_product_image_with_caption(phone: str):
|
|
3723 |
except Exception as e:
|
3724 |
return {"error": str(e)}
|
3725 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3726 |
if __name__ == "__main__":
|
3727 |
# Launch FastAPI app
|
3728 |
import uvicorn
|
|
|
900 |
try:
|
901 |
# Download image if it's a URL
|
902 |
if media_path.startswith("http://") or media_path.startswith("https://"):
|
903 |
+
try:
|
904 |
+
response = requests.get(media_path, stream=True, timeout=15)
|
905 |
+
response.raise_for_status()
|
906 |
+
media_content = response.content
|
907 |
+
content_type = response.headers.get('Content-Type', '')
|
908 |
+
logger.info(f"[WhatsJet][DEBUG] Downloaded image content-type: {content_type}")
|
909 |
+
logger.info(f"[WhatsJet][DEBUG] Image size: {len(media_content)} bytes")
|
910 |
+
logger.info(f"[WhatsJet][DEBUG] First 20 bytes: {media_content[:20]}")
|
911 |
+
|
912 |
+
# Validate image content
|
913 |
+
if len(media_content) == 0:
|
914 |
+
logger.error("[WhatsJet] Downloaded image is empty")
|
915 |
+
return False
|
916 |
+
|
917 |
+
# Check if content is actually an image
|
918 |
+
if not content_type.startswith('image/'):
|
919 |
+
logger.warning(f"[WhatsJet] URL does not return an image: {content_type}")
|
920 |
+
|
921 |
+
except Exception as e:
|
922 |
+
logger.error(f"[WhatsJet] Failed to download image from {media_path}: {e}")
|
923 |
+
return False
|
924 |
else:
|
925 |
+
try:
|
926 |
+
with open(media_path, 'rb') as f:
|
927 |
+
media_content = f.read()
|
928 |
+
logger.info(f"[WhatsJet][DEBUG] Local image size: {len(media_content)} bytes")
|
929 |
+
except Exception as e:
|
930 |
+
logger.error(f"[WhatsJet] Failed to read local image {media_path}: {e}")
|
931 |
+
return False
|
932 |
+
|
933 |
+
# Try method 1: Send as multipart form data with file upload
|
|
|
|
|
934 |
try:
|
935 |
+
files = {
|
936 |
+
'media': (filename or 'image.jpg', media_content, media_type)
|
937 |
+
}
|
938 |
+
data = {
|
939 |
+
'phone_number': phone_number,
|
940 |
+
'message_body': '' # No caption with image
|
941 |
+
}
|
942 |
+
|
943 |
+
logger.info(f"[WhatsJet] Attempting multipart upload for {phone_number}")
|
944 |
response = httpx.post(
|
945 |
url,
|
946 |
+
data=data,
|
947 |
+
files=files,
|
948 |
+
timeout=30
|
949 |
)
|
950 |
response.raise_for_status()
|
951 |
+
logger.info(f"[WhatsJet] Media image sent successfully via multipart upload to {phone_number}")
|
952 |
+
|
953 |
+
# Send caption as separate text message
|
954 |
+
if message.strip():
|
955 |
+
for chunk in split_message_for_whatsapp(message):
|
956 |
+
try:
|
957 |
+
text_payload = {"phone_number": phone_number, "message_body": chunk}
|
958 |
+
text_response = httpx.post(
|
959 |
+
url,
|
960 |
+
json=text_payload,
|
961 |
+
timeout=15
|
962 |
+
)
|
963 |
+
text_response.raise_for_status()
|
964 |
+
logger.info(f"[WhatsJet] Text chunk (caption) sent successfully to {phone_number}")
|
965 |
+
except Exception as e:
|
966 |
+
logger.error(f"[WhatsJet] Exception sending text chunk (caption): {e}")
|
967 |
+
return False
|
968 |
+
return True
|
969 |
+
|
970 |
except Exception as e:
|
971 |
+
logger.warning(f"[WhatsJet] Multipart upload failed, trying base64 method: {e}")
|
972 |
+
|
973 |
+
# Try method 2: Send as base64 encoded content
|
974 |
+
try:
|
975 |
+
media_b64 = base64.b64encode(media_content).decode('utf-8')
|
976 |
+
payload = {
|
977 |
+
"phone_number": phone_number,
|
978 |
+
"media_type": media_type,
|
979 |
+
"media_content": media_b64,
|
980 |
+
"media_filename": filename or os.path.basename(media_path) if not media_path.startswith('http') else filename or 'image.jpg',
|
981 |
+
"message_body": "" # No caption
|
982 |
+
}
|
983 |
+
|
984 |
+
logger.info(f"[WhatsJet] Attempting base64 upload for {phone_number}")
|
985 |
+
response = httpx.post(
|
986 |
+
url,
|
987 |
+
json=payload,
|
988 |
+
timeout=30
|
989 |
+
)
|
990 |
+
response.raise_for_status()
|
991 |
+
logger.info(f"[WhatsJet] Media image sent successfully via base64 to {phone_number}")
|
992 |
+
|
993 |
+
# Send caption as separate text message
|
994 |
+
if message.strip():
|
995 |
+
for chunk in split_message_for_whatsapp(message):
|
996 |
+
try:
|
997 |
+
text_payload = {"phone_number": phone_number, "message_body": chunk}
|
998 |
+
text_response = httpx.post(
|
999 |
+
url,
|
1000 |
+
json=text_payload,
|
1001 |
+
timeout=15
|
1002 |
+
)
|
1003 |
+
text_response.raise_for_status()
|
1004 |
+
logger.info(f"[WhatsJet] Text chunk (caption) sent successfully to {phone_number}")
|
1005 |
+
except Exception as e:
|
1006 |
+
logger.error(f"[WhatsJet] Exception sending text chunk (caption): {e}")
|
1007 |
+
return False
|
1008 |
+
return True
|
1009 |
+
|
1010 |
+
except Exception as e:
|
1011 |
+
logger.error(f"[WhatsJet] Base64 method also failed: {e}")
|
1012 |
+
# Fallback: send text only
|
1013 |
+
logger.warning(f"[WhatsJet] Both image methods failed, sending text only for {phone_number}")
|
1014 |
+
return send_whatsjet_message(phone_number, message)
|
1015 |
+
|
1016 |
except Exception as e:
|
1017 |
logger.error(f"[WhatsJet] Exception preparing media image: {str(e)}")
|
1018 |
+
# Fallback: send text only
|
1019 |
+
return send_whatsjet_message(phone_number, message)
|
1020 |
|
1021 |
# Handle other media messages (existing logic)
|
1022 |
if media_type and media_path:
|
|
|
1030 |
else:
|
1031 |
with open(media_path, 'rb') as f:
|
1032 |
media_content = f.read()
|
1033 |
+
|
1034 |
+
# Try multipart first, then base64
|
|
|
|
|
|
|
|
|
|
|
|
|
1035 |
try:
|
1036 |
+
files = {
|
1037 |
+
'media': (filename or 'file.bin', media_content, media_type)
|
1038 |
+
}
|
1039 |
+
data = {
|
1040 |
+
'phone_number': phone_number,
|
1041 |
+
'message_body': message
|
1042 |
+
}
|
1043 |
+
|
1044 |
response = httpx.post(
|
1045 |
url,
|
1046 |
+
data=data,
|
1047 |
+
files=files,
|
1048 |
+
timeout=30
|
1049 |
)
|
1050 |
response.raise_for_status()
|
1051 |
+
logger.info(f"[WhatsJet] Media message sent successfully via multipart to {phone_number}")
|
1052 |
return True
|
1053 |
+
|
1054 |
except Exception as e:
|
1055 |
+
logger.warning(f"[WhatsJet] Multipart upload failed for media, trying base64: {e}")
|
1056 |
+
|
1057 |
+
media_b64 = base64.b64encode(media_content).decode('utf-8')
|
1058 |
+
payload = {
|
1059 |
+
"phone_number": phone_number,
|
1060 |
+
"message_body": message,
|
1061 |
+
'media_type': media_type,
|
1062 |
+
'media_content': media_b64,
|
1063 |
+
'media_filename': filename or os.path.basename(media_path) if not media_path.startswith('http') else filename or 'file.bin'
|
1064 |
+
}
|
1065 |
+
try:
|
1066 |
+
response = httpx.post(
|
1067 |
+
url,
|
1068 |
+
json=payload,
|
1069 |
+
timeout=30
|
1070 |
+
)
|
1071 |
+
response.raise_for_status()
|
1072 |
+
logger.info(f"[WhatsJet] Media message sent successfully via base64 to {phone_number}")
|
1073 |
+
return True
|
1074 |
+
except Exception as e:
|
1075 |
+
logger.error(f"[WhatsJet] Exception sending media message: {e}")
|
1076 |
+
return False
|
1077 |
except Exception as e:
|
1078 |
logger.error(f"[WhatsJet] Exception preparing media message: {str(e)}")
|
1079 |
return False
|
|
|
3731 |
details = generate_veterinary_product_response(product, user_context)
|
3732 |
image_url = product.get('Images', '').strip() if 'Images' in product else ''
|
3733 |
|
3734 |
+
logger.info(f"[Product] Processing image for product: {product_name}")
|
3735 |
+
logger.info(f"[Product] Image URL from CSV: {image_url}")
|
3736 |
+
|
3737 |
try:
|
3738 |
# First, check if we have an image URL from CSV
|
3739 |
if image_url:
|
3740 |
# Convert Google Drive link to direct download if needed
|
3741 |
if 'drive.google.com' in image_url:
|
3742 |
+
logger.info(f"[Product] Converting Google Drive link: {image_url}")
|
3743 |
if '/d/' in image_url:
|
3744 |
file_id = image_url.split('/d/')[1].split('/')[0]
|
3745 |
elif 'id=' in image_url:
|
|
|
3748 |
file_id = ''
|
3749 |
if file_id:
|
3750 |
image_url = f"https://drive.google.com/uc?export=download&id={file_id}"
|
3751 |
+
logger.info(f"[Product] Converted to direct download URL: {image_url}")
|
3752 |
|
3753 |
# Use the public URL directly for WhatsApp API
|
3754 |
media_type = 'image/jpeg'
|
3755 |
filename = f"{product_name.replace(' ', '_')}.jpg"
|
3756 |
|
3757 |
+
# Test the image URL first
|
3758 |
+
try:
|
3759 |
+
logger.info(f"[Product] Testing image URL accessibility: {image_url}")
|
3760 |
+
test_response = requests.head(image_url, timeout=10)
|
3761 |
+
if test_response.status_code != 200:
|
3762 |
+
logger.warning(f"[Product] Image URL not accessible (status {test_response.status_code}): {image_url}")
|
3763 |
+
raise Exception(f"Image URL not accessible: {test_response.status_code}")
|
3764 |
+
logger.info(f"[Product] Image URL is accessible")
|
3765 |
+
except Exception as e:
|
3766 |
+
logger.warning(f"[Product] Failed to test image URL {image_url}: {e}")
|
3767 |
+
image_url = None
|
3768 |
|
3769 |
+
# Send using public URL (not local file)
|
3770 |
+
if image_url:
|
3771 |
+
logger.info(f"[Product] Attempting to send image from CSV URL for: {product_name}")
|
3772 |
+
success = send_whatsjet_message(
|
3773 |
+
from_number,
|
3774 |
+
details,
|
3775 |
+
media_type=media_type,
|
3776 |
+
media_path=image_url, # Use public URL directly
|
3777 |
+
filename=filename
|
3778 |
+
)
|
3779 |
+
|
3780 |
+
if success:
|
3781 |
+
logger.info(f"[Product] Successfully sent image from CSV link with caption for product: {product_name}")
|
3782 |
+
return
|
3783 |
+
else:
|
3784 |
+
logger.warning(f"[Product] Failed to send image from CSV link, trying fallback: {product_name}")
|
3785 |
|
3786 |
+
# Fallback 1: Try with a known public test image
|
3787 |
+
logger.info(f"[Product] Trying public test image for: {product_name}")
|
3788 |
+
test_image_url = "https://www.w3schools.com/w3images/lights.jpg"
|
3789 |
+
media_type = 'image/jpeg'
|
3790 |
+
filename = f"{product_name.replace(' ', '_')}.jpg"
|
3791 |
+
|
3792 |
+
success = send_whatsjet_message(
|
3793 |
+
from_number,
|
3794 |
+
details,
|
3795 |
+
media_type=media_type,
|
3796 |
+
media_path=test_image_url,
|
3797 |
+
filename=filename
|
3798 |
+
)
|
3799 |
+
|
3800 |
+
if success:
|
3801 |
+
logger.info(f"[Product] Successfully sent test image with caption for product: {product_name}")
|
3802 |
+
return
|
3803 |
+
|
3804 |
+
# Fallback 2: Try local uploads directory (public URL)
|
3805 |
+
logger.info(f"[Product] Trying local uploads directory for: {product_name}")
|
3806 |
image_path = get_product_image_path(product_name)
|
3807 |
if image_path and (image_path.startswith('http') or os.path.exists(image_path)):
|
3808 |
media_type = get_product_image_media_type(image_path)
|
|
|
3811 |
# If it's already a public URL, use it directly
|
3812 |
if image_path.startswith('http'):
|
3813 |
media_path = image_path
|
3814 |
+
logger.info(f"[Product] Using existing public URL: {media_path}")
|
3815 |
else:
|
3816 |
# Convert local path to public URL
|
3817 |
media_path = f"https://dreamstream-1-chatbot.hf.space/uploads/{os.path.basename(image_path).replace(' ', '%20')}"
|
3818 |
+
logger.info(f"[Product] Converted local path to public URL: {media_path}")
|
3819 |
|
3820 |
success = send_whatsjet_message(
|
3821 |
from_number,
|
|
|
3826 |
)
|
3827 |
|
3828 |
if success:
|
3829 |
+
logger.info(f"[Product] Successfully sent image with caption for product: {product_name}")
|
3830 |
else:
|
3831 |
logger.warning(f"[Product] Failed to send image, sending text only: {product_name}")
|
3832 |
send_whatsjet_message(from_number, details)
|
3833 |
else:
|
3834 |
# No image available, send text only
|
3835 |
+
logger.info(f"[Product] No image available, sending text only for: {product_name}")
|
3836 |
send_whatsjet_message(from_number, details)
|
|
|
3837 |
|
3838 |
except Exception as e:
|
3839 |
logger.error(f"[Product] Error sending product image with caption: {e}")
|
3840 |
+
logger.info(f"[Product] Falling back to text-only message for: {product_name}")
|
3841 |
send_whatsjet_message(from_number, details)
|
3842 |
|
3843 |
@app.get("/test-product-image-with-caption")
|
|
|
3858 |
except Exception as e:
|
3859 |
return {"error": str(e)}
|
3860 |
|
3861 |
+
@app.get("/test-image-sending")
|
3862 |
+
async def test_image_sending(phone: str, image_url: str = "https://www.w3schools.com/w3images/lights.jpg"):
|
3863 |
+
"""
|
3864 |
+
Test endpoint to send a test image with caption to debug image sending functionality.
|
3865 |
+
"""
|
3866 |
+
try:
|
3867 |
+
test_message = f"""🧪 *Test Image Message*
|
3868 |
+
|
3869 |
+
This is a test message to verify image sending functionality.
|
3870 |
+
|
3871 |
+
📸 *Image Details:*
|
3872 |
+
• URL: {image_url}
|
3873 |
+
• Type: JPEG
|
3874 |
+
• Purpose: Testing WhatsJet API
|
3875 |
+
|
3876 |
+
💬 *Test Options:*
|
3877 |
+
1️⃣ Send another test image
|
3878 |
+
2️⃣ Test with different URL
|
3879 |
+
3️⃣ Back to main menu
|
3880 |
+
|
3881 |
+
Please confirm if you received both the image and this text message."""
|
3882 |
+
|
3883 |
+
success = send_whatsjet_message(
|
3884 |
+
phone,
|
3885 |
+
test_message,
|
3886 |
+
media_type="image/jpeg",
|
3887 |
+
media_path=image_url,
|
3888 |
+
filename="test_image.jpg"
|
3889 |
+
)
|
3890 |
+
|
3891 |
+
if success:
|
3892 |
+
return {
|
3893 |
+
"status": "success",
|
3894 |
+
"phone": phone,
|
3895 |
+
"image_url": image_url,
|
3896 |
+
"message": "Test image and caption sent successfully"
|
3897 |
+
}
|
3898 |
+
else:
|
3899 |
+
return {
|
3900 |
+
"status": "failed",
|
3901 |
+
"phone": phone,
|
3902 |
+
"image_url": image_url,
|
3903 |
+
"message": "Failed to send test image"
|
3904 |
+
}
|
3905 |
+
except Exception as e:
|
3906 |
+
return {"error": str(e), "phone": phone, "image_url": image_url}
|
3907 |
+
|
3908 |
+
@app.get("/debug-whatsjet")
|
3909 |
+
async def debug_whatsjet():
|
3910 |
+
"""
|
3911 |
+
Debug endpoint to check WhatsJet configuration and test basic functionality.
|
3912 |
+
"""
|
3913 |
+
try:
|
3914 |
+
# Check environment variables
|
3915 |
+
config_status = {
|
3916 |
+
"WHATSJET_API_URL": bool(WHATSJET_API_URL),
|
3917 |
+
"WHATSJET_VENDOR_UID": bool(WHATSJET_VENDOR_UID),
|
3918 |
+
"WHATSJET_API_TOKEN": bool(WHATSJET_API_TOKEN),
|
3919 |
+
"all_configured": all([WHATSJET_API_URL, WHATSJET_VENDOR_UID, WHATSJET_API_TOKEN])
|
3920 |
+
}
|
3921 |
+
|
3922 |
+
# Test basic text message if configured
|
3923 |
+
test_result = None
|
3924 |
+
if config_status["all_configured"]:
|
3925 |
+
try:
|
3926 |
+
# Test with a simple text message
|
3927 |
+
test_phone = "1234567890" # Dummy phone for testing
|
3928 |
+
test_success = send_whatsjet_message(
|
3929 |
+
test_phone,
|
3930 |
+
"🧪 WhatsJet API Test Message\n\nThis is a test to verify API connectivity.",
|
3931 |
+
)
|
3932 |
+
test_result = {
|
3933 |
+
"success": test_success,
|
3934 |
+
"message": "API test completed (dummy phone number used)"
|
3935 |
+
}
|
3936 |
+
except Exception as e:
|
3937 |
+
test_result = {
|
3938 |
+
"success": False,
|
3939 |
+
"error": str(e)
|
3940 |
+
}
|
3941 |
+
|
3942 |
+
return {
|
3943 |
+
"timestamp": datetime.now().isoformat(),
|
3944 |
+
"config_status": config_status,
|
3945 |
+
"test_result": test_result,
|
3946 |
+
"api_url": WHATSJET_API_URL if config_status["all_configured"] else "Not configured",
|
3947 |
+
"vendor_uid": WHATSJET_VENDOR_UID if config_status["all_configured"] else "Not configured"
|
3948 |
+
}
|
3949 |
+
except Exception as e:
|
3950 |
+
return {"error": str(e), "timestamp": datetime.now().isoformat()}
|
3951 |
+
|
3952 |
if __name__ == "__main__":
|
3953 |
# Launch FastAPI app
|
3954 |
import uvicorn
|