关于 cold-email-outreach
将 Supabase 中符合条件的潜在客户转化为冷邮件活动的技能,涵盖筛选受众、撰写邮件序列、设置活动和记录数据。它会根据所选工具调整流程:Smartlead 使用 MCP 自动化,其他列出的工具通过 CSV 导出并提供导入指引。
主要功能
- 01筛选 Supabase 潜在客户
- 02执行 84 天联系冷却期
- 03规划并审核邮件序列
- 04自动设置 Smartlead 活动
- 05导出适配工具的 CSV 文件
- 06将触达记录写入 Supabase
适用场景
- 01启动经过审核的 Smartlead 活动
- 02为 Instantly、Lemlist 或 Apollo 准备 CSV 导入
- 03跟踪活动触达记录与联系冷却期
MCP 相关
对于 Smartlead,该技能通过 MCP 工具列出邮件账户、创建活动、配置序列与设置、导入潜在客户,并在获得批准后启动活动。其他触达工具采用 CSV 导出。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nikiandr/ goose-skills --skill cold-email-outreach安装后在 Claude Code 中输入/cold-email-outreach确认已加载。
附带文件skill.meta.json
详细介绍
冷邮件外联
外联流程的最后一公里。从 Supabase 获取符合条件的潜在客户,使用 email-drafting 技能构建邮件序列,将营销活动加载到用户选择的外联工具中,并将所有记录写回 Supabase。
**与工具无关:**询问用户使用哪种外联平台。如果已配置 MCP 工具,则默认使用 Smartlead。对于其他工具或手动工作流,则回退到 CSV 导出。
自动加载时机
在以下情况下加载此技能:
- 用户说“启动营销活动”“发送外联邮件”“给这些潜在客户发邮件”或“设置冷邮件”
- 上游技能使用“创建邮件营销活动”进行连接,或传递
supabase-eligible-leads - 用户完成
lead-qualification,并希望采取后续行动
支持的外联工具
此技能不会假设用户使用特定工具,而是先询问,再进行适配。
| 工具 | 集成方式 | 工作方式 |
|---|---|---|
| Smartlead(默认) | MCP 工具(mcp__smartlead__*) | 全自动化:创建营销活动、添加序列、导入潜在客户、配置日程并启动 |
| 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),并询问用户该工具的导入要求
前置条件
Supabase
人员必须按照 tools/supabase/schema.sql 中的架构存储在 Supabase 中。people 和 outreach_log 表必须存在。如果是全新设置,请运行 python3 tools/supabase/setup_database.py。
.env 中的环境变量:
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJ...
外联工具
- **Smartlead:**可通过
mcp__smartlead__*使用 MCP 工具。无需额外设置。 - **其他所有工具:**只需导出 CSV,无需 API 密钥。
阶段 0:信息收集
一次性询问所有问题,并按类别整理。跳过上游技能已经回答的问题。
营销活动目标
- 目标是什么?(预约会议、推动演示申请、获得回复、培育潜在客户)
- 外联切入点或吸引点是什么?(招聘信号、替代竞争对手、基于活动、基于痛点、冷门数据库)
- 这次营销活动应该叫什么名字?
外联工具
- 你使用哪种外联工具?(Smartlead / Instantly / Lemlist / Apollo / 其他 / 直接给我 CSV)
潜在客户筛选
- 应该联系哪些潜在客户?选项:
- 指定
client_name的所有潜在客户 - 特定的
icp_segment - 职位名称模式(例如,“运营副总裁”“销售总监”)
- 行业或地区筛选条件
- 高于某一阈值的
qualification_score - 特定的
source(crustdata、apollo、linkedin 等) - 自定义筛选条件(描述你的需求)
- 指定
- 有哪些排除条件?(特定公司、近期联系过的潜在客户、某些职位)
- 营销活动规模上限是多少?(默认:200)
序列设计
- 需要多少次触达?(默认:3)
- 每次触达之间间隔多久?(默认:第 1 天 / 第 5 天 / 第 12 天)
- 个性化级别?(第 1 级:仅合并字段 / 第 2 级:按细分群体个性化 / 第 3 级:为每位潜在客户单独撰写)
发送配置(导出 CSV 时跳过)
- 应使用哪些电子邮件账户发送?(列出账户,或说“使用所有可用账户”)
- 发送日程?(默认:按收件人所在时区,周一至周五上午 8 点至下午 5 点)
- 每个账户的每日发送上限是多少?(默认:每天 30 封)
- 是否跟踪打开和点击?(默认:跟踪打开,不跟踪点击)
阶段 1:从 Supabase 中筛选潜在客户
连接
使用共享的 Supabase 客户端:
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"])
构建筛选条件
将用户条件映射为 people 表上的 PostgREST 查询参数:
| 用户表述 | PostgREST 筛选条件 |
|---|---|
| “VP Operations” | title=ilike.*VP Operations* |
| 客户“happy-robot” | client_name=eq.happy-robot |
| 评分 > 7 | qualification_score=gte.7 |
| 有已验证的邮箱 | email_verified=eq.true |
| 行业“logistics” | industry=ilike.*logistics* |
| 地点“San Francisco” | location=ilike.*San Francisco* |
| 来源“crustdata” | source=eq.crustdata |
| 84 天内未联系过 | or=(last_contacted.is.null,last_contacted.lt.{84_days_ago}) |
冷却期筛选(必需)
始终排除 84 天(12 周)内联系过的人。这不是可选项。
使用共享客户端的 check_cooldown() 方法:
in_cooldown = client.check_cooldown(client_name="happy-robot", cooldown_days=84)
# Returns set of person_id strings still in cooldown
或者直接查询:
- 查询
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} - 将这些
person_id收集到排除集合中 - 在 people 查询中添加
id=not.in.({excluded_ids})
展示并确认
展示一个示例表格(10-15 条潜在客户),包含:
- 姓名、职位、公司、行业、评分、邮箱、上次联系时间
告知用户:符合条件的潜在客户总数、因冷却期排除的数量、拥有已验证邮箱的数量。
请用户确认或调整筛选条件后再继续。
第 2 阶段:序列设计
在撰写任何文案之前,先以表格形式展示序列计划:
| 触达 | 天数 | 邮件类型 | 框架 | CTA |
|---|---|---|---|---|
| 1 | 1 | 冷启动介绍 | Signal-Proof-Ask | 15 分钟通话 |
| 2 | 5 | 新角度 / 资源 | PAS | 提供资源 |
| 3 | 12 | 社会认同 | BAB | 愿意聊聊吗? |
在第 3 阶段生成文案之前,先征得用户对结构的批准。
第 3 阶段:邮件生成
加载 email-drafting 技能,并向其传递:
- 活动背景(目标、角度、产品、证明要点)
- 第 2 阶段的序列结构
- 所选列表中的 3-5 条示例潜在客户
- 个性化级别
- 语气偏好
按个性化级别
级别 1(通用): 每次触达生成一个带合并字段({first_name}、{company}、{title})的模板。所有潜在客户使用同一模板。
级别 2(细分): 每个细分群体的每次触达生成一个模板。根据角色、行业或信号类型定义细分群体。在不同细分群体之间替换痛点和证明要点。
级别 3(深度): 为每位潜在客户的每次触达生成唯一邮件。最多处理 50 位潜在客户;超过此数量时建议使用级别 2。
审核流程
- 先为 3-5 位潜在客户生成邮件样例
- 提交给用户审核
- 迭代直至获批(最多 3 轮)
- 获批后生成其余邮件
第 4 阶段:活动设置
使用 Smartlead(MCP 自动化)
通过 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 } }
]
合并变量映射: 将 {first_name} → {{first_name}}、{company} → {{company}}(Smartlead 使用双大括号语法)。
第 4 步:导入潜在客户(每批 100 条)
mcp__smartlead__add_leads_to_campaign
campaign_id: {campaign_id}
lead_list: [{ email: "...", first_name: "...", last_name: "...", company_name: "...", ... }]
如果潜在客户超过 100 条,则按每组 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 }
如果使用基于 CSV 的工具(Instantly、Lemlist、Apollo 等)
步骤 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_subject、touch_3_body
步骤 2:保存文件
skills/cold-email-outreach/output/{campaign-name}-{YYYY-MM-DD}.csv
步骤 3:提供特定工具的导入说明
Instantly:
- 上传 CSV → Sequences → Create new sequence
- 映射列:Email → email、First Name → first_name 等
- 将序列模板粘贴到各个步骤中
- 设置步骤间的延迟时间
Lemlist:
- People → Import → Upload CSV
- 将自定义变量映射到各列
- 创建营销活动 → 添加邮件步骤 → 插入变量
Apollo:
- Sequences → Create Sequence → 添加邮件步骤
- Contacts → Import → Upload CSV
- 将导入的联系人添加到序列中
其他工具/手动操作:
- 提供 CSV 路径并说明列结构
- 询问用户的工具要求什么格式,如有需要则进行调整
阶段 5:审核并启动
展示营销活动摘要:
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.}
必须获得明确批准
**未经用户明确确认,不要激活营销活动。**展示摘要,然后询问:“准备好启动了吗?输入 ‘yes’ 以激活。”
- Smartlead:
mcp__smartlead__update_campaign_status→ 设为 active - **CSV 工具:**告知用户文件已准备好导入,并提供文件路径
阶段 6:跟踪与记录
数据库写入策略
**此阶段的所有数据库写入都必须事先获得用户在阶段 5 的启动批准。**阶段 5 的批准(“准备好启动了吗?”)同时涵盖营销活动激活和后续记录。但是,如果营销活动是导出为 CSV(而非通过 Smartlead 启动),则记录前要先向用户确认——他们可能还没有实际导入或发送。
记录到 Supabase
启动(或导出)后,将记录插入 outreach_log:
POST /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}"
},
...
]
或者使用共享客户端:
client.log_outreach(entries)
**对于基于 CSV 的工具:**记录时将 status 设为 "exported"。用户确认已在工具中启动营销活动后,将其改为 "sent"。
更新人员记录
为此营销活动中的所有人员更新 people 表中的 last_contacted:
PATCH /rest/v1/people?id=in.({person_ids})
{ "last_contacted": "{ISO timestamp}" }
展示摘要
{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}
冷却期执行规则
本节说明此技能中使用的冷却期逻辑。
| 规则 | 详情 |
|---|---|
| 默认冷却期 | 从 sent_date 起算 84 天(12 周) |
| 邮件退回的潜在客户 | 不受冷却期限制——邮件从未送达。检查冷却期时使用筛选条件:status=neq.bounced |
| 活跃营销活动中的潜在客户 | 始终不符合条件——如果某位潜在客户处于活跃营销活动中(状态 = "sent",且未回复/退回),则不能将其添加到其他营销活动 |
| 用户覆盖规则 | 用户可以明确要求对特定潜在客户覆盖冷却期——允许前先征求确认 |
last_contacted 为空 | 从未联系过的潜在客户始终符合条件 |
输出目录
营销活动导出文件保存至:
skills/cold-email-outreach/output/
如果此目录不存在,请创建该目录。文件命名格式为 {campaign-name}-{YYYY-MM-DD}.csv。