167 lines
6.4 KiB
Python
167 lines
6.4 KiB
Python
import requests
|
|
import logging
|
|
import json
|
|
from django.conf import settings
|
|
from .models import PlatformProfile
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def get_whatsapp_credentials():
|
|
"""
|
|
Retrieves Wablas WhatsApp credentials from PlatformProfile.
|
|
Returns tuple: (api_token, secret_key, domain, source_info)
|
|
"""
|
|
# Defaults
|
|
api_token = settings.WHATSAPP_API_KEY if hasattr(settings, 'WHATSAPP_API_KEY') else ""
|
|
# We repurpose Phone ID as Domain in settings if needed, or default to Wablas DEU
|
|
domain = "https://deu.wablas.com"
|
|
secret_key = "" # Add this to settings if you want env support, but for now mostly DB
|
|
source = "Settings/Env"
|
|
|
|
# Try to fetch from PlatformProfile
|
|
try:
|
|
profile = PlatformProfile.objects.first()
|
|
if profile:
|
|
# Check for token override
|
|
if profile.whatsapp_access_token:
|
|
api_token = profile.whatsapp_access_token.strip()
|
|
source = "Database (PlatformProfile)"
|
|
|
|
# Check for secret key override
|
|
if profile.whatsapp_app_secret:
|
|
secret_key = profile.whatsapp_app_secret.strip()
|
|
|
|
# Check for domain override
|
|
if profile.whatsapp_business_phone_number_id:
|
|
domain = profile.whatsapp_business_phone_number_id.strip()
|
|
# Ensure no trailing slash
|
|
if domain.endswith('/'):
|
|
domain = domain[:-1]
|
|
|
|
except Exception as e:
|
|
logger.warning(f"Failed to fetch PlatformProfile for WhatsApp config: {e}")
|
|
|
|
return api_token, secret_key, domain, source
|
|
|
|
def send_whatsapp_message(phone_number, message):
|
|
"""
|
|
Sends a WhatsApp message using the Wablas gateway.
|
|
Returns True if successful, False otherwise.
|
|
"""
|
|
success, _ = send_whatsapp_message_detailed(phone_number, message)
|
|
return success
|
|
|
|
def send_whatsapp_message_detailed(phone_number, message):
|
|
"""
|
|
Sends a WhatsApp message via Wablas V2 API and returns detailed status.
|
|
Returns tuple: (success: bool, response_msg: str)
|
|
"""
|
|
if not getattr(settings, 'WHATSAPP_ENABLED', True):
|
|
msg = "WhatsApp notifications are disabled by settings (WHATSAPP_ENABLED=False)."
|
|
logger.info(msg)
|
|
return False, msg
|
|
|
|
api_token, secret_key, domain, source = get_whatsapp_credentials()
|
|
|
|
if not api_token:
|
|
msg = f"WhatsApp API configuration (Token) is missing. (Source: {source})"
|
|
logger.warning(msg)
|
|
return False, msg
|
|
|
|
# Normalize phone number (Wablas expects international format without +, e.g. 628123...)
|
|
# Remove all non-digits
|
|
clean_phone = "".join(filter(str.isdigit, str(phone_number)))
|
|
|
|
# Construct Authorization Header
|
|
# Wablas V2: Authorization: {$token}.{$secret_key}
|
|
# Some Wablas servers just need Token, but docs say Token.Secret
|
|
auth_header = api_token
|
|
if secret_key:
|
|
auth_header = f"{api_token}.{secret_key}"
|
|
|
|
# Endpoint V2
|
|
url = f"{domain}/api/v2/send-message"
|
|
|
|
headers = {
|
|
"Authorization": auth_header,
|
|
"Content-Type": "application/json",
|
|
}
|
|
|
|
payload = {
|
|
"data": [
|
|
{
|
|
"phone": clean_phone,
|
|
"message": message,
|
|
"isGroup": "false",
|
|
"flag": "instant" # Priority
|
|
}
|
|
]
|
|
}
|
|
|
|
try:
|
|
response = requests.post(url, headers=headers, json=payload, timeout=15)
|
|
response_data = response.json()
|
|
|
|
# Wablas success usually has status: true
|
|
if response.status_code == 200 and response_data.get('status') is not False:
|
|
logger.info(f"WhatsApp message sent to {clean_phone} via Wablas")
|
|
return True, f"Message sent successfully via Wablas. (Source: {source})"
|
|
else:
|
|
error_msg = f"Wablas API error (Source: {source}): {response.status_code} - {response_data}"
|
|
logger.error(error_msg)
|
|
return False, error_msg
|
|
except Exception as e:
|
|
error_msg = f"Failed to send WhatsApp message via Wablas (Source: {source}): {str(e)}"
|
|
logger.error(error_msg)
|
|
return False, error_msg
|
|
|
|
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) |