mcpField
L
linkedin-outreach

linkedin-outreach

github.com/gooseworks-ai营销与增长1.3k112 次安装6 天前更新
代码仓库

关于 linkedin-outreach

linkedin-outreach 是一项技能,可从 Supabase 选取合格线索、编写个性化 LinkedIn 消息序列并记录触达。它为用户选择的触达工具生成 CSV,而不自动操作这些基于浏览器的工具。

主要功能

  1. 01从 Supabase 选择符合条件的线索
  2. 02应用筛选条件和 84 天冷却期
  3. 03生成个性化消息序列
  4. 04遵循 LinkedIn 字符数限制
  5. 05导出适配工具的 CSV 文件
  6. 06将触达记录写入 Supabase

适用场景

  1. 01为合格线索准备 LinkedIn 活动
  2. 02生成 Dripify 或 Expandi 导入文件
  3. 03排除跨渠道近期联系过的线索
  4. 04在 Supabase 记录触达活动

MCP 相关

该技能不通过 API 或 MCP 自动操作 LinkedIn 触达工具,而是生成供手动导入的 CSV 文件。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/gooseworks-ai/goose-skills --skill linkedin-outreach

安装后在 Claude Code 中输入/linkedin-outreach确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

skill.meta.json
templates/
tone-presets.json
templates/sequence-templates/
competitor-engagement.md
database-search.md
event-attendee.md
hiring-signal.md
kol-engagement.md
pain-language.md

详细介绍

LinkedIn 触达

这是 cold-email-outreach 的 LinkedIn 对应流程。从 Supabase 获取符合条件的潜在客户,生成个性化的 LinkedIn 消息序列,导出到用户使用的 LinkedIn 触达工具,并将所有记录写回 Supabase。

**与工具无关:**询问用户使用哪款 LinkedIn 工具。所有工具都基于 CSV 导入——LinkedIn 工具(基于浏览器)不提供 API/MCP 自动化。适配器负责处理各工具的列映射和格式差异。

何时自动加载

在以下情况下加载此技能:

  • 用户提到“LinkedIn 触达”“在 LinkedIn 上联系这些潜在客户”“发送 LinkedIn 消息”“设置 LinkedIn 营销活动”
  • 上游技能通过“创建 LinkedIn 营销活动”或“传递:supabase-eligible-leads”连接,并且用户指定 LinkedIn
  • 用户完成 lead-qualification,希望通过 LinkedIn 联系潜在客户

支持的触达工具

此技能不会默认使用某款特定工具。它会先询问,然后进行适配。

工具集成方式工作原理
DripifyCSV 导入生成符合 Dripify 导入格式的 CSV,用户手动上传
BotdogCSV 导入生成包含 Botdog 兼容列的 CSV
ExpandiCSV 导入生成符合 Expandi 导入格式的 CSV
PhantomBusterCSV 导入为 PhantomBuster LinkedIn 消息序列生成 CSV
手动 / 其他CSV + 说明将潜在客户和消息导出为通用 CSV,并提供设置说明

