Seth commited on
Commit
f1bcbcc
·
1 Parent(s): a941701
backend/app/main.py CHANGED
@@ -480,7 +480,7 @@ async def push_to_smartlead(request: SmartleadPushRequest, db: Session = Depends
480
 
481
  # Step 1: Add leads without custom variables (chunk in batches of 50)
482
  batch_size = 50
483
- successfully_added_leads = [] # Store leads that were successfully added
484
 
485
  for i in range(0, len(leads), batch_size):
486
  batch = leads[i:i + batch_size]
@@ -488,9 +488,45 @@ async def push_to_smartlead(request: SmartleadPushRequest, db: Session = Depends
488
  lead_batch = [item["lead_data"] for item in batch]
489
  try:
490
  response = client.add_leads_to_campaign(campaign_id, lead_batch)
491
- # Store successfully added leads with their custom vars for update
492
- successfully_added_leads.extend(batch)
493
  added_count += len(lead_batch)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
  except Exception as e:
495
  # Mark batch as failed
496
  for item in batch:
@@ -501,19 +537,30 @@ async def push_to_smartlead(request: SmartleadPushRequest, db: Session = Depends
501
  failed_count += 1
502
 
503
  # Step 2: Try to update each successfully added lead with custom variables
504
- # Note: This may not be supported by Smartlead API, but we'll try
505
- if successfully_added_leads:
506
- for item in successfully_added_leads:
507
- if item.get('custom_vars'):
508
- try:
509
- client.update_lead(campaign_id, item['email'], item['custom_vars'])
510
- except Exception as e:
511
- # If update fails, log but don't fail the entire operation
512
- # The lead was added successfully, just without custom variables
513
- errors.append({
514
- "email": item.get('email', 'unknown'),
515
- "error": f"Lead added but custom variables could not be set: {str(e)}"
516
- })
 
 
 
 
 
 
 
 
 
 
 
517
 
518
  # Update run record
519
  run.status = 'completed'
 
480
 
481
  # Step 1: Add leads without custom variables (chunk in batches of 50)
482
  batch_size = 50
483
+ leads_to_update = [] # Store leads with their lead_ids for updating custom vars
484
 
485
  for i in range(0, len(leads), batch_size):
486
  batch = leads[i:i + batch_size]
 
488
  lead_batch = [item["lead_data"] for item in batch]
489
  try:
490
  response = client.add_leads_to_campaign(campaign_id, lead_batch)
 
 
491
  added_count += len(lead_batch)
492
+
493
+ # Parse response to extract lead_ids
494
+ # Smartlead API response structure may vary - try common patterns
495
+ if isinstance(response, dict):
496
+ # Check for different response structures
497
+ added_leads = response.get('added_leads') or response.get('leads') or response.get('data') or []
498
+
499
+ # Map emails to lead_ids from response
500
+ email_to_lead_id = {}
501
+ if isinstance(added_leads, list):
502
+ for lead_info in added_leads:
503
+ if isinstance(lead_info, dict):
504
+ lead_id = lead_info.get('lead_id') or lead_info.get('id') or lead_info.get('leadId')
505
+ lead_email = lead_info.get('email') or lead_info.get('email_address')
506
+ if lead_id and lead_email:
507
+ email_to_lead_id[lead_email] = lead_id
508
+
509
+ # Store leads with their lead_ids for updating
510
+ for item in batch:
511
+ lead_email = item.get('email')
512
+ lead_id = email_to_lead_id.get(lead_email)
513
+ if lead_id and item.get('custom_vars'):
514
+ leads_to_update.append({
515
+ 'lead_id': lead_id,
516
+ 'email': lead_email,
517
+ 'custom_vars': item['custom_vars']
518
+ })
519
+ # If response doesn't have lead_ids, try to match by email order
520
+ if not email_to_lead_id and len(batch) == len(lead_batch):
521
+ # Store with email for now - we'll try to get lead_id another way
522
+ for item in batch:
523
+ if item.get('custom_vars'):
524
+ leads_to_update.append({
525
+ 'lead_id': None, # Will try to get from email lookup
526
+ 'email': item.get('email'),
527
+ 'custom_vars': item['custom_vars']
528
+ })
529
+
530
  except Exception as e:
531
  # Mark batch as failed
532
  for item in batch:
 
537
  failed_count += 1
538
 
539
  # Step 2: Try to update each successfully added lead with custom variables
540
+ # Use lead_id from the response
541
+ for item in leads_to_update:
542
+ if item.get('lead_id'):
543
+ try:
544
+ # Convert lead_id to int if it's a string
545
+ lead_id = int(item['lead_id'])
546
+ client.update_lead(campaign_id, lead_id, item['custom_vars'])
547
+ except (ValueError, TypeError) as e:
548
+ errors.append({
549
+ "email": item.get('email', 'unknown'),
550
+ "error": f"Lead added but invalid lead_id: {str(e)}"
551
+ })
552
+ except Exception as e:
553
+ # If update fails, log but don't fail the entire operation
554
+ errors.append({
555
+ "email": item.get('email', 'unknown'),
556
+ "error": f"Lead added but custom variables could not be set: {str(e)}"
557
+ })
558
+ else:
559
+ # If we don't have lead_id, log an error
560
+ errors.append({
561
+ "email": item.get('email', 'unknown'),
562
+ "error": "Lead added but lead_id not found in response - cannot update custom variables"
563
+ })
564
 
565
  # Update run record
566
  run.status = 'completed'
backend/app/smartlead_client.py CHANGED
@@ -165,18 +165,15 @@ class SmartleadClient:
165
  """Update campaign settings"""
166
  return self._make_request("POST", f"/campaigns/{campaign_id}/settings", settings)
167
 
168
- def update_lead(self, campaign_id: str, lead_email: str, custom_variables: Dict) -> Dict:
169
  """Update a lead's custom variables after adding to campaign
170
 
171
- This may use a different endpoint structure. Common patterns:
172
- - PUT /campaigns/{campaign_id}/leads/{email}
173
- - POST /campaigns/{campaign_id}/leads/{email}/update
174
- - POST /campaigns/{campaign_id}/leads/update
175
  """
176
- # Try different endpoint patterns
177
  endpoints = [
178
- f"/campaigns/{campaign_id}/leads/{lead_email}",
179
- f"/campaigns/{campaign_id}/leads/{lead_email}/update",
180
  f"/campaigns/{campaign_id}/leads/update"
181
  ]
182
 
@@ -186,7 +183,7 @@ class SmartleadClient:
186
  {"custom_variables": custom_variables},
187
  {"variables": custom_variables},
188
  {"customFields": custom_variables},
189
- {"email": lead_email, **custom_variables}, # Include email with custom vars
190
  ]
191
 
192
  last_error = None
@@ -206,7 +203,7 @@ class SmartleadClient:
206
  raise
207
 
208
  # If all variations failed, raise the last error
209
- raise last_error if last_error else Exception(f"Failed to update lead {lead_email}: All endpoint variations failed")
210
 
211
  def build_sequences(self, steps_count: int) -> List[Dict]:
212
  """Build sequence templates for campaign
 
165
  """Update campaign settings"""
166
  return self._make_request("POST", f"/campaigns/{campaign_id}/settings", settings)
167
 
168
+ def update_lead(self, campaign_id: str, lead_id: int, custom_variables: Dict) -> Dict:
169
  """Update a lead's custom variables after adding to campaign
170
 
171
+ Smartlead API requires lead_id (number) to update leads.
 
 
 
172
  """
173
+ # Try different endpoint patterns with lead_id
174
  endpoints = [
175
+ f"/campaigns/{campaign_id}/leads/{lead_id}",
176
+ f"/campaigns/{campaign_id}/leads/{lead_id}/update",
177
  f"/campaigns/{campaign_id}/leads/update"
178
  ]
179
 
 
183
  {"custom_variables": custom_variables},
184
  {"variables": custom_variables},
185
  {"customFields": custom_variables},
186
+ {"lead_id": lead_id, **custom_variables}, # Include lead_id with custom vars
187
  ]
188
 
189
  last_error = None
 
203
  raise
204
 
205
  # If all variations failed, raise the last error
206
+ raise last_error if last_error else Exception(f"Failed to update lead {lead_id}: All endpoint variations failed")
207
 
208
  def build_sequences(self, steps_count: int) -> List[Dict]:
209
  """Build sequence templates for campaign