37794-vm/core/whatsapp_utils.py
2026-01-25 12:05:49 +00:00

125 lines
4.7 KiB
Python

import requests
import logging
from django.conf import settings
from .models import PlatformProfile
logger = logging.getLogger(__name__)
def get_whatsapp_credentials():
"""
Retrieves WhatsApp credentials from PlatformProfile (preferred) or settings.
Returns tuple: (api_key, phone_id)
"""
# Default to settings
api_key = settings.WHATSAPP_API_KEY
phone_id = settings.WHATSAPP_PHONE_ID
# Try to fetch from PlatformProfile
try:
profile = PlatformProfile.objects.first()
if profile:
if profile.whatsapp_access_token:
api_key = profile.whatsapp_access_token
if profile.whatsapp_business_phone_number_id:
phone_id = profile.whatsapp_business_phone_number_id
except Exception as e:
logger.warning(f"Failed to fetch PlatformProfile for WhatsApp config: {e}")
return api_key, phone_id
def send_whatsapp_message(phone_number, message):
"""
Sends a WhatsApp message using the configured gateway.
This implementation assumes Meta WhatsApp Business API (Graph API).
"""
if not settings.WHATSAPP_ENABLED:
logger.info("WhatsApp notifications are disabled by settings.")
return False
api_key, phone_id = get_whatsapp_credentials()
if not api_key or not phone_id:
logger.warning("WhatsApp API configuration is missing (checked PlatformProfile and settings).")
return False
# Normalize phone number (ensure it has country code and no +)
clean_phone = "".join(filter(str.isdigit, str(phone_number)))
url = f"https://graph.facebook.com/v17.0/{phone_id}/messages"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
payload = {
"messaging_product": "whatsapp",
"to": clean_phone,
"type": "text",
"text": {"body": message}
}
try:
response = requests.post(url, headers=headers, json=payload, timeout=10)
response_data = response.json()
if response.status_code == 200:
logger.info(f"WhatsApp message sent to {clean_phone}")
return True
else:
logger.error(f"WhatsApp API error: {response.status_code} - {response_data}")
return False
except Exception as e:
logger.error(f"Failed to send WhatsApp message: {str(e)}")
return False
def notify_shipment_created(parcel):
"""Notifies the shipper that the shipment request was received."""
shipper_name = parcel.shipper.get_full_name() or parcel.shipper.username
message = f"""Hello {shipper_name},
Your shipment request for '{parcel.description}' has been received.
Tracking Number: {parcel.tracking_number}
Status: {parcel.get_status_display()}
Please proceed to payment to make it visible to drivers."""
if hasattr(parcel.shipper, 'profile') and parcel.shipper.profile.phone_number:
return send_whatsapp_message(parcel.shipper.profile.phone_number, message)
return False
def notify_payment_received(parcel):
"""Notifies the shipper and receiver about successful payment."""
# Notify Shipper
shipper_name = parcel.shipper.get_full_name() or parcel.shipper.username
shipper_msg = f"""Payment successful for shipment {parcel.tracking_number}.
Your shipment is now visible to available drivers."""
if hasattr(parcel.shipper, 'profile') and parcel.shipper.profile.phone_number:
send_whatsapp_message(parcel.shipper.profile.phone_number, shipper_msg)
# Notify Receiver
receiver_msg = f"""Hello {parcel.receiver_name},
A shipment is coming your way from {shipper_name}.
Tracking Number: {parcel.tracking_number}
Status: {parcel.get_status_display()}"""
send_whatsapp_message(parcel.receiver_phone, receiver_msg)
def notify_driver_assigned(parcel):
"""Notifies the shipper and receiver that a driver has picked up the parcel."""
driver_name = parcel.carrier.get_full_name() or parcel.carrier.username
msg = f"""Shipment {parcel.tracking_number} has been picked up by {driver_name}.
Status: {parcel.get_status_display()}"""
if hasattr(parcel.shipper, 'profile') and parcel.shipper.profile.phone_number:
send_whatsapp_message(parcel.shipper.profile.phone_number, msg)
send_whatsapp_message(parcel.receiver_phone, msg)
def notify_status_change(parcel):
"""Notifies parties about general status updates (In Transit, Delivered)."""
msg = f"""Update for shipment {parcel.tracking_number}:
New Status: {parcel.get_status_display()}"""
if hasattr(parcel.shipper, 'profile') and parcel.shipper.profile.phone_number:
send_whatsapp_message(parcel.shipper.profile.phone_number, msg)
send_whatsapp_message(parcel.receiver_phone, msg)