109 lines
3.2 KiB
Python
109 lines
3.2 KiB
Python
# Function.py
|
|
import os
|
|
import time
|
|
import requests
|
|
from dotenv import load_dotenv
|
|
|
|
# Load .env variables once
|
|
load_dotenv()
|
|
|
|
WHATSAPP_TOKEN = os.getenv("WHATSAPP_TOKEN")
|
|
WHATSAPP_PHONE_ID = os.getenv("WHATSAPP_PHONE_NUMBER_ID")
|
|
WHATSAPP_RECIPIENT = os.getenv("WHATSAPP_RECIPIENT_NUMBER")
|
|
|
|
WAPI_URL = f"https://graph.facebook.com/v21.0/{WHATSAPP_PHONE_ID}/messages"
|
|
|
|
|
|
def SendWhatsAppMessage(message: str, retries: int = 3, delay: int = 2) -> bool:
|
|
"""
|
|
Sends a WhatsApp message using the WhatsApp Cloud API test number.
|
|
Automatically retries on failure.
|
|
|
|
:param message: Text to send.
|
|
:param retries: Number of retry attempts.
|
|
:param delay: Delay between retries (seconds).
|
|
:return: True if message sent successfully, False otherwise.
|
|
"""
|
|
|
|
# --- safety check: missing config ---
|
|
if not WHATSAPP_TOKEN or not WHATSAPP_PHONE_ID or not WHATSAPP_RECIPIENT:
|
|
print("❌ WhatsApp API configuration missing in .env")
|
|
return False
|
|
|
|
headers = {
|
|
"Authorization": f"Bearer {WHATSAPP_TOKEN}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
payload = {
|
|
"messaging_product": "whatsapp",
|
|
"to": WHATSAPP_RECIPIENT,
|
|
"type": "text",
|
|
"text": {"body": message}
|
|
}
|
|
|
|
# --- retry loop ---
|
|
for attempt in range(1, retries + 1):
|
|
try:
|
|
response = requests.post(WAPI_URL, headers=headers, json=payload, timeout=15)
|
|
status = response.status_code
|
|
|
|
if status == 200:
|
|
print(f"📨 WhatsApp message sent successfully (attempt {attempt})")
|
|
return True
|
|
|
|
else:
|
|
print(f"⚠️ WhatsApp API error (attempt {attempt}): {status} {response.text}")
|
|
|
|
except requests.RequestException as e:
|
|
print(f"⚠️ Network error (attempt {attempt}): {e}")
|
|
|
|
time.sleep(delay)
|
|
|
|
print("❌ Failed to send WhatsApp message after retries.")
|
|
return False
|
|
|
|
# -----------------------------------------------------
|
|
# Find Dropbox root by reading official info.json
|
|
# -----------------------------------------------------
|
|
|
|
def get_dropbox_root() -> str | None:
|
|
# """
|
|
# Returns the absolute Dropbox folder path by reading:
|
|
# C:\Users\<user>\AppData\Local\Dropbox\info.json
|
|
# This is 100% reliable even if Dropbox changes drive letter.
|
|
# """
|
|
|
|
import os
|
|
import json
|
|
|
|
localapp = os.environ.get("LOCALAPPDATA")
|
|
if not localapp:
|
|
print("⚠️ LOCALAPPDATA not found.")
|
|
return None
|
|
|
|
info_path = os.path.join(localapp, "Dropbox", "info.json")
|
|
|
|
if not os.path.exists(info_path):
|
|
print(f"⚠️ Dropbox info.json not found at: {info_path}")
|
|
return None
|
|
|
|
try:
|
|
with open(info_path, "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
|
|
# Most users: `personal`
|
|
if "personal" in data and "path" in data["personal"]:
|
|
return data["personal"]["path"]
|
|
|
|
# Business Dropbox if used
|
|
if "business" in data and "path" in data["business"]:
|
|
return data["business"]["path"]
|
|
|
|
print("⚠️ Dropbox info.json missing 'path' in personal/business")
|
|
return None
|
|
|
|
except Exception as e:
|
|
print(f"⚠️ Error reading Dropbox info.json: {e}")
|
|
return None
|