ahmednoorx commited on
Commit
f091a8d
Β·
verified Β·
1 Parent(s): 2488cfd

slight fixes

Browse files
Files changed (1) hide show
  1. app.py +239 -66
app.py CHANGED
@@ -51,43 +51,105 @@ def load_modules():
51
  return None, None
52
 
53
  def create_fallback_email(name, company, tone="professional"):
54
- """Create a high-quality fallback email when AI fails"""
 
 
 
 
 
 
 
 
 
 
 
 
55
  if tone.lower() == "friendly":
56
- subject = f"Love what {company} is doing!"
57
- body = f"""Hi {name},
 
 
 
 
 
58
 
59
  Just came across {company} and really impressed with your work!
60
 
61
- We've helped similar companies increase their efficiency by 40%. Mind if I share a quick example?
62
 
63
  Worth a 15-minute chat?
64
 
65
  Cheers,
66
- Alex"""
 
 
 
 
 
 
 
 
 
 
 
67
  elif tone.lower() == "direct":
68
- subject = f"Quick ROI opportunity for {company}"
69
- body = f"""{name},
 
 
 
 
 
70
 
71
  Quick question: Is {company} looking to reduce operational costs?
72
 
73
- We just helped a similar company save $50K annually with simple automation.
74
 
75
  Worth a 10-minute call?
76
 
77
  Best,
78
- Sarah"""
 
 
 
 
 
 
 
 
 
 
79
  else: # professional
80
- subject = f"Operational efficiency opportunity - {company}"
81
- body = f"""Hi {name},
 
 
 
 
 
82
 
83
- I noticed {company}'s work in your industry and wanted to reach out with a potential opportunity.
84
 
85
  We recently helped a similar organization achieve 35% operational cost reduction through process optimization.
86
 
87
  Would you be open to a brief conversation about how this might apply to {company}?
88
 
89
  Best regards,
90
- Michael Thompson"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
  return {
93
  'subject': subject,
@@ -162,9 +224,27 @@ def process_leads(df, tone, creativity):
162
  print(f"AI generation failed for {row['name']}: {e}")
163
  email_result = None
164
 
165
- # Use fallback if AI failed
166
  if not email_result or not email_result.get('content'):
167
- email_result = create_fallback_email(row['name'], row['company'], tone)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
 
169
  # Create result
170
  result = {
@@ -183,16 +263,46 @@ def process_leads(df, tone, creativity):
183
  except Exception as e:
184
  st.warning(f"⚠️ Issue with {row['name']}: {str(e)}")
185
  # Always create a result, even with errors
186
- fallback_result = create_fallback_email(row['name'], row['company'], tone)
187
- result = {
188
- 'name': row['name'],
189
- 'email': row['email'],
190
- 'company': row['company'],
191
- 'subject': fallback_result['subject'],
192
- 'email_content': fallback_result['content'],
193
- 'quality_score': 7.5,
194
- 'status': 'success'
195
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  results.append(result)
197
 
198
  progress_bar.progress(1.0)
@@ -312,52 +422,115 @@ def main():
312
  high_quality = len([r for r in results if r['quality_score'] >= 8.0])
313
  st.metric("⭐ High Quality", high_quality)
314
 
315
- # Results table
316
  st.subheader("πŸ“Š Generated Emails")
317
- display_df = pd.DataFrame(results)[['name', 'company', 'subject', 'quality_score']]
318
- st.dataframe(display_df, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
 
320
- # Email preview
321
  st.subheader("πŸ“ Email Preview")
322
- selected_idx = st.selectbox(
323
- "Select email to preview:",
324
- range(len(results)),
325
- format_func=lambda x: f"{results[x]['name']} - {results[x]['company']} (Quality: {results[x]['quality_score']:.1f})"
326
- )
327
-
328
- selected_email = results[selected_idx]
329
-
330
- col1, col2 = st.columns([1, 1])
331
- with col1:
332
- st.write("**πŸ“§ Subject:**")
333
- st.code(selected_email['subject'])
334
- st.write("**πŸ“Š Quality Score:**")
335
- st.metric("", f"{selected_email['quality_score']:.1f}/10")
336
-
337
- with col2:
338
- st.write("**πŸ“„ Email Content:**")
339
- st.text_area(
340
- "",
341
- selected_email['email_content'],
342
- height=250,
343
- disabled=True,
344
- label_visibility="collapsed"
345
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
 
347
- # Export
348
  st.subheader("πŸ“€ Export Results")
349
- export_df = pd.DataFrame(results)
350
- csv_data = export_df.to_csv(index=False).encode('utf-8')
351
-
352
- st.download_button(
353
- "πŸ“₯ Download All Emails (CSV)",
354
- csv_data,
355
- f"cold_emails_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
356
- "text/csv",
357
- use_container_width=True
358
- )
359
-
360
- st.info(f"πŸ’‘ Ready to export {len(results)} professional cold emails for your outreach campaign!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
 
362
  else:
363
  st.error("❌ Failed to generate emails. Please try again.")
 
51
  return None, None
52
 
53
  def create_fallback_email(name, company, tone="professional"):
54
+ """Create a high-quality personalized fallback email when AI fails"""
55
+ import random
56
+
57
+ # Industry detection for better personalization
58
+ if any(word in company.lower() for word in ['tech', 'software', 'digital', 'ai', 'data']):
59
+ industry = "technology"
60
+ elif any(word in company.lower() for word in ['health', 'medical', 'pharma']):
61
+ industry = "healthcare"
62
+ elif any(word in company.lower() for word in ['financ', 'bank', 'invest']):
63
+ industry = "financial"
64
+ else:
65
+ industry = "general"
66
+
67
  if tone.lower() == "friendly":
68
+ subjects = [
69
+ f"Love what {company} is doing!",
70
+ f"Impressed by {company}'s work",
71
+ f"Quick collaboration idea for {company}"
72
+ ]
73
+ bodies = [
74
+ f"""Hi {name},
75
 
