营销运营即代码:用 GitHub 自动化活动全流程
我负责 GitHub 在日本和韩国的市场营销工作。在这里,活动是业务的重心:针对企业开发者的定期网络研讨会、在东京举办的社区聚会,以及在首尔举行的定向高管研讨会。这个市场的开发者当下真正需要的是什么?哪些话题值得占用他们一小时?谁又该在场?我乐意整天思考这些问题。
但决策之后的执行是另一回事。一旦活动获批,便会启动一套固定流程:
- 在活动平台上复制落地页。
- 生成一组带 UTM 标签的链接:每个渠道一个,且格式要求严格。
- 起草邀请邮件,并向发送团队提交请求。
- 将活动添加到两个项目看板中。
- 活动前的每个早晨:下载报名者名单,清理数据,并向干系人发布状态更新。
- 活动结束后:导出与会者名单,调整格式以适配 CRM 上传,标记相关记录,并撰写报告。
这些任务单独看都不难,但每一步都存在贴错链接、漏做某一天操作,或者拼错一个营销活动名称的风险——而后者可能影响下游的 15 份报告。
关键背景是:我曾是一名工程师。我的第一份职业是为企业客户维护运行在 Linux 服务器上的数据库。虽然我的编码技能可能已有些生疏,但我仍能识别出哪些流程适合自动化。这正是我运用 GitHub Copilot 的地方,而你也能在自己的工作中复用这种方法。
我没有手写代码。我将自己的操作手册记录下来,交给 GitHub Copilot,通过对话式交互逐步构建自动化系统。如今,过去需要我花好几天手工搭建的活动,现在只需从一个 GitHub Issue 出发即可自动配置;它每天早晨自动筛查报名者,活动结束后也能自动清理现场。
下文将详细介绍其工作原理,以及为什么我认为,任何从事跨工具重复性工作的人——只要这些工具提供某种可编程入口(API 或 CLI 即可)——都能照此办理。
一个活动就是一个 Issue
这个基础理念并非我首创。GitHub 的市场团队原本就有为每个项目开一个 GitHub Issue 的习惯。这个 Issue 成为计划、讨论和状态信息的汇聚地。Issue 早已是我们工作的基本单元。我所做的,是让 Issue 本身去执行工作。
整个系统由三个 GitHub 原生功能承载:
- Issue forms 就是申请表。issue form 不是空白文本框,而是一组结构化字段:活动名称、日期、地区、营销活动名称、目标受众。每种活动类型(比如线上研讨会、线下活动)各有一张表单,最终都汇入同一套流程。
- Labels 就是开关。像
event-setup这样的 label 不是标签,而是触发器。每个自动化 workflow 的开头都有一个条件,意思就是“只有带上这个 label 才运行”。 - Actions 就是机器。GitHub Actions workflow 在 label 打上后触发,从 issue 正文里解析出表单字段,然后开始干活。
仓库能给开发者的一切,都在不知不觉中给了我的营销工作流:历史记录、可见性、评审,以及每个决策对应的 URL。
这一切之所以可行,靠的不是和活动本身相关的什么特性,而是:我们的活动管理平台提供了 API。我们的 CRM 甚至不需要 API,它的官方 CLI 就覆盖了我们所有用到的功能,我也从没为它配置过 API key——CLI 通过浏览器登录并自行处理认证。不管是 API 还是 CLI,要求都一样:得有一条可以用脚本调用的入口。如果你的重复性工作跑在某个提供这类接口的工具上——活动平台、CRM、表单构建器、数据分析服务都行——那本文的模式就适用于你。
读到这里的开发者可能已经在构思一个显而易见的质疑:这难道不是在重复造轮子吗?市面上确实存在营销自动化平台,一款优秀的平台也许能开箱即用地覆盖上述部分需求。但亚太区并非单一市场,而是由许多差异显著的细分市场组成的集合。即便在我自己的团队内部,工作流程也会随着不同次级区域和目标客群而变化。同一场网络研讨会,可能这个月以日语面向东京举办,下个月又切换为韩语面向首尔,对应的客群、CRM 字段以及优质线索的定义都会随之改变。要让现成的工具兼容所有这些变化,意味着需要投入定制预算、咨询工时,并受制于他人的产品路线图。而基于手头现有工具自行构建,则意味着工作流程的变更等同于一次代码拉取请求(pull request):我描述需求,审查者确认,随后代码合并至主分支——整个过程与开发者修改软件完全一致。
活动规划是一场对话
流水线在 Issue 创建之前就已经启动。我打开 GitHub Copilot,大致这样说道:“我想在十一月举办一场关于 AI 辅助开发的网络研讨会。”
接下来的操作由仓库根目录下名为 AGENTS.md 的文件驱动。这是用纯 Markdown 编写的团队运行手册(runbook),定义了活动命名规范、财季与日期的映射关系、各时区对应区域,以及优质邀请邮件的标准。GitHub Copilot 读取该文件后,会检索相似的历史活动,提出符合命名规范的活动名称,起草两个版本的邀请邮件,并运行手册中规定的提问。
将对话置于流水线前端本身就是一个设计决策,同时解决了两个问题。若一切皆自动化,灵活性会丧失;当你希望某场活动略有不同之时,僵化的流水线无法体现这种差异。但若让填所有细节交给人类,错误随之而来。对话恰好介于两者之间。GitHub Copilot 遵循模板,确保填入 Issue 的数据既正确且格式规范。由于这是对话形式,我可以为特定活动调整细节,而不会破坏下游机制。
起初,这种对话发生在GitHub Copilot CLI的终端中。对我来说这没问题,但对许多我希望引入这一工作流的人来说,“打开终端”是一道门槛。借助GitHub Copilot 应用,同样的对话现在可以在普通的桌面窗口中完成。入门门槛从“熟悉 Shell”降低到了“会打字”。
我想明确一下分工,因为这是核心所在:GitHub Copilot 起草,我决策。每一个活动名称、每一行邮件标题、每一个日期,都必须经过我的批准才能推进。对话结束时,GitHub Copilot 会提交带有正确标签的 GitHub Issue,随后就由机器接管了。
一个标签,一个活动,完全自动化
一旦 event-setup 标签出现在 Issue 上,GitHub Actions 工作流就会接管,并在几分钟内完成过去需要我大半天的工作:
- 在活动平台上复制过去的活动以创建新的落地页
- 生成全套带 UTM 标记的 URL:每个渠道一个,格式始终统一
- 生成 Word 格式的邀请邮件并提交到仓库
- 向负责发送邮件和区域营销的团队创建请求 Issue
- 将活动添加到项目看板并填充字段
- 在 Issue 上发布汇总评论,以便下一个查看的人能在一处看到所有信息
报名筛选是按时间计划运行,而非由标签触发。每天早上,由 cron 触发的的工作流会获取所有开放活动的最新报名者,并分享整理好的名单。对于仅限邀请的活动,它还会根据我们的标准筛选候补名单(该报名者是否是企业的开发者、学生,或是非常想参加我们高管简报会的竞争对手?)之后才批准任何人。
我最引以为傲的设计决策是一个名为 DRY_RUN 的开关,它以设置的形式存储(用 GitHub 的说法是一个仓库变量),每个 workflow 运行前都会检查它。打开它,所有 workflow 都会照常执行流程,但不碰任何外部系统:不创建落地页,不在其他仓库提交 Issue,不共享列表。当营销团队在自动化自己的工作时,你需要一种排练的方式。DRY_RUN 就是排练开关,也是我一直敢于放手实验的原因。
活动结束后:一个斜杠命令
活动后的收尾工作曾经最让人头疼:导出参会者名单、为上传 CRM 重新整理表格格式、将公司名与客户账户记录匹配,再写总结报告。现在只需要两条命令。
/lead-upload 会获取参会者名单,整理成市场运营团队上传 CRM 所需的格式,提交请求 Issue,并关闭相关的追踪 Issue。/event-report 则拉取到场数据和问卷结果,以评论的形式把报告发布到该活动的 Issue 上——回到那个汇集活动全部信息的唯一 URL。
这些是 GitHub Copilot agent skills,而这里是我最想让你知道的一点:一个 skill 就是一个 Markdown 文件。每个 skill 都是一个 SKILL.md:一份用文字写成的操作说明,告诉 GitHub Copilot 要做什么、按什么顺序做、需要注意什么。我的 skill 读起来就像我过去记在脑子里的那些 runbook——因为它们本质上就是 runbook。
能写出 runbook,就能写出 skill。
Skill 也是保持系统灵活的关键。亚太(APAC)地区没有两个市场的后续流程完全一样:受众不同、细分不同、本地惯例不同,硬编码的 workflow 会把所有市场强行套进同一个模子。而用 Markdown 写的流程就很灵活:每个市场都可以按自己的实际情况调整 runbook,而不必改动底层的机制。这正是活动后流程放在 GitHub Copilot skills 里、而不是固定 pipeline 里的原因。
在某个方面,我们把 skill 当作代码来对待:新增 skill 通过 pull request 提交,合并前需要审查,并通过 CODEOWNERS 文件把审查指派给相应的维护者。这就是带审批流程的营销自动化。而治理机制,同样是随平台免费附赠的。
内置的防护机制让我敢于大胆尝试
我自动化了一个涉及客户数据和 API 密钥的工作流。该代码存放在整个团队可见的仓库中,而我自己几乎没怎么写代码。半年前,我会认为这种组合是鲁莽的。改变我想法的是,我意识到在我开始之前,其实已经有很多防护机制到位了。
有些防护是我自己建立的:比如DRY_RUN开关、每个拉取请求都会运行的测试套件,以及针对每次变更的代码审查。这些都是标准的开发者习惯。事实证明,它们保护营销工作的效果与保护软件工作一样好。
但最关键的保护措施来自平台本身:
- 具备推送保护的密钥扫描。对我这个职位的人来说,最糟糕的场景是意外提交 API 令牌。GitHub 的推送保护功能会在密钥写入仓库之前拦截推送;对于 GitHub 自家的令牌,即使某个令牌侥幸混入,也会自动被吊销。
- GitHub Copilot 的数据策略。注册人列表属于商业数据,固定的脚本以固定的方式处理它们。但实际工作从不完全是固定的;有些日子,我需要做一个临时性的数据切片,这是现有脚本未曾预料的。由于 GitHub Copilot 的商业版计划不会保留提示词,也不会使用它们来训练模型,我可以直接索取这种临时分析,而不必像全行业的人默默做的那样:把商业数据粘贴到下一个标签页打开的某个消费级聊天机器人里。模型本身也是如此:我可以使用哪些模型由组织策略设定,而非由我的个人判断决定,因此即使是临时实验也运行在公司既定好的边界之内。安全路径和便捷路径,这一次是重合的。
这些能力还带来了一个几乎是副作用的可能性:由于每个步骤现在都是一个命名的、固定的工作单元,我可以按需匹配模型,从组织批准的模型阵容中选择。快速且低成本的模型负责日常的列表清理;更强的模型负责撰写营销文案。
还有一个真实的失败教训,免得你也踩坑:一次清晨筛选流程静默失败了整整五天,直到有人发现名单过时了才发觉。没人监控的自动化,不过是个延时引爆的定时炸弹。给每个定时工作流都加上报警机制,让它一出问题就大声喊,别让它悄悄失效。
从一件事做起
作为一个刚从手工操作里“戒断”出来的人,这是我给同行们的建议。
挑出你每周最重复的一件事。然后看看它涉及的工具有没有 API 或 CLI。你可能会惊讶地发现,很多工具都支持。
然后做最小可行版本:一个 issue 表单收集输入,一个标签表示“可以执行”,一个 Action 完成其中一步。或者跳过这一步,直接把你的操作手册写成 SKILL.md,交给 GitHub Copilot 去跑。先用 dry-run 模式跑,直到你确信没问题,再逐步扩展。
代码不是我写的。我只是把已经知道的内容(活儿是怎么干的)写下来,平台把剩下的活干了。无论你手头的“清晨报名单”长什么样,它离自动运行,可能只差一份写好的操作手册。
起步资源:
- issue 表单语法
- GitHub Actions 文档
- GitHub Copilot 文档
- 还有那篇让我确信这招可行的博客:我自动化了自己的工作,它让我成了更好的管理者