forked from jatin-dot-py/zomato-intelligence
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsync_contacts.py
More file actions
153 lines (123 loc) · 4.5 KB
/
sync_contacts.py
File metadata and controls
153 lines (123 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import requests
import json
import re
def validate_phone(number):
"""
Validate and normalize Indian phone number.
Returns normalized format like "+91 99999 99999" or None if invalid.
"""
# Remove all spaces, dashes, dots
cleaned = re.sub(r'[\s\-\.]', '', number)
# Check various formats
if re.match(r'^\+91\d{10}$', cleaned):
# +919999999999 -> +91 99999 99999
digits = cleaned[3:]
elif re.match(r'^91\d{10}$', cleaned):
# 919999999999 -> +91 99999 99999
digits = cleaned[2:]
elif re.match(r'^0\d{10}$', cleaned):
# 09999999999 -> +91 99999 99999
digits = cleaned[1:]
elif re.match(r'^\d{10}$', cleaned):
# 9999999999 -> +91 99999 99999
digits = cleaned
else:
return None
# Format as "+91 XXXXX XXXXX"
return f"+91 {digits[:5]} {digits[5:]}"
def parse_phones(phones_csv=None, phones_file=None):
"""
Parse phone numbers from comma-separated string or file.
Returns list of raw phone strings.
"""
phones = []
if phones_csv:
phones = [p.strip() for p in phones_csv.split(',') if p.strip()]
elif phones_file:
with open(phones_file, 'r') as f:
phones = [line.strip() for line in f if line.strip()]
return phones
def build_contacts(phones):
"""
Build contacts array in Zomato format.
Returns tuple: (contacts_list, errors_list)
"""
contacts = []
errors = []
for i, phone in enumerate(phones):
normalized = validate_phone(phone)
if not normalized:
errors.append(f"Invalid: '{phone}' - Use format: +919999999999, 9999999999, or 09999999999")
continue
# Extract just digits for name
digits = re.sub(r'\D', '', normalized)[-10:]
contacts.append({
"phone_numbers": [normalized],
"name": f"poc_contact_{digits}",
"id": str(i + 1)
})
return contacts, errors
def sync_contacts(zomato_token, phones_csv=None, phones_file=None, proxies=None):
"""
Sync contacts to Zomato.
Args:
zomato_token: X-Zomato-Access-Token
phones_csv: Comma separated phone numbers (e.g. "9999999999,8888888888")
phones_file: Path to text file with one phone per line
Returns dict with success status and synced contacts.
"""
if not phones_csv and not phones_file:
return {'success': False, 'error': 'Provide phones_csv or phones_file'}
if phones_csv and phones_file:
return {'success': False, 'error': 'Provide only one: phones_csv OR phones_file'}
# Parse phones
phones = parse_phones(phones_csv, phones_file)
if not phones:
return {'success': False, 'error': 'No phone numbers provided'}
# Build contacts
contacts, errors = build_contacts(phones)
if errors:
return {
'success': False,
'error': 'Invalid phone numbers',
'validation_errors': errors,
'examples': ['+919999999999', '9999999999', '09876543210']
}
if not contacts:
return {'success': False, 'error': 'No valid contacts to sync'}
url = "https://api.zomato.com/gw/user-preference/recommendation/sync-contacts"
headers = {
"Accept": "image/webp",
"Accept-Encoding": "gzip, deflate, br",
"Content-Type": "application/json; charset=utf-8",
"Host": "api.zomato.com",
"X-Zomato-Access-Token": zomato_token,
"X-Zomato-API-Key": "7749b19667964b87a3efc739e254ada2",
"X-Zomato-App-Version": "931",
"X-Zomato-App-Version-Code": "1710019310",
"X-Zomato-Client-Id": "5276d7f1-910b-4243-92ea-d27e758ad02b"
}
payload = {
"flow_type": "revamped_flow",
"contacts_access_level": "full_access",
"contacts": contacts,
"location": {
"city_id": 11111,
"place": {
"delivery_subzone_id": 11111
}
}
}
try:
response = requests.post(url, json=payload, headers=headers, proxies=proxies, verify=True if not proxies else False)
success = response.status_code >= 200 and response.status_code < 300
return {
'success': success,
'status_code': response.status_code,
'response': response.json() if response.text else None
}
except Exception as e:
return {
'success': False,
'error': str(e)
}