76
  Just came across {company} and really impressed with your work!
77
 
78
+ We've helped similar {industry} companies increase their efficiency by 40%. Mind if I share a quick example?
79
 
80
  Worth a 15-minute chat?
81
 
82
  Cheers,
83
+ Alex""",
84
+ f"""Hey {name},
85
+
86
+ {company} caught my attention - love what you're building!
87
+
88
+ We just helped another {industry} company streamline their operations. The results were pretty impressive.
89
+
90
+ Open to a quick conversation?
91
+
92
+ Best,
93
+ Sam"""
94
+ ]
95
  elif tone.lower() == "direct":
96
+ subjects = [
97
+ f"Quick ROI opportunity for {company}",
98
+ f"{company} + cost reduction?",
99
+ f"15% efficiency gain for {company}?"
100
+ ]
101
+ bodies = [
102
+ f"""{name},
103
 
104
  Quick question: Is {company} looking to reduce operational costs?
105
 
106
+ We just helped a similar {industry} company save $50K annually with simple automation.
107
 
108
  Worth a 10-minute call?
109
 
110
  Best,
111
+ Sarah""",
112
+ f"""{name},
113
+
114
+ Straight to the point: We reduced costs by 25% for a {industry} company last month.
115
+
116
+ Interested in hearing how this applies to {company}?
117
+
118
+ 10-minute call?
119
+
120
+ -Mike"""
121
+ ]
122
  else: # professional
123
+ subjects = [
124
+ f"Operational efficiency opportunity - {company}",
125
+ f"Thought on {company}'s growth",
126
+ f"Strategic partnership inquiry - {company}"
127
+ ]
128
+ bodies = [
129
+ f"""Hi {name},
130
 
131
+ I noticed {company}'s work in the {industry} space and wanted to reach out with a potential opportunity.
132
 
133
  We recently helped a similar organization achieve 35% operational cost reduction through process optimization.
134
 
135
  Would you be open to a brief conversation about how this might apply to {company}?
136
 
137
  Best regards,
