cold-email-outreach
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCold Email Outreach
冷邮件推广
The final mile of the outbound pipeline. Takes qualified leads from Supabase, builds email sequences using the skill, loads campaigns into the user's chosen outreach tool, and logs everything back to Supabase.
email-draftingTool-agnostic: Asks the user which outreach platform they use. Defaults to Smartlead if they have MCP tools configured. Falls back to CSV export for any other tool or manual workflow.
outbound转化流程的最后一环。从Supabase获取合格的潜在客户,使用技能构建邮件序列,将营销活动导入用户选择的推广工具,并将所有操作日志回写到Supabase。
email-drafting工具无关性: 先询问用户使用的推广平台。如果用户配置了MCP工具,默认使用Smartlead。对于其他工具或手动流程,则回退到CSV导出方式。
When to Auto-Load
何时自动加载
Load this skill when:
- User says "launch a campaign", "send outreach", "email these leads", "set up cold email"
- An upstream skill connects with "create email campaign" or "passes: supabase-eligible-leads"
- User completes and wants to act on the results
lead-qualification
在以下场景加载此技能:
- 用户提到“启动营销活动”、“发送推广邮件”、“给这些潜在客户发邮件”、“设置冷邮件”
- 上游技能通过“创建邮件营销活动”或“传递:supabase-eligible-leads”触发
- 用户完成技能后,希望对结果采取行动
lead-qualification
Supported Outreach Tools
支持的推广工具
This skill does NOT assume a specific tool. It asks first, then adapts.
| Tool | Integration | How It Works |
|---|---|---|
| Smartlead (default) | MCP tools ( | Full automation: create campaign, add sequences, import leads, configure schedule, launch |
| Instantly | CSV import | Generate CSV matching Instantly's import format, user uploads manually |
| Lemlist | CSV import | Generate CSV with Lemlist-compatible columns |
| Apollo | CSV import | Generate CSV matching Apollo sequence import format |
| Manual / Other | CSV + instructions | Export leads + emails as generic CSV, provide setup instructions |
Tool selection logic:
- Ask user in Phase 0: "Which outreach tool do you use?"
- If Smartlead → use MCP tools for full automation
- If Instantly / Lemlist / Apollo → generate tool-specific import CSV
- If Other or unknown → generate generic CSV (,
email,first_name,last_name,company,title,subjectper touch) and ask user for their tool's import requirementsbody
本技能不预设特定工具,会先询问用户,再适配对应的流程。
| 工具 | 集成方式 | 工作原理 |
|---|---|---|
| Smartlead(默认) | MCP工具( | 全自动化:创建营销活动、添加邮件序列、导入潜在客户、配置发送计划、启动活动 |
| Instantly | CSV导入 | 生成符合Instantly导入格式的CSV文件,由用户手动上传 |
| Lemlist | CSV导入 | 生成包含Lemlist兼容列的CSV文件 |
| Apollo | CSV导入 | 生成符合Apollo序列导入格式的CSV文件 |
| 手动/其他工具 | CSV+操作指南 | 将潜在客户和邮件导出为通用CSV,提供设置说明 |
工具选择逻辑:
- 阶段0询问用户:“你使用哪款推广工具?”
- 如果是Smartlead → 使用MCP工具实现全自动化
- 如果是Instantly / Lemlist / Apollo → 生成工具专属的导入CSV
- 如果是其他或未知工具 → 生成通用CSV(包含、
email、first_name、last_name、company、每个触点的title和subject),并询问用户其工具的导入要求body
Prerequisites
前置条件
Supabase
Supabase
People must be stored in Supabase with the schema from . The and tables must exist. Run if setting up fresh.
tools/supabase/schema.sqlpeopleoutreach_logpython3 tools/supabase/setup_database.pyEnvironment variables in :
.envSUPABASE_URL=https://xxx.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJ...潜在客户数据必须存储在Supabase中,且遵循定义的表结构。必须存在和表。如果是全新部署,运行完成初始化。
tools/supabase/schema.sqlpeopleoutreach_logpython3 tools/supabase/setup_database.py.envSUPABASE_URL=https://xxx.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJ...Outreach Tool
推广工具
- Smartlead: MCP tools available via . No additional setup.
mcp__smartlead__* - All others: Just need CSV export — no API keys required.
- Smartlead: 需配置MCP工具(),无需额外设置。
mcp__smartlead__* - 其他工具: 仅需支持CSV导入,无需API密钥。
Phase 0: Intake
阶段0:需求收集
Ask all questions at once. Organize by category. Skip any already answered by an upstream skill.
一次性询问所有问题,按类别整理。如果上游技能已回答部分问题,则跳过。
Campaign Goal
营销活动目标
- What's the objective? (book meetings, drive demo requests, get replies, nurture)
- What's the outreach angle or hook? (hiring signal, competitor displacement, event-based, pain-based, cold database)
- What should we name this campaign?
- 活动目标是什么?(预约会议、获取演示请求、得到回复、客户培育)
- 推广切入点或钩子是什么?(招聘信号、竞品替代、事件驱动、痛点导向、冷数据触达)
- 本次活动的名称是什么?
Outreach Tool
推广工具
- Which outreach tool do you use? (Smartlead / Instantly / Lemlist / Apollo / Other / Just give me a CSV)
- 你使用哪款推广工具?(Smartlead / Instantly / Lemlist / Apollo / 其他工具 / 仅提供CSV)
Lead Selection
潜在客户筛选
- Which leads should we target? Options:
- All leads for a specific
client_name - Specific
icp_segment - Title patterns (e.g., "VP Operations", "Director of Sales")
- Industry or location filters
- above a threshold
qualification_score - Specific (crustdata, apollo, linkedin, etc.)
source - Custom filter (describe what you want)
- All leads for a specific
- Any exclusions? (specific companies, recently contacted leads, certain titles)
- Max campaign size? (default: 200)
- 我们应该定位哪些潜在客户?可选条件:
- 特定下的所有潜在客户
client_name - 特定(理想客户画像细分)
icp_segment - 职位匹配(例如:“VP Operations”、“Director of Sales”)
- 行业或地域筛选
- 高于指定阈值
qualification_score - 特定(crustdata、apollo、linkedin等)
source - 自定义筛选(描述你的需求)
- 特定
- 有没有需要排除的对象?(特定公司、近期已联系过的潜在客户、特定职位)
- 活动最大规模?(默认:200个潜在客户)
Sequence Design
邮件序列设计
- How many touches? (default: 3)
- Timing between touches? (default: Day 1 / Day 5 / Day 12)
- Personalization tier? (Tier 1: merge fields only / Tier 2: segment-specific / Tier 3: unique per lead)
- 包含多少个邮件触点?(默认:3个)
- 触点之间的时间间隔?(默认:第1天 / 第5天 / 第12天)
- 个性化等级?(等级1:仅合并字段 / 等级2:细分群体专属 / 等级3:每个潜在客户专属)
Sending Config (skip if CSV export)
发送配置(CSV导出模式下跳过)
- Which email accounts should send? (list accounts or "use all available")
- Sending schedule? (default: Mon-Fri 8am-5pm in recipient's timezone)
- Daily send limit per account? (default: 30/day)
- Track opens and clicks? (default: opens yes, clicks no)
- 使用哪些邮箱账户发送?(列出账户或“使用所有可用账户”)
- 发送时间计划?(默认:收件人时区的周一至周五8:00-17:00)
- 每个账户的每日发送上限?(默认:30封/天)
- 是否追踪打开和点击?(默认:追踪打开,不追踪点击)
Phase 1: Lead Selection from Supabase
阶段1:从Supabase筛选潜在客户
Connect
连接Supabase
Use the shared Supabase client:
python
import sys, os
sys.path.insert(0, os.path.join("tools", "supabase"))
from supabase_client import SupabaseClient
client = SupabaseClient(os.environ["SUPABASE_URL"], os.environ["SUPABASE_SERVICE_ROLE_KEY"])使用共享的Supabase客户端:
python
import sys, os
sys.path.insert(0, os.path.join("tools", "supabase"))
from supabase_client import SupabaseClient
client = SupabaseClient(os.environ["SUPABASE_URL"], os.environ["SUPABASE_SERVICE_ROLE_KEY"])Build Filters
构建筛选条件
Map user criteria to PostgREST query parameters on the table:
people| User Says | PostgREST Filter |
|---|---|
| "VP Operations" | |
| Client "happy-robot" | |
| Score > 7 | |
| Has verified email | |
| Industry "logistics" | |
| Location "San Francisco" | |
| Source "crustdata" | |
| Not contacted in 84 days | |
将用户的筛选条件映射到表的PostgREST查询参数:
people| 用户需求 | PostgREST筛选条件 |
|---|---|
| "VP Operations" | |
| 客户"happy-robot" | |
| 评分>7 | |
| 邮箱已验证 | |
| 行业为“物流” | |
| 地域为“旧金山” | |
| 来源为“crustdata” | |
| 84天内未联系 | |
Cooldown Filter (Mandatory)
冷却期筛选(强制要求)
Always exclude people contacted within 84 days (12 weeks). This is not optional.
Use the shared client's method:
check_cooldown()python
in_cooldown = client.check_cooldown(client_name="happy-robot", cooldown_days=84)必须排除84天内已联系过的潜在客户,此规则不可省略。
使用共享客户端的方法:
check_cooldown()python
in_cooldown = client.check_cooldown(client_name="happy-robot", cooldown_days=84)Returns set of person_id strings still in cooldown
返回仍处于冷却期的person_id字符串集合
Or query directly:
1. Query `outreach_log` for `person_id`s with `sent_date` in the last 84 days:GET /rest/v1/outreach_log?select=person_id&sent_date=gte.{84_days_ago}&status=neq.bounced&client_name=eq.{client}
2. Collect those `person_id`s into an exclusion set
3. Add `id=not.in.({excluded_ids})` to the people query
或直接查询:
1. 查询`outreach_log`表中`sent_date`在过去84天内的`person_id`:GET /rest/v1/outreach_log?select=person_id&sent_date=gte.{84_days_ago}&status=neq.bounced&client_name=eq.{client}
2. 将这些`person_id`收集到排除集合中
3. 在`people`表的查询中添加`id=not.in.({excluded_ids})`条件Present & Confirm
展示与确认
Show a sample table (10-15 leads) with:
- Name, Title, Company, Industry, Score, Email, Last Contacted
Tell user: total eligible leads, how many excluded by cooldown, how many have verified emails.
Ask user to confirm or adjust filters before proceeding.
展示包含10-15个潜在客户的样本表格,包含以下字段:
- 姓名、职位、公司、行业、评分、邮箱、最后联系时间
告知用户:符合条件的潜在客户总数、因冷却期排除的数量、邮箱已验证的数量。
询问用户是否确认筛选条件,或是否需要调整后再继续。
Phase 2: Sequence Design
阶段2:邮件序列设计
Present the sequence plan as a table before writing any copy:
| Touch | Day | Email Type | Framework | CTA |
|---|---|---|---|---|
| 1 | 1 | Cold intro | Signal-Proof-Ask | 15-min call |
| 2 | 5 | New angle / asset | PAS | Resource offer |
| 3 | 12 | Social proof | BAB | Open to chat? |
Get user approval on the structure before generating copy in Phase 3.
在生成邮件内容前,先以表格形式展示序列方案:
| 触点 | 天数 | 邮件类型 | 框架 | 行动号召(CTA) |
|---|---|---|---|---|
| 1 | 1 | 冷启动介绍 | Signal-Proof-Ask | 15分钟会议 |
| 2 | 5 | 新角度/资料 | PAS | 资源提供 |
| 3 | 12 | 社交证明 | BAB | 随时沟通? |
在阶段3生成邮件内容前,先获取用户对序列结构的确认。
Phase 3: Email Generation
阶段3:邮件生成
Load the skill and pass it:
email-drafting- Campaign context (goal, angle, product, proof points)
- Sequence structure from Phase 2
- 3-5 sample leads from the selected list
- Personalization tier
- Tone preference
加载技能,并传递以下参数:
email-drafting- 营销活动上下文(目标、切入点、产品、证明点)
- 阶段2确定的序列结构
- 筛选出的3-5个潜在客户样本
- 个性化等级
- 语气偏好
By Personalization Tier
按个性化等级生成
Tier 1 (Generic): Generate one template per touch with merge fields (, , ). Same template for all leads.
{first_name}{company}{title}Tier 2 (Segment): Generate one template per segment per touch. Segments are defined by role, industry, or signal type. Swap pain points and proof points between segments.
Tier 3 (Deep): Generate unique email per lead per touch. Cap at 50 leads — recommend Tier 2 above that volume.
等级1(通用型): 每个触点生成一个模板,包含合并字段(、、)。所有潜在客户使用同一模板。
{first_name}{company}{title}等级2(细分群体型): 每个细分群体的每个触点生成一个模板。细分群体按职位、行业或信号类型划分,不同群体使用不同的痛点和证明点。
等级3(深度个性化): 每个潜在客户的每个触点生成专属邮件。当潜在客户数量超过50时,推荐使用等级2。
Review Loop
审核循环
- Generate sample emails for 3-5 leads first
- Present to user for review
- Iterate until approved (max 3 rounds)
- Generate remaining emails after approval
- 先为3-5个潜在客户生成样本邮件
- 展示给用户审核
- 迭代优化直到用户批准(最多3轮)
- 获得批准后,生成剩余所有邮件
Phase 4: Campaign Setup
阶段4:营销活动设置
If Smartlead (MCP Automation)
若使用Smartlead(MCP自动化)
Full automation via MCP tools. Execute in this order:
Step 1: List email accounts
mcp__smartlead__get_email_accountsPresent available accounts. User selects which to use.
Step 2: Create campaign
mcp__smartlead__create_campaign
name: {campaign_name}Save the returned .
campaign_idStep 3: Add sequence steps
mcp__smartlead__save_campaign_sequences
campaign_id: {campaign_id}
sequences: [
{ seq_number: 1, subject: "...", email_body: "...", seq_delay_details: { delay_in_days: 0 } },
{ seq_number: 2, subject: "...", email_body: "...", seq_delay_details: { delay_in_days: 4 } },
{ seq_number: 3, subject: "...", email_body: "...", seq_delay_details: { delay_in_days: 7 } }
]Merge variable mapping: Convert → , → (Smartlead uses double-brace syntax).
{first_name}{{first_name}}{company}{{company}}Step 4: Import leads (batch 100)
mcp__smartlead__add_leads_to_campaign
campaign_id: {campaign_id}
lead_list: [{ email: "...", first_name: "...", last_name: "...", company_name: "...", ... }]Batch in groups of 100 if more than 100 leads.
Step 5: Assign sending accounts
mcp__smartlead__add_email_accounts_to_campaign
campaign_id: {campaign_id}
email_account_ids: [...]Step 6: Set schedule
mcp__smartlead__update_campaign_schedule
campaign_id: {campaign_id}
schedule: { ... }Step 7: Configure settings
mcp__smartlead__update_campaign_settings
campaign_id: {campaign_id}
settings: { track_opens: true, track_clicks: false, stop_on_reply: true }通过MCP工具实现全自动化,按以下顺序执行:
步骤1:列出邮箱账户
mcp__smartlead__get_email_accounts展示可用账户,由用户选择使用哪些账户。
步骤2:创建营销活动
mcp__smartlead__create_campaign
name: {campaign_name}保存返回的。
campaign_id步骤3:添加序列步骤
mcp__smartlead__save_campaign_sequences
campaign_id: {campaign_id}
sequences: [
{ seq_number: 1, subject: "...", email_body: "...", seq_delay_details: { delay_in_days: 0 } },
{ seq_number: 2, subject: "...", email_body: "...", seq_delay_details: { delay_in_days: 4 } },
{ seq_number: 3, subject: "...", email_body: "...", seq_delay_details: { delay_in_days: 7 } }
]合并变量映射: 将转换为,转换为(Smartlead使用双大括号语法)。
{first_name}{{first_name}}{company}{{company}}步骤4:导入潜在客户(批量100个)
mcp__smartlead__add_leads_to_campaign
campaign_id: {campaign_id}
lead_list: [{ email: "...", first_name: "...", last_name: "...", company_name: "...", ... }]如果潜在客户数量超过100,分批次导入。
步骤5:分配发送账户
mcp__smartlead__add_email_accounts_to_campaign
campaign_id: {campaign_id}
email_account_ids: [...]步骤6:设置发送计划
mcp__smartlead__update_campaign_schedule
campaign_id: {campaign_id}
schedule: { ... }步骤7:配置活动设置
mcp__smartlead__update_campaign_settings
campaign_id: {campaign_id}
settings: { track_opens: true, track_clicks: false, stop_on_reply: true }If CSV-Based Tool (Instantly, Lemlist, Apollo, Other)
若使用基于CSV的工具(Instantly、Lemlist、Apollo、其他)
Step 1: Generate CSV
Columns depend on personalization tier:
Tier 1 (same template for all):
- CSV columns: ,
email,first_name,last_name,company,title(signal/hook)custom_field_1 - Separate file with sequence templates (subjects + bodies with merge fields)
Tier 2/3 (per-segment or per-lead emails):
- CSV columns: ,
email,first_name,last_name,company,title,touch_1_subject,touch_1_body,touch_2_subject,touch_2_body,touch_3_subjecttouch_3_body
Step 2: Save file
skills/cold-email-outreach/output/{campaign-name}-{YYYY-MM-DD}.csvStep 3: Provide tool-specific import instructions
Instantly:
- Upload CSV → Sequences → Create new sequence
- Map columns: Email → email, First Name → first_name, etc.
- Paste sequence templates into each step
- Set delays between steps
Lemlist:
- People → Import → Upload CSV
- Map custom variables to columns
- Create campaign → add email steps → insert variables
Apollo:
- Sequences → Create Sequence → add email steps
- Contacts → Import → Upload CSV
- Add imported contacts to sequence
Other / Manual:
- Provide the CSV path and explain the column structure
- Ask user what format their tool expects, adjust if needed
步骤1:生成CSV文件
列数取决于个性化等级:
等级1(通用模板):
- CSV列:、
email、first_name、last_name、company、title(信号/切入点)custom_field_1 - 单独提供包含序列模板(主题+带合并字段的正文)的文件
等级2/3(细分群体或专属邮件):
- CSV列:、
email、first_name、last_name、company、title、touch_1_subject、touch_1_body、touch_2_subject、touch_2_body、touch_3_subjecttouch_3_body
步骤2:保存文件
skills/cold-email-outreach/output/{campaign-name}-{YYYY-MM-DD}.csv步骤3:提供工具专属的导入说明
Instantly:
- 上传CSV → 序列 → 创建新序列
- 映射列:Email → email、First Name → first_name等
- 将序列模板粘贴到每个步骤中
- 设置步骤间的延迟
Lemlist:
- 联系人 → 导入 → 上传CSV
- 将自定义变量映射到对应列
- 创建营销活动 → 添加邮件步骤 → 插入变量
Apollo:
- 序列 → 创建序列 → 添加邮件步骤
- 联系人 → 导入 → 上传CSV
- 将导入的联系人添加到序列中
其他工具/手动:
- 提供CSV文件路径并说明列结构
- 询问用户其工具所需的格式,按需调整
Phase 5: Review & Launch
阶段5:审核与启动
Present campaign summary:
Campaign: {name}
Leads: {count}
Sequence: {touches} touches over {days} days
Sending: {accounts} accounts × {daily_limit}/day = {daily_volume} emails/day
Estimated completion: {date}
Tool: {smartlead/instantly/etc.}展示营销活动摘要:
活动名称:{name}
潜在客户数量:{count}
邮件序列:{touches}个触点,覆盖{days}天
发送配置:{accounts}个账户 × {daily_limit}/天 = {daily_volume}封/天
预计完成时间:{date}
使用工具:{smartlead/instantly/etc.}Hard Approval Gate
强制确认环节
Do NOT activate the campaign without explicit user confirmation. Present the summary, then ask: "Ready to launch? Type 'yes' to activate."
- Smartlead: → set to active
mcp__smartlead__update_campaign_status - CSV tools: Tell user the file is ready for import, provide the file path
未获得用户明确确认前,不得激活营销活动。 展示摘要后,询问:“是否准备启动?输入'yes'确认激活。”
- Smartlead: 调用→ 设置为激活状态
mcp__smartlead__update_campaign_status - CSV工具: 告知用户文件已准备好可导入,并提供文件路径
Phase 6: Tracking & Logging
阶段6:追踪与日志
Database Write Policy
数据库写入规则
All database writes in this phase require the user's prior approval from the launch gate in Phase 5. The Phase 5 approval ("Ready to launch?") covers both the campaign activation AND the subsequent logging. However, if the campaign was exported as CSV (not launched via Smartlead), confirm with the user before logging — they may not have actually imported/sent yet.
本阶段的所有数据库写入操作,必须获得阶段5中用户的启动确认。 阶段5的确认(“是否准备启动?”)同时涵盖活动激活和后续的日志记录。但如果活动是通过CSV导出(未通过Smartlead启动),则需先与用户确认,再进行日志记录——因为用户可能尚未实际导入/发送邮件。
Log to Supabase
记录到Supabase
After launch (or export), insert records into :
outreach_logPOST /rest/v1/outreach_log
Prefer: return=minimal
[
{
"person_id": "{person_uuid}",
"campaign_name": "{campaign_name}",
"external_campaign_id": "{smartlead_campaign_id or null}",
"channel": "email",
"tool": "{smartlead/instantly/lemlist/apollo/manual}",
"sent_date": "{ISO timestamp}",
"status": "sent",
"client_name": "{client_name}"
},
...
]Or use the shared client:
python
client.log_outreach(entries)For CSV-based tools: Log with = . It changes to when user confirms they launched the campaign in their tool.
status"exported""sent"启动(或导出)后,向表插入记录:
outreach_logPOST /rest/v1/outreach_log
Prefer: return=minimal
[
{
"person_id": "{person_uuid}",
"campaign_name": "{campaign_name}",
"external_campaign_id": "{smartlead_campaign_id or null}",
"channel": "email",
"tool": "{smartlead/instantly/lemlist/apollo/manual}",
"sent_date": "{ISO timestamp}",
"status": "sent",
"client_name": "{client_name}"
},
...
]或使用共享客户端:
python
client.log_outreach(entries)对于基于CSV的工具: 记录时设为。当用户确认已在其工具中启动活动后,再将状态改为。
status"exported""sent"Update People Records
更新潜在客户记录
Update on the people table for all people in this campaign:
last_contactedPATCH /rest/v1/people?id=in.({person_ids})
{ "last_contacted": "{ISO timestamp}" }更新表中本次活动所有潜在客户的字段:
peoplelast_contactedPATCH /rest/v1/people?id=in.({person_ids})
{ "last_contacted": "{ISO timestamp}" }Present Summary
展示操作摘要
{count} people logged to outreach_log
last_contacted updated for {count} people
Campaign ID: {id}
Cooldown active until: {date + 84 days}
Next eligible re-contact: {date}已向outreach_log表记录{count}条数据
已更新{count}个潜在客户的last_contacted字段
活动ID:{id}
冷却期生效至:{date + 84 days}
下次可重新联系时间:{date}Cooldown Enforcement Rules
冷却期执行规则
Reference section for cooldown logic used throughout this skill.
| Rule | Detail |
|---|---|
| Default cooldown | 84 days (12 weeks) from |
| Bounced leads | Exempt from cooldown — email never reached them. Filter: |
| Active campaign leads | Always ineligible — if a lead is in an active campaign (status = "sent", no reply/bounce), they cannot be added to another campaign |
| User override | User can explicitly override cooldown for specific leads — ask for confirmation before allowing |
| Null last_contacted | Leads never contacted are always eligible |
本技能全程遵循的冷却期逻辑参考:
| 规则 | 细节 |
|---|---|
| 默认冷却期 | 从 |
| 邮件退回的潜在客户 | 不受冷却期限制——邮件未送达对方。检查冷却期时使用筛选条件: |
| 活动中潜在客户 | 始终不可选——如果潜在客户处于活跃活动中(状态为"sent",未回复/未退回),则无法添加到其他活动 |
| 用户覆盖 | 用户可明确覆盖特定潜在客户的冷却期——允许前需确认用户意愿 |
| last_contacted为空 | 从未联系过的潜在客户始终符合条件 |
Output Directory
输出目录
Campaign exports are saved to:
skills/cold-email-outreach/output/Create this directory if it doesn't exist. Files are named .
{campaign-name}-{YYYY-MM-DD}.csv活动导出文件保存至:
skills/cold-email-outreach/output/如果目录不存在则自动创建。文件命名格式为。
{campaign-name}-{YYYY-MM-DD}.csv