Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -2780,58 +2780,136 @@ def ensure_images_dir():
|
|
2780 |
|
2781 |
# New feature: Send product image with caption (product details)
|
2782 |
async def send_product_image_with_caption(from_number: str, product: Dict[str, Any], user_context: Dict[str, Any]):
|
2783 |
-
logger.info(f"[Product] send_product_image_with_caption called for: {product.get('Product Name', '')}")
|
2784 |
"""
|
2785 |
Send product image (if available) with product details as caption in a single WhatsApp message.
|
2786 |
If image is not available, send only the product details as text.
|
|
|
2787 |
"""
|
2788 |
ensure_images_dir()
|
2789 |
product_name = product.get('Product Name', 'Unknown Product')
|
2790 |
details = generate_veterinary_product_response(product, user_context)
|
2791 |
-
|
2792 |
-
|
|
|
|
|
|
|
2793 |
|
2794 |
-
|
2795 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2796 |
filename = f"{product_name.replace(' ', '_')}.jpg"
|
2797 |
-
logger.info(f"[Product] Sending public image URL with caption: {image_path}")
|
2798 |
|
2799 |
-
# Try sending with image first
|
2800 |
success = send_whatsjet_message(
|
2801 |
from_number,
|
2802 |
details,
|
2803 |
media_type=media_type,
|
2804 |
-
media_path=
|
2805 |
filename=filename
|
2806 |
)
|
2807 |
|
2808 |
if success:
|
2809 |
-
logger.info(f"[Product] Successfully sent image
|
2810 |
return
|
2811 |
-
|
2812 |
-
|
|
|
|
|
|
|
|
|
|
|
2813 |
|
2814 |
-
#
|
2815 |
-
|
2816 |
-
|
2817 |
-
|
2818 |
-
|
2819 |
-
|
2820 |
-
|
2821 |
-
|
2822 |
-
else:
|
2823 |
-
logger.warning(f"[Product] Image-only approach also failed for: {product_name}")
|
2824 |
-
except Exception as e:
|
2825 |
-
logger.error(f"[Product] Exception in image-only approach: {e}")
|
2826 |
|
2827 |
-
|
2828 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2829 |
send_whatsjet_message(from_number, details)
|
2830 |
-
|
2831 |
-
|
2832 |
-
|
2833 |
-
|
2834 |
-
|
2835 |
|
2836 |
# Test endpoint for product image with caption
|
2837 |
@app.get("/test-product-image-with-caption")
|
|
|
2780 |
|
2781 |
# New feature: Send product image with caption (product details)
|
2782 |
async def send_product_image_with_caption(from_number: str, product: Dict[str, Any], user_context: Dict[str, Any]):
|
|
|
2783 |
"""
|
2784 |
Send product image (if available) with product details as caption in a single WhatsApp message.
|
2785 |
If image is not available, send only the product details as text.
|
2786 |
+
Now supports 'Images' column in CSV (Google Drive or direct links).
|
2787 |
"""
|
2788 |
ensure_images_dir()
|
2789 |
product_name = product.get('Product Name', 'Unknown Product')
|
2790 |
details = generate_veterinary_product_response(product, user_context)
|
2791 |
+
image_url = product.get('Images', '').strip() if 'Images' in product else ''
|
2792 |
+
|
2793 |
+
# Force image URL for Respira Aid Plus (use cPanel public URL)
|
2794 |
+
if product_name.lower().strip() == "respira aid plus":
|
2795 |
+
image_url = "https://amgocus.com/uploads/images/Respira%20Aid%20Plus.jpg"
|
2796 |
|
2797 |
+
logger.info(f"[Product] Processing image for product: {product_name}")
|
2798 |
+
logger.info(f"[Product] Image URL from CSV: {image_url}")
|
2799 |
+
|
2800 |
+
try:
|
2801 |
+
# First, check if we have an image URL from CSV
|
2802 |
+
if image_url:
|
2803 |
+
# Convert Google Drive link to direct download if needed
|
2804 |
+
if 'drive.google.com' in image_url:
|
2805 |
+
logger.info(f"[Product] Converting Google Drive link: {image_url}")
|
2806 |
+
if '/d/' in image_url:
|
2807 |
+
file_id = image_url.split('/d/')[1].split('/')[0]
|
2808 |
+
elif 'id=' in image_url:
|
2809 |
+
file_id = image_url.split('id=')[1].split('&')[0]
|
2810 |
+
else:
|
2811 |
+
file_id = ''
|
2812 |
+
if file_id:
|
2813 |
+
image_url = f"https://drive.google.com/uc?export=download&id={file_id}"
|
2814 |
+
logger.info(f"[Product] Converted to direct download URL: {image_url}")
|
2815 |
+
|
2816 |
+
# Use the public URL directly for WhatsApp API
|
2817 |
+
media_type = 'image/jpeg'
|
2818 |
+
filename = f"{product_name.replace(' ', '_')}.jpg"
|
2819 |
+
|
2820 |
+
# Test the image URL first
|
2821 |
+
try:
|
2822 |
+
logger.info(f"[Product] Testing image URL accessibility: {image_url}")
|
2823 |
+
headers = {
|
2824 |
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
2825 |
+
'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
|
2826 |
+
'Accept-Language': 'en-US,en;q=0.9',
|
2827 |
+
'Accept-Encoding': 'gzip, deflate, br',
|
2828 |
+
'Connection': 'keep-alive',
|
2829 |
+
'Upgrade-Insecure-Requests': '1'
|
2830 |
+
}
|
2831 |
+
test_response = requests.head(image_url, headers=headers, timeout=10, allow_redirects=True)
|
2832 |
+
if test_response.status_code != 200:
|
2833 |
+
logger.warning(f"[Product] Image URL not accessible (status {test_response.status_code}): {image_url}")
|
2834 |
+
raise Exception(f"Image URL not accessible: {test_response.status_code}")
|
2835 |
+
logger.info(f"[Product] Image URL is accessible")
|
2836 |
+
except Exception as e:
|
2837 |
+
logger.warning(f"[Product] Failed to test image URL {image_url}: {e}")
|
2838 |
+
image_url = None
|
2839 |
+
|
2840 |
+
# Send using public URL (not local file)
|
2841 |
+
if image_url:
|
2842 |
+
logger.info(f"[Product] Attempting to send image from CSV URL for: {product_name}")
|
2843 |
+
success = send_whatsjet_message(
|
2844 |
+
from_number,
|
2845 |
+
details,
|
2846 |
+
media_type=media_type,
|
2847 |
+
media_path=image_url, # Use public URL directly
|
2848 |
+
filename=filename
|
2849 |
+
)
|
2850 |
+
|
2851 |
+
if success:
|
2852 |
+
logger.info(f"[Product] Successfully sent image from CSV link with caption for product: {product_name}")
|
2853 |
+
return
|
2854 |
+
else:
|
2855 |
+
logger.warning(f"[Product] Failed to send image from CSV link, trying fallback: {product_name}")
|
2856 |
+
|
2857 |
+
# Fallback 1: Try with a known public test image
|
2858 |
+
logger.info(f"[Product] Trying public test image for: {product_name}")
|
2859 |
+
test_image_url = "https://www.w3schools.com/w3images/lights.jpg"
|
2860 |
+
media_type = 'image/jpeg'
|
2861 |
filename = f"{product_name.replace(' ', '_')}.jpg"
|
|
|
2862 |
|
|
|
2863 |
success = send_whatsjet_message(
|
2864 |
from_number,
|
2865 |
details,
|
2866 |
media_type=media_type,
|
2867 |
+
media_path=test_image_url,
|
2868 |
filename=filename
|
2869 |
)
|
2870 |
|
2871 |
if success:
|
2872 |
+
logger.info(f"[Product] Successfully sent test image with caption for product: {product_name}")
|
2873 |
return
|
2874 |
+
|
2875 |
+
# Fallback 2: Try local uploads directory (public URL)
|
2876 |
+
logger.info(f"[Product] Trying local uploads directory for: {product_name}")
|
2877 |
+
image_path = get_product_image_path(product_name)
|
2878 |
+
if image_path and (image_path.startswith('http') or os.path.exists(image_path)):
|
2879 |
+
media_type = get_product_image_media_type(image_path)
|
2880 |
+
filename = f"{product_name.replace(' ', '_')}.jpg"
|
2881 |
|
2882 |
+
# If it's already a public URL, use it directly
|
2883 |
+
if image_path.startswith('http'):
|
2884 |
+
media_path = image_path
|
2885 |
+
logger.info(f"[Product] Using existing public URL: {media_path}")
|
2886 |
+
else:
|
2887 |
+
# Convert local path to public URL
|
2888 |
+
media_path = f"https://dreamstream-1-chatbot.hf.space/uploads/{os.path.basename(image_path).replace(' ', '%20')}"
|
2889 |
+
logger.info(f"[Product] Converted local path to public URL: {media_path}")
|
|
|
|
|
|
|
|
|
2890 |
|
2891 |
+
success = send_whatsjet_message(
|
2892 |
+
from_number,
|
2893 |
+
details,
|
2894 |
+
media_type=media_type,
|
2895 |
+
media_path=media_path, # Use public URL
|
2896 |
+
filename=filename
|
2897 |
+
)
|
2898 |
+
|
2899 |
+
if success:
|
2900 |
+
logger.info(f"[Product] Successfully sent image with caption for product: {product_name}")
|
2901 |
+
else:
|
2902 |
+
logger.warning(f"[Product] Failed to send image, sending text only: {product_name}")
|
2903 |
+
send_whatsjet_message(from_number, details)
|
2904 |
+
else:
|
2905 |
+
# No image available, send text only
|
2906 |
+
logger.info(f"[Product] No image available, sending text only for: {product_name}")
|
2907 |
send_whatsjet_message(from_number, details)
|
2908 |
+
|
2909 |
+
except Exception as e:
|
2910 |
+
logger.error(f"[Product] Error sending product image with caption: {e}")
|
2911 |
+
logger.info(f"[Product] Falling back to text-only message for: {product_name}")
|
2912 |
+
send_whatsjet_message(from_number, details)
|
2913 |
|
2914 |
# Test endpoint for product image with caption
|
2915 |
@app.get("/test-product-image-with-caption")
|