-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsend_enhanced_gmail.py
More file actions
261 lines (212 loc) · 9.79 KB
/
send_enhanced_gmail.py
File metadata and controls
261 lines (212 loc) · 9.79 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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#!/usr/bin/env python3
"""
Send enhanced Gmail-style personalized outbound emails via CCAI.
Handles both basic and enhanced Gmail outbound results.
"""
import asyncio
import json
import os
import aiohttp
from pathlib import Path
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
class CCAPIClient:
"""Client for CCAI API integration."""
def __init__(self):
self.api_key = os.getenv("CCAI_API_KEY")
self.client_id = os.getenv("CCAI_CLIENT_ID")
self.email_url = os.getenv("CCAI_EMAIL_URL")
self.core_url = os.getenv("CCAI_CORE_URL")
if not self.api_key or not self.client_id:
raise ValueError("CCAI_API_KEY and CCAI_CLIENT_ID must be set in .env file")
self.headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
"Accept": "*/*",
"clientId": self.client_id,
"accountId": "1223"
}
async def send_personalized_email(self, first_name: str, last_name: str, to_email: str, subject: str, message: str):
"""Send personalized email via CCAI campaigns API."""
try:
from datetime import datetime, timedelta
import pytz
# Schedule for immediate sending
pst = pytz.timezone('America/Los_Angeles')
tomorrow = datetime.now(pst) + timedelta(days=1)
scheduled_time = tomorrow.replace(hour=16, minute=30, second=0, microsecond=0)
campaign = {
"subject": subject,
"title": f"Personalized Outbound - {first_name}",
"message": message,
"senderEmail": os.getenv("SENDER_EMAIL", "andreas@allcode.com"),
"replyEmail": os.getenv("SENDER_EMAIL", "andreas@allcode.com"),
"senderName": os.getenv("SENDER_NAME", "Andreas Garcia"),
"scheduledTimestamp": scheduled_time.isoformat(),
"scheduledTimezone": "America/Los_Angeles",
"accounts": [{
"firstName": first_name,
"lastName": last_name,
"email": to_email,
"phone": ""
}],
"campaignType": "EMAIL",
"addToList": "noList",
"contactInput": "accounts",
"fromType": "single",
"senders": []
}
async with aiohttp.ClientSession() as session:
async with session.post(
f"{self.email_url}/api/v1/campaigns",
headers=self.headers,
json=campaign
) as response:
result = await response.json()
return {
"success": response.status in [200, 201],
"status_code": response.status,
"response": result
}
except Exception as e:
return {"success": False, "error": str(e)}
async def send_enhanced_batch(results_file="enhanced_gmail_outbound_results.json"):
"""Send enhanced Gmail-style emails via CCAI."""
# Check for results file
if not Path(results_file).exists():
print(f"❌ Results file not found: {results_file}")
print("Run enhanced_gmail_outbound.py first to generate emails")
return
with open(results_file, 'r', encoding='utf-8') as f:
contacts = json.load(f)
if not contacts:
print("❌ No contacts found in results file")
return
print(f"📧 Sending {len(contacts)} enhanced personalized emails via CCAI...")
ccai_client = CCAPIClient()
sent_emails = 0
errors = []
for i, contact in enumerate(contacts, 1):
contact_info = contact["contact_info"]
# Handle both enhanced and basic email formats
email_content = contact.get("enhanced_gmail_email") or contact.get("gmail_email", "")
print(f"\n📤 Sending to {contact_info['name']} ({i}/{len(contacts)})")
# Show personalization analysis if available
if "personalization_analysis" in contact:
analysis = contact["personalization_analysis"]
print(f"🧠 Personalization: {len([k for k, v in analysis.items() if v])} factors used")
try:
# Parse email content
lines = email_content.split('\n')
subject = lines[0].replace("Subject: ", "")
# Find where the body starts
body_start = 1
while body_start < len(lines) and not lines[body_start].strip():
body_start += 1
body = '\n'.join(lines[body_start:])
# Parse name
name_parts = contact_info["name"].split()
first_name = name_parts[0] if name_parts else "Friend"
last_name = " ".join(name_parts[1:]) if len(name_parts) > 1 else ""
# Send email
email_result = await ccai_client.send_personalized_email(
first_name=first_name,
last_name=last_name,
to_email=contact_info["email"],
subject=subject,
message=body
)
if email_result["success"]:
print(f"✅ Email sent successfully")
sent_emails += 1
else:
print(f"❌ Email failed: {email_result}")
errors.append(f"Email to {contact_info['name']}: {email_result}")
except Exception as e:
print(f"❌ Email error: {e}")
errors.append(f"Email to {contact_info['name']}: {e}")
# Delay between emails
await asyncio.sleep(3)
print(f"\n🎉 Enhanced Gmail campaign completed!")
print(f"📧 Emails sent: {sent_emails}")
if errors:
print(f"⚠️ Errors: {len(errors)}")
for error in errors[:3]:
print(f" {error}")
async def preview_enhanced_emails(results_file="enhanced_gmail_outbound_results.json"):
"""Preview enhanced Gmail-style emails with personalization analysis."""
if not Path(results_file).exists():
print(f"❌ Results file not found: {results_file}")
return
with open(results_file, 'r', encoding='utf-8') as f:
contacts = json.load(f)
print(f"📧 Preview of {len(contacts)} enhanced personalized emails:")
print("=" * 80)
for i, contact in enumerate(contacts[:3], 1):
contact_info = contact["contact_info"]
email_content = contact.get("enhanced_gmail_email") or contact.get("gmail_email", "")
print(f"\n📤 Email {i} - To: {contact_info['name']} ({contact_info['email']})")
print(f"🏢 Company: {contact_info['company']} | Title: {contact_info['title']}")
# Show personalization analysis
if "personalization_analysis" in contact:
analysis = contact["personalization_analysis"]
print("🧠 Personalization factors used:")
for key, value in analysis.items():
if value:
if isinstance(value, list) and value:
print(f" • {key}: {', '.join(value)}")
elif isinstance(value, str):
print(f" • {key}: {value[:60]}...")
print("-" * 60)
print(email_content)
print("-" * 60)
if len(contacts) > 3:
print(f"\n... and {len(contacts) - 3} more personalized emails")
async def analyze_personalization_stats(results_file="enhanced_gmail_outbound_results.json"):
"""Analyze personalization statistics from the results."""
if not Path(results_file).exists():
print(f"❌ Results file not found: {results_file}")
return
with open(results_file, 'r', encoding='utf-8') as f:
contacts = json.load(f)
print(f"📊 Personalization Analysis for {len(contacts)} contacts:")
print("=" * 50)
# Count personalization factors
factor_counts = {}
for contact in contacts:
if "personalization_analysis" in contact:
analysis = contact["personalization_analysis"]
for key, value in analysis.items():
if value:
factor_counts[key] = factor_counts.get(key, 0) + 1
print("🧠 Personalization factors used:")
for factor, count in sorted(factor_counts.items(), key=lambda x: x[1], reverse=True):
percentage = (count / len(contacts)) * 100
print(f" • {factor}: {count}/{len(contacts)} ({percentage:.1f}%)")
# Show sample personalizations
print(f"\n📝 Sample personalizations:")
for i, contact in enumerate(contacts[:2], 1):
if "personalization_analysis" in contact:
print(f"\n{i}. {contact['contact_info']['name']}:")
analysis = contact["personalization_analysis"]
for key, value in analysis.items():
if value and isinstance(value, str) and len(value) > 10:
print(f" • {key}: {value[:80]}...")
if __name__ == "__main__":
import sys
print("🚀 Enhanced Gmail-Style Email Sender")
print("=" * 40)
if len(sys.argv) > 1:
if sys.argv[1] == "preview":
asyncio.run(preview_enhanced_emails())
elif sys.argv[1] == "stats":
asyncio.run(analyze_personalization_stats())
elif sys.argv[1] == "basic":
# Send basic Gmail emails
asyncio.run(send_enhanced_batch("gmail_outbound_results.json"))
else:
print("Usage: python send_enhanced_gmail.py [preview|stats|basic]")
else:
# Send enhanced emails by default
asyncio.run(send_enhanced_batch())