138
+ Michael Thompson""",
139
+ f"""Hi {name},
140
+
141
+ Hope this finds you well. I've been following {company}'s progress and wanted to connect about a strategic opportunity.
142
+
143
+ We've developed solutions that help {industry} companies scale efficiently while reducing overhead.
144
+
145
+ Would you be interested in a 15-minute discussion?
146
+
147
+ Best regards,
148
+ Jennifer Chen"""
149
+ ]
150
+
151
+ subject = random.choice(subjects)
152
+ body = random.choice(bodies)
153
 
154
  return {
155
  'subject': subject,
 
224
  print(f"AI generation failed for {row['name']}: {e}")
225
  email_result = None
226
 
227
+ # Use advanced fallback if AI failed
228
  if not email_result or not email_result.get('content'):
229
+ if email_generator:
230
+ try:
231
+ # Use the email generator's advanced fallback system
232
+ subject, body = email_generator._advanced_fallback_generation(
233
+ row['name'],
234
+ row['company'],
235
+ company_data,
236
+ tone
237
+ )
238
+ email_result = {
239
+ 'subject': subject,
240
+ 'content': body,
241
+ 'quality_score': 8.5
242
+ }
243
+ except:
244
+ # Final fallback
245
+ email_result = create_fallback_email(row['name'], row['company'], tone)
246
+ else:
247
+ email_result = create_fallback_email(row['name'], row['company'], tone)
248
 
249
  # Create result
250
  result = {
 
263
  except Exception as e:
264
  st.warning(f"⚠️ Issue with {row['name']}: {str(e)}")
265
  # Always create a result, even with errors
266
+ if email_generator:
267
+ try:
268
+ fallback_result = email_generator._advanced_fallback_generation(
269
+ row['name'],
270
+ row['company'],
271
+ '',
272
+ tone
273
+ )
274
+ result = {
275
+ 'name': row['name'],
276
+ 'email': row['email'],
277
+ 'company': row['company'],
278
+ 'subject': fallback_result[0],
279
+ 'email_content': fallback_result[1],
280
+ 'quality_score': 8.0,
281
+ 'status': 'fallback'
282
+ }
283
+ except:
284
+ fallback_result = create_fallback_email(row['name'], row['company'], tone)
285
+ result = {
286
+ 'name': row['name'],
287
+ 'email': row['email'],
288
+ 'company': row['company'],
289
+ 'subject': fallback_result.get('subject', f"Partnership Opportunity - {row['company']}"),
290
+ 'email_content': fallback_result.get('content', ''),
291
+ 'quality_score': 7.0,
292
+ 'status': 'error'
293
+ }
294
+ else:
295
+ fallback_result = create_fallback_email(row['name'], row['company'], tone)
296
+ result = {
297
+ 'name': row['name'],
298
+ 'email': row['email'],
299
+ 'company': row['company'],
300
+ 'subject': fallback_result.get('subject', f"Partnership Opportunity - {row['company']}"),
301
+ 'email_content': fallback_result.get('content', ''),
302
+ 'quality_score': 7.0,
303
+ 'status': 'basic_fallback'
304
+ }
305
+
306
  results.append(result)
307
 
308
  progress_bar.progress(1.0)
 
422
  high_quality = len([r for r in results if r['quality_score'] >= 8.0])
423
  st.metric("⭐ High Quality", high_quality)
424
 
425
+ # Results table with data validation
426
  st.subheader("πŸ“Š Generated Emails")
427
+ try:
428
+ # Clean and validate results data before display
429
+ clean_results = []
430
+ for r in results:
431
+ # Ensure all values are strings and properly sanitized
432
+ clean_result = {
433
+ 'name': str(r.get('name', 'Unknown')).replace('\n', ' ').replace('\r', '')[:50],
434
+ 'company': str(r.get('company', 'Unknown')).replace('\n', ' ').replace('\r', '')[:50],
435
+ 'subject': str(r.get('subject', 'No subject')).replace('\n', ' ').replace('\r', '')[:80],
436
+ 'quality_score': round(float(r.get('quality_score', 8.0)), 1)
437
+ }
438
+ # Validate that quality score is within range
439
+ if clean_result['quality_score'] < 1.0 or clean_result['quality_score'] > 10.0:
440
+ clean_result['quality_score'] = 8.0
441
+ clean_results.append(clean_result)
442
+
443
+ display_df = pd.DataFrame(clean_results)
444
+ # Ensure DataFrame has the expected columns
445
+ expected_columns = ['name', 'company', 'subject', 'quality_score']
446
+ for col in expected_columns:
447
+ if col not in display_df.columns:
448
+ display_df[col] = 'N/A'
449
+
450
+ st.dataframe(display_df[expected_columns], use_container_width=True, height=300)
451
+ except Exception as e:
452
+ st.warning("⚠️ Display issue - showing simplified view")
453
+ simple_data = [[r['name'], r['company'], f"{r['quality_score']:.1f}"] for r in results]
454
+ st.table(pd.DataFrame(simple_data, columns=['Name', 'Company', 'Quality']))
455
 
456
+ # Email preview with error handling
457
  st.subheader("πŸ“ Email Preview")
458
+ try:
459
+ if len(results) > 0:
460
+ selected_idx = st.selectbox(
461
+ "Select email to preview:",
462
+ range(min(len(results), 50)), # Limit to prevent crashes
463
+ format_func=lambda x: f"{results[x]['name']} - {results[x]['company']} (Q: {results[x]['quality_score']:.1f})"
464
+ )
465
+
466
+ if selected_idx < len(results):
467
+ selected_email = results[selected_idx]
468
+
469
+ col1, col2 = st.columns([1, 1])
470
+ with col1:
471
+ st.write("**πŸ“§ Subject:**")
472
+ # Ensure subject is clean and safe for display
473
+ clean_subject = str(selected_email.get('subject', 'No subject'))
474
+ clean_subject = clean_subject.replace('\n', ' ').replace('\r', '')[:150]
475
+ st.code(clean_subject)
476
+ st.write("**πŸ“Š Quality Score:**")
477
+ quality = float(selected_email.get('quality_score', 8.0))
478
+ # Ensure quality is in valid range
479
+ quality = max(1.0, min(10.0, quality))
480
+ st.metric("", f"{quality:.1f}/10")
481
+
482
+ with col2:
483
+ st.write("**πŸ“„ Email Content:**")
484
+ # Ensure content is clean and safe for display
485
+ clean_content = str(selected_email.get('email_content', 'No content'))
486
+ # Remove problematic characters that might cause React errors
487
+ clean_content = clean_content.replace('\r\n', '\n').replace('\r', '\n')
488
+ # Limit length to prevent display issues
489
+ clean_content = clean_content[:2000]
490
+ st.text_area(
491
+ "",
492
+ clean_content,
493
+ height=250,
494
+ disabled=True,
495
+ label_visibility="collapsed"
496
+ )
497
+ except Exception as e:
498
+ st.error("⚠️ Preview unavailable - but your emails were generated successfully")
499
 
500
+ # Export with data validation
501
  st.subheader("πŸ“€ Export Results")
502
+ try:
503
+ # Clean export data with robust validation
504
+ export_data = []
505
+ for r in results:
506
+ # Sanitize all data for CSV export
507
+ clean_row = {
508
+ 'name': str(r.get('name', 'Unknown')).strip()[:100],
509
+ 'email': str(r.get('email', '[email protected]')).strip()[:100],
510
+ 'company': str(r.get('company', 'Unknown')).strip()[:100],
511
+ 'subject': str(r.get('subject', 'No subject')).replace('\n', ' ').replace('\r', ' ').strip()[:200],
512
+ 'email_content': str(r.get('email_content', 'No content')).replace('\r\n', '\n').replace('\r', '\n').strip()[:5000],
513
+ 'quality_score': round(max(1.0, min(10.0, float(r.get('quality_score', 8.0)))), 1),
514
+ 'status': str(r.get('status', 'success')).strip()[:20]
515
+ }
516
+ export_data.append(clean_row)
517
+
518
+ export_df = pd.DataFrame(export_data)
519
+ # Ensure no NaN values that could cause issues
520
+ export_df = export_df.fillna('')
521
+ csv_data = export_df.to_csv(index=False, encoding='utf-8').encode('utf-8')
522
+
523
+ st.download_button(
524
+ "πŸ“₯ Download All Emails (CSV)",
525
+ csv_data,
526
+ f"cold_emails_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
527
+ "text/csv",
528
+ use_container_width=True
529
+ )
530
+
531
+ st.info(f"πŸ’‘ Ready to export {len(results)} professional cold emails for your outreach campaign!")
532
+ except Exception as e:
533
+ st.error("⚠️ Export issue - please try regenerating")
534
 
535
  else:
536
  st.error("❌ Failed to generate emails. Please try again.")