invy/backend/google_contacts.py
2025-12-29 11:09:20 +02:00

128 lines
4.0 KiB
Python

import httpx
from sqlalchemy.orm import Session
import models
import re
def normalize_phone_number(phone: str) -> str:
"""
Convert phone numbers from +972 format to Israeli 0 format
Examples:
+972501234567 -> 0501234567
+972-50-123-4567 -> 0501234567
972501234567 -> 0501234567
"""
if not phone:
return phone
# Remove all non-digit characters except +
cleaned = re.sub(r'[^\d+]', '', phone)
# Handle +972 format
if cleaned.startswith('+972'):
# Remove +972 and add 0 prefix
return '0' + cleaned[4:]
elif cleaned.startswith('972'):
# Remove 972 and add 0 prefix
return '0' + cleaned[3:]
# If already starts with 0, return as is
if cleaned.startswith('0'):
return cleaned
# If it's a 9-digit number (Israeli mobile without prefix), add 0
if len(cleaned) == 9 and cleaned[0] in '5789':
return '0' + cleaned
return cleaned
async def import_contacts_from_google(access_token: str, db: Session, owner: str = None) -> int:
"""
Import contacts from Google People API
Args:
access_token: OAuth 2.0 access token from Google
db: Database session
owner: Name of the person importing (e.g., 'me', 'fianc\u00e9')
Returns:
Number of contacts imported
"""
headers = {
"Authorization": f"Bearer {access_token}"
}
# Google People API endpoint
url = "https://people.googleapis.com/v1/people/me/connections"
params = {
"personFields": "names,phoneNumbers,emailAddresses",
"pageSize": 1000
}
imported_count = 0
async with httpx.AsyncClient() as client:
response = await client.get(url, headers=headers, params=params)
if response.status_code != 200:
raise Exception(f"Failed to fetch contacts: {response.text}")
data = response.json()
connections = data.get("connections", [])
for connection in connections:
# Extract name
names = connection.get("names", [])
if not names:
continue
name = names[0]
first_name = name.get("givenName", "")
last_name = name.get("familyName", "")
if not first_name and not last_name:
continue
# Extract email
emails = connection.get("emailAddresses", [])
email = emails[0].get("value") if emails else None
# Extract phone number
phones = connection.get("phoneNumbers", [])
phone_number = phones[0].get("value") if phones else None
# Normalize phone number to Israeli format (0...)
if phone_number:
phone_number = normalize_phone_number(phone_number)
# Check if contact already exists by email OR phone number
existing = None
if email:
existing = db.query(models.Guest).filter(models.Guest.email == email).first()
if not existing and phone_number:
existing = db.query(models.Guest).filter(models.Guest.phone_number == phone_number).first()
if existing:
# Contact exists - merge owners
if existing.owner and owner not in existing.owner.split(","):
# Add current owner to existing owners
existing.owner = f"{existing.owner},{owner}"
db.add(existing)
else:
# Create new guest
guest = models.Guest(
first_name=first_name or "Unknown",
last_name=last_name or "",
email=email,
phone_number=phone_number,
rsvp_status="pending",
owner=owner
)
db.add(guest)
imported_count += 1
db.commit()
return imported_count