工具选择逻辑:

  1. 在第 0 阶段询问用户:“你使用哪款 LinkedIn 触达工具?”
  2. 根据用户的选择生成对应工具的导入 CSV
  3. 如果是其他工具或未知工具 → 生成通用 CSV(linkedin_url、first_name、last_name、company、title、connection_request、followup_1、followup_2、followup_3、inmail_subject、inmail_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...
LinkedIn 工具

只需导出 CSV——无需 API 密钥。用户手动将 CSV 导入其工具。

字符数限制

LinkedIn 对字符数有严格限制。所有生成的消息都必须遵守这些限制。

消息类型限制备注
好友申请附言300 个字符硬性限制。每个字符都计入。
普通消息8,000 个字符对方接受好友申请后发送
InMail 主题200 个字符仅限 InMail(高级功能)
InMail 正文1,900 个字符仅限 InMail

**限制执行:**生成任何消息后,都要统计字符数。如果超过限制,请改写——不要截断。截断后的消息看起来会不完整。

第 0 阶段:信息收集

一次性询问所有问题,并按类别整理。跳过上游技能已回答的问题。

营销活动目标
  1. 目标是什么?(预约会议、促成演示申请、获得回复、建立关系、持续培育)
  2. 触达切入点或吸引点是什么?(招聘信号、替代竞争对手产品、基于活动、基于痛点、陌生人数据库、关键意见领袖互动、共同联系人)
  3. 这次营销活动应该叫什么?
触达工具
  1. 你使用哪款 LinkedIn 触达工具?(Dripify / Botdog / Expandi / PhantomBuster / 其他 / 只需要 CSV)
线索筛选
  1. 我们应该锁定哪些线索?选项:
    • 特定 client_name 的所有线索
    • 特定 icp_segment
    • 职位名称模式(例如,“运营副总裁”“销售总监”)
    • 行业或地点筛选条件
    • 高于某个阈值的 qualification_score
    • 特定 source(crustdata、apollo、linkedin 等)
    • 自定义筛选条件(描述你的需求)
  2. 有哪些排除项?(特定公司、近期联系过的线索、某些职位)
  3. 营销活动的最大规模是多少?(默认值:100 — LinkedIn 工具的每日限制低于电子邮件)
语气与风格
  1. 选择哪种语气预设?请展示以下选项:
    • 随和专业 — 友好、自然,略带非正式感。像是在给同行发消息。(默认)
    • 思想领袖 — 以洞见或反常观点开篇,树立发送者的专家形象。
    • 挑衅式 — 挑战固有观念,打破思维定式。风险更高,回报也更高。
    • 企业正式 — 精炼、条理清晰。适用于受监管行业或高管目标人群。
    • 自定义 — 粘贴之前效果不错的参考消息,或描述你想要的风格。
  2. 有哪些效果不错的参考消息?(粘贴示例 — 这些示例会覆盖语气预设)
序列结构
  1. 建立联系后发送几条跟进消息?(默认值:3)
  2. 消息之间间隔多久?(默认值:第 0 天建立联系 / 第 3 天跟进 1 / 第 7 天跟进 2 / 第 14 天跟进 3)
  3. 对于未接受联系请求的线索,是否将 InMail 作为单独步骤?(默认值:是)
个性化
  1. 这些线索有哪些信号数据?(评论文本、互动过的帖子、共同联系人、招聘信号、活动出席情况)
  2. 有哪些可引用的证明材料或案例研究?(客户名称、指标、评价)

阶段 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 筛选条件
“运营副总裁”title=ilike.*VP Operations*
客户“happy-robot”client_name=eq.happy-robot
评分 > 7qualification_score=gte.7
有 LinkedIn URLlinkedin_url=neq.(非空)
行业“物流”industry=ilike.*logistics*
地点“旧金山”location=ilike.*San Francisco*
来源“crustdata”source=eq.crustdata
84 天内未联系or=(last_contacted.is.null,last_contacted.lt.{84_days_ago})

重要: 对于 LinkedIn 外联,人员必须有 linkedin_url。筛除没有该字段的人员 — 无法通过 LinkedIn 联系他们。

冷却期筛选(必须执行)

始终排除过去 84 天(12 周)内通过任何渠道(电子邮件或 LinkedIn)联系过的人员。此项不可省略。

使用共享客户端的 check_cooldown() 方法:

in_cooldown = client.check_cooldown(client_name="happy-robot", cooldown_days=84)
# Returns set of person_id strings still in cooldown

或直接查询:

  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. 在人员查询中添加 id=not.in.({excluded_ids})

注意: 冷却期适用于所有渠道。30 天前收到过电子邮件的人员,仍处于 LinkedIn 联系的冷却期内。这样可以避免通过多个渠道对同一人员进行轰炸式联系。

展示并确认

展示包含 10-15 条线索的示例表格,其中包括:

  • 姓名、职位、公司、行业、评分、LinkedIn URL、上次联系时间、信号类型

告知用户:符合条件的线索总数、因冷却期排除的数量,以及因缺少 LinkedIn URL 排除的数量。

请用户在继续之前确认或调整筛选条件。

阶段 2:序列设计

撰写任何文案之前,先以表格形式呈现序列计划:

步骤时间消息类型方法CTA
1第 0 天添加好友请求(300 个字符)基于信号的个性化备注轻量——只需建立联系
2第 3 天后续跟进 1(对方接受后)价值优先:见解、资源或观察提问或提供帮助
3第 7 天后续跟进 2社会认同或案例研究明确的请求
4第 14 天后续跟进 3结束联系/最后一次触达留下沟通机会
5第 7 天*InMail(如果对方尚未接受)附带背景信息的独立推介会议邀请

*如果潜在客户到第 7 天仍未接受添加好友请求,则向其发送 InMail。

与电子邮件序列的主要区别:

  • 添加好友请求是第一道关卡——必须让对方愿意接受。备注中不要推销。
  • 后续跟进应像对话,而不是群发消息。读起来应该像私信,而不是电子邮件。
  • 除 InMail 外,不要使用主题行。
  • 消息通常越短越好。在 LinkedIn 上,2 句话的消息效果胜过 5 句话的消息。

在第 3 阶段生成文案之前,先让用户批准结构。

阶段 3:消息生成

直接在此技能中生成消息(无需外部子技能——LinkedIn 消息足够简短,可以直接处理)。

根据互动信号选择模板

根据潜在客户的信号数据选择合适的序列模板:

信号类型模板关键个性化变量
使用痛点语言的互动者(有评论文本)templates/sequence-templates/pain-language.md{comment_snippet}、{pain_topic}
互动过竞争对手帖文的用户templates/sequence-templates/competitor-engagement.md{competitor_name}、{post_topic}
互动过 KOL 帖文的用户templates/sequence-templates/kol-engagement.md{kol_name}、{post_topic}
数据库搜索(信号较弱)templates/sequence-templates/database-search.md{title}、{company}、{industry}
招聘信号templates/sequence-templates/hiring-signal.md{role_hiring_for}、{job_posting_detail}
活动参与者templates/sequence-templates/event-attendee.md{event_name}、{event_topic}
语气校准
  1. 从 templates/tone-presets.json 加载选定的语气预设
  2. 如果用户提供了参考消息,则以参考消息为准——分析参考消息的语气、长度、结构和用词
  3. 将语气指南应用于所有生成的消息
校准流程
  1. 先为 3–5 位潜在客户生成示例消息(选择信号丰富程度不同的潜在客户)
  2. 呈现给用户审核——展示每位示例潜在客户的完整序列
  3. 反复调整直至获得批准(最多 3 轮)
  4. 获得批准后,批量生成其余消息
写作指南

添加好友请求(最多 300 个字符):

  • 以信号开头(对方做了什么/说了什么,引起了你的注意)
  • 用一句话说明关联性(你为什么要建立联系)
  • 不要推销、不要使用 CTA、不要说“我很乐意……”——只要有趣到足以让对方接受即可
  • 必须少于 300 个字符。逐个字符计数。

后续跟进 1(价值优先):

  • 简短地感谢对方建立联系(一小句即可,不要写成完整句子)
  • 分享真正有用的内容:见解、文章,或对其公司/行业的观察
  • 以问题结尾,不要推销

后续跟进 2(社会认同):

  • 提及相关客户或案例研究
  • 将其与对方的具体情况联系起来
  • 提出明确、低承诺的请求(15 分钟通话、异步提问)

后续跟进 3(结束联系):

  • 表明你之前曾尝试联系对方
  • 用一句话回顾价值
  • 不施加压力,为后续沟通留出空间
  • 序列中最短的一条消息

InMail(独立推介):

  • 主题:最多 200 个字符——以激发好奇心为主,而非推销
  • 正文:最多 1,900 个字符——必须能独立成文,因为对方尚未接受你的好友请求
  • 说明你联系对方的背景(信号)
  • 即使对方从未听说过你,也必须能让其理解
合并变量

所有潜在客户均可使用的标准变量:

  • {first_name}、{last_name}、{company}、{title}、{industry}、{location}

特定信号变量(根据来源提供):

  • {comment_snippet} — 对方 LinkedIn 评论的文本
  • {pain_topic} — 对方参与互动的痛点
  • {competitor_name} — 对方参与互动的竞争对手帖子所属的竞争对手
  • {kol_name} — 对方参与互动的 KOL 帖子所属的 KOL
  • {post_topic} — 帖子的主题
  • {event_name} — 对方参加的活动
  • {role_hiring_for} — 对方正在招聘的职位
  • {job_posting_detail} — 招聘信息中的一项详情

第 4 阶段:导出营销活动

步骤 1:生成通用 CSV

所有导出的核心列:

linkedin_url, first_name, last_name, company, title, connection_request, followup_1, followup_2, followup_3, inmail_subject, inmail_body
步骤 2:按所选工具设置格式

Dripify:

  • 列映射:Profile URL → linkedin_url,Note → connection_request,Message 1 → followup_1,等等。
  • Dripify 要求每位潜在客户占一行,所有消息分别放在不同的列中
  • 导出格式:CSV,表头与 Dripify 的导入模板一致

Botdog:

  • 列映射:linkedin_profile_url → linkedin_url,connection_note → connection_request,message_1 → followup_1,等等。
  • 导出格式:CSV

Expandi:

  • 列映射:LinkedIn URL → linkedin_url,Connection message → connection_request,Follow-up #1 → followup_1,等等。
  • 支持 InMail 列:InMail subject、InMail message
  • 导出格式:CSV

PhantomBuster:

  • 列映射:profileUrl → linkedin_url,message → connection_request
  • PhantomBuster 通常一次处理一个操作——可能需要分别为连接请求和后续跟进创建 CSV 文件
  • 导出格式:CSV

手动 / 其他:

  • 使用通用 CSV 格式
  • 提供列说明和与工具无关的导入说明
  • 询问用户的工具需要哪种格式;如有需要,进行调整
步骤 3:保存文件
skills/linkedin-outreach/output/{campaign-name}-{YYYY-MM-DD}.csv

如果 output/ 目录不存在,请创建该目录。

步骤 4:可选的 Google 表格

如果用户需要审核表格,请使用 google-sheets-write 功能创建一个表格,包含:

  • 标签页 1:潜在客户列表及所有消息(每位潜在客户占一行)
  • 标签页 2:序列模板(使用的主模板)
  • 标签页 3:营销活动配置摘要

第 5 阶段:审核与批准

展示营销活动摘要:

Campaign: {name}
Tool: {dripify/botdog/expandi/etc.}
Leads: {count}
Sequence: Connection + {followup_count} follow-ups + InMail
Timing: Day 0 → Day {last_day}
Tone: {preset_name}
Signal types: {breakdown by signal type}
Leads with rich signal: {count} ({percentage}%)
Leads with lean signal: {count} ({percentage}%)
Export file: {file_path}
强制审批关卡

**未经用户明确确认,切勿将营销活动标记为已就绪。**展示摘要,然后询问:“准备好定稿了吗?输入 ‘yes’ 将其标记为可导入。”

批准后:

  • 告知用户文件已准备好,可导入其 LinkedIn 工具
  • 提供文件路径
  • 提供针对相应工具的导入说明(参见第 4 阶段)
  • 提醒用户导入后检查前 5-10 条消息是否正确

第 6 阶段:记录日志

数据库写入策略

**本阶段的所有数据库写入都必须事先获得用户在第 5 阶段最终确认关卡中的批准。**由于 LinkedIn 营销活动始终以导出方式交付(从不自动启动),写入 outreach_log 前请先向用户确认——他们可能尚未将营销活动导入 LinkedIn 工具。只有在用户确认导出内容已定稿后,才能记录日志。

记录到 Supabase

导出并获得用户确认后,将记录插入 outreach_log:

POST /rest/v1/outreach_log
Prefer: return=minimal

[
  {
    "person_id": "{person_uuid}",
    "campaign_name": "{campaign_name}",
    "channel": "linkedin",
    "tool": "{dripify/botdog/expandi/phantombuster/manual}",
    "sent_date": "{ISO timestamp}",
    "status": "exported",
    "client_name": "{client_name}"
  },
  ...
]

或者使用共享客户端:

client.log_outreach(entries)

**状态为 "exported",而非 "sent"。**LinkedIn 工具基于浏览器运行——我们无法确认是否送达。用户确认已在工具中启动营销活动后,状态才会变为 "sent"。

更新人员记录

更新人员表中本次营销活动涉及的所有人员的 last_contacted:

PATCH /rest/v1/people?id=in.({person_ids})
{ "last_contacted": "{ISO timestamp}" }
展示摘要
Campaign: {name}
{count} people logged to outreach_log (channel: linkedin)
last_contacted updated for {count} people
Cooldown active until: {date + 84 days}
Next eligible re-contact: {date}
File ready: {file_path}

冷却期执行规则

本节介绍整个技能中使用的冷却期逻辑。与 cold-email-outreach 共享。

规则详情
默认冷却期从 sent_date 起 84 天(12 周)
跨渠道冷却期适用于电子邮件和 LinkedIn。最近收到过电子邮件的潜在客户,在 LinkedIn 上也处于冷却期。
退信的潜在客户不受冷却期限制(仅限电子邮件——LinkedIn 不会退信)。检查冷却期时使用筛选条件:status=neq.bounced
正在进行的营销活动中的潜在客户始终不符合条件——如果潜在客户正在任何渠道的营销活动中,就不能将其添加到其他营销活动中
用户覆盖用户可以明确要求对特定潜在客户覆盖冷却期——允许前请先征求确认
last_contacted 为空从未联系过的潜在客户始终符合条件

输出目录

营销活动导出文件保存在:

skills/linkedin-outreach/output/

如果此目录不存在,请创建该目录。文件名格式为 {campaign-name}-{YYYY-MM-DD}.csv。

评论

支持 Markdown