自动化邮件发送系统 - 使用 Google Sheets 管理联系人,通过 Gmail API 发送随机化邮件内容。
所有功能已就绪!
- ✅ Google Sheets 集成 (OAuth 认证)
- ✅ Gmail API 集成 (OAuth 认证)
- ✅ 随机化邮件模板 (防止垃圾邮件标记)
- ✅ 代理支持 (Clash Verge)
- ✅ SSL 问题已修复
- ✅ LaunchD 自动化 (每天 9:30 AM)
- ✅ 完整日志记录
在你的 Google Sheet 中,确保有以下列:
| Company Name | Customer Name | Status | sent date | variation seed | |
|---|---|---|---|---|---|
| Test Company | John Doe | john@example.com | to send | ||
| ABC Corp | alice@test.com | to send |
重要字段说明:
- Company Name: 公司名称(备用名称)
- Customer Name: 联系人姓名(优先使用)
- Email: 邮箱地址(必填,否则会跳过)
- Status: 设置为
to send才会发送邮件 - sent date: 发送时间(自动填写)
- variation seed: 模板版本(自动填写)
cd /Users/sensor/cursor_project/email-auto-sender
python main.py# 查看输出日志
cat log/out.log
# 查看错误日志
cat log/err.log
# 实时查看日志
tail -f log/out.log在 config.py 中已配置:
GOOGLE_SHEET_ADDR = "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/..."系统会自动提取 Spreadsheet ID。
# config.py
USE_PROXY = True # 使用代理(中国大陆必须)
VERIFY_SSL = False # 禁用 SSL 验证(解决代理 SSL 问题)
CLASH_PROXY_HOST = "127.0.0.1"
CLASH_PROXY_PORT = 7897所有邮件自动包含签名:
Best regards,
Joey Chen
Fujian Lohas Technology
www.fjlohas.com
WA +86 18959339019
修改签名:编辑 templates_config.py
系统有 2 个邮件模板(Stage 1 和 Stage 2),每个模板有数百万种变体:
- 简单自我介绍
- 工厂背景
- 产品优势
- 邀请通话
- 礼貌跟进
- 强调灵活性(MOQ、混装等)
- 询问需求
- 邀请反馈
示例邮件:
Subject: Quick hello from our xxx factory in Fujian, China
Hi John,
Hope you're doing well! We're reaching out from a xxx
factory in Fujian, China. We specialize in OEM/ODM work.
We've been supporting companies in international markets who need
quality partners for popular products.
If you're interested, I could share a few models we have.
Can a short chat fit your schedule sometime next week?
Best regards,
Jason
Lohas Technology
WA +86 xxx
系统每天自动运行一次:
运行时间: 每天 09:30 AM
配置文件: ~/Library/LaunchAgents/com.yourname.emailsender.plist
# 查看状态
launchctl list | grep emailsender
# 重新加载配置
launchctl unload ~/Library/LaunchAgents/com.yourname.emailsender.plist
launchctl load ~/Library/LaunchAgents/com.yourname.emailsender.plist
# 立即运行(不等待 9:30)
launchctl start com.user.emailsender
# 查看详细信息
launchctl print gui/$(id -u)/com.user.emailsender┌─────────────────────────────────────────┐
│ LaunchD (9:30 AM Daily) │
└──────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ 1. 连接 Google Sheets │
│ 2. 读取 status='to send' 的行 │
│ 3. 跳过没有邮箱的行 │
└──────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ 对每个任务: │
│ 1. 生成随机邮件内容 │
│ 2. 通过 Gmail API 发送 │
│ 3. 更新 status='sent' │
│ 4. 记录发送时间和模板版本 │
│ 5. 等待 2-5 分钟后发送下一封 │
└─────────────────────────────────────────┘
检查 1: Google Sheet 中是否有 status='to send' 的行?
# 查看日志确认
cat log/out.log | grep "找到"检查 2: Email 字段是否填写?
日志会显示:⚠️ 跳过第 X 行: 没有邮箱地址
检查 3: Clash 代理是否运行?
curl -I --proxy http://127.0.0.1:7897 https://www.google.com如果看到认证错误,手动运行一次重新认证:
cd /Users/sensor/cursor_project/email-auto-sender
python main.py浏览器会打开进行 OAuth 认证。
系统已配置 VERIFY_SSL=False 来解决代理 SSL 问题。
如果仍有问题,检查 config.py:
VERIFY_SSL = False # 必须为 Falseemail-auto-sender/
├── main.py # 主程序入口
├── config.py # 配置文件
├── templates_config.py # 邮件模板
├── gmail_client.py # Gmail API 客户端
├── sheets_client.py # Google Sheets 客户端
├── network.py # 代理配置
├── credentials.json # OAuth 客户端凭证
├── token.json # Gmail OAuth token
├── sheets_token.json # Sheets OAuth token
├── log/
│ ├── out.log # 标准输出日志
│ └── err.log # 错误日志
└── test_integration.py # 集成测试
python test_integration.py不会实际发送邮件,只模拟流程。
python test_integration.py --send会真正发送邮件并更新 Sheet。
python test_template_randomization.py验证邮件内容的多样性。
python test_sheets_connection.py验证 Sheets API 连接。
编辑 ~/Library/LaunchAgents/com.yourname.emailsender.plist:
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>9</integer> <!-- 修改小时 -->
<key>Minute</key>
<integer>30</integer> <!-- 修改分钟 -->
</dict>然后重新加载:
launchctl unload ~/Library/LaunchAgents/com.yourname.emailsender.plist
launchctl load ~/Library/LaunchAgents/com.yourname.emailsender.plist编辑 main.py:
delay = random.randint(120, 300) # 2-5分钟编辑 templates_config.py,添加 Stage 3:
TEMPLATES = {
1: { ... },
2: { ... },
3: {
"subject": "...",
"body": "..."
}
}邮件中的 {name} 字段使用以下逻辑:
- 优先: Customer Name
- 备用: Company Name (如果 Customer Name 为空)
示例:
- Customer Name = "John", Company Name = "ABC" → 使用 "John"
- Customer Name = "", Company Name = "ABC" → 使用 "ABC"
- 系统默认每封邮件间隔 2-5 分钟(随机)
- 建议每天不超过 50 封
- 避免发送过快触发 Gmail 限制
- 确保邮箱地址准确
- 填写 Customer Name 或 Company Name
- 定期检查邮件是否进入垃圾箱
- 每天查看
log/out.log确认发送状态 - 检查 Google Sheet 的 status 是否更新为 'sent'
- 关注发送成功率
token.json和sheets_token.json包含访问令牌- 不要分享这些文件
- 已在
.gitignore中排除(如果使用 git)
VERIFY_SSL=False仅用于解决本地代理 SSL 问题- 连接仍通过 HTTPS 加密
- 代理是本地 Clash Verge,安全可控
Q: 为什么没有发送邮件?
A: 检查 Google Sheet 中是否有 status='to send' 且 email 不为空的行。
Q: 如何修改邮件签名?
A: 编辑 templates_config.py 中的签名部分。
Q: 可以手动触发发送吗?
A: 可以,运行 launchctl start com.user.emailsender
Q: 如何停止自动发送?
A: 运行 launchctl unload ~/Library/LaunchAgents/com.yourname.emailsender.plist
# 测试运行
python main.py
# 查看日志
tail -20 log/out.log
# 立即触发
launchctl start com.user.emailsender
# 停止自动运行
launchctl unload ~/Library/LaunchAgents/com.yourname.emailsender.plist
# 重新启动自动运行
launchctl load ~/Library/LaunchAgents/com.yourname.emailsender.plist
# 查看状态
launchctl list | grep emailsender-
添加测试数据到 Google Sheet
- 至少一行包含有效邮箱
- Status 设置为 'to send'
-
手动测试一次
python main.py
-
检查发送结果
- 查看日志:
cat log/out.log - 检查 Sheet status 是否更新为 'sent'
- 检查收件箱是否收到邮件
- 查看日志:
-
等待明天 9:30 AM 自动运行,或立即触发:
launchctl start com.user.emailsender
系统已就绪!🎉
更多详情查看:
LAUNCHD_TROUBLESHOOTING.md- LaunchD 故障排查test_integration.py- 完整测试test_template_randomization.py- 模板测试