Workflows as Code 是一个用于 HubSpot 工作流管理的技能,核心目标是把工作流当作代码来管理:导出、版本控制、差异对比和恢复。
用途
HubSpot 没有工作流回收站,一旦工作流被删除或损坏,除非保留其定义,否则无法恢复。该技能为工作流提供备份安全网,并支持对导出之间的变更进行可审查的差异对比。工作流属于生产自动化,但多数门户将其视为一次性 UI 配置,没有备份、变更历史或审查。工作流编辑器中的一次误操作可能悄无声息地破坏线索路由或抑制逻辑数周。v4 Automation API 支持完整读取和创建工作流定义,从而实现类似代码的生命周期:导出 → 版本化 → 差异对比 → 恢复。
主要能力
导出:scripts/export.py 通过 GET /automation/v4/flows 列出所有流程,通过批量读取端点(POST /automation/v4/flows/batch/read,失败时回退到逐个 GET)获取每个完整定义,为每个工作流写入一个 JSON 文件,并生成清单。输出布局为 data/workflow-exports/<YYYY-MM-DD>/,包含 manifest.csv(flowId、name、type、isEnabled、revisionId、file)和 flow-<flowId>.json。
差异对比:可使用 diff -u 对比两个导出目录中的同一工作流 JSON 文件。时间戳和 revision ID 会不同,有意义的变更会体现在 actions 和 enrollmentCriteria 中。
恢复:scripts/restore.py 从导出文件通过 POST /automation/v4/flows 重建工作流。脚本会剥离服务器分配的字段(id、revisionId、时间戳),将流程重命名为带“(restored)”后缀以避免名称冲突,并以禁用状态创建。需在 UI 中审查,对照原始版本验证注册条件和操作,然后重命名并启用。
使用方式
前置条件:具有 automation 作用域的 HubSpot 私有应用访问令牌(.env 中的 HUBSPOT_ACCESS_TOKEN),如果任何流程涉及敏感属性还需敏感数据作用域;Python 3.10+ 与 uv;用于保存导出的位置,推荐使用 git 仓库(默认情况下 data/workflow-exports/ 被 gitignore,因为导出可能引用内部名称;如需历史记录可移至私有仓库)。
导出命令:uv run skills/workflows-as-code/scripts/export.py
恢复命令:uv run skills/workflows-as-code/scripts/restore.py <export-file.json>
执行模式:
阶段 1 计划:确定导出频率——在任何工作流清理之前(强制)、构建新工作流之后,以及按计划(每月与季度数据库清理搭配较好)。确定导出的长期存放位置(推荐私有 git 仓库)。
阶段 2 准备:无需准备,导出是只读的。记录 Automation > Workflows 中的当前工作流数量以便对比。
阶段 3 执行导出:运行导出脚本,检查输出布局。
阶段 3 替代执行恢复:运行恢复脚本,脚本会剥离服务器分配字段、重命名并禁用创建。
阶段 4 之后:导出后验证清单行数与门户工作流数量匹配,并抽查一个 JSON 文件。恢复后在 Automation > Workflows 中打开恢复的工作流,与导出对比,然后启用。
回滚:导出是只读的,无需回滚。不想要的恢复工作流以禁用状态创建,直接删除即可。
适用场景
适用于需要对 HubSpot 工作流进行备份、变更审查、版本控制和灾难恢复的管理场景。特别适合在工作流清理前、构建新工作流后、以及定期(如每月)执行导出。
限制与技术注意事项
就地更新需要当前 revisionId。PUT /automation/v4/{flowId} 必须包含流程的最新 revisionId 和 type,过期的 revision 会被拒绝。恢复脚本通过创建新流程而非更新来规避此问题。
部分操作往返不完美。字段结构未文档化的操作(例如 copy-from-associated-object、通知收件人)可以正常导出,但在不同门户中重新创建时可能被拒绝。恢复脚本会报告每个操作的错误;被拒绝的操作需在 UI 中添加。
v3 工作流 ID 与 v4 流程 ID 不同。如果已有基于 /automation/v3/workflows 的旧工具,v4 API 提供 workflowId → flowId 映射端点用于迁移。新工具应完全使用 v4,v3 是旧版。
敏感数据作用域。读取或设置敏感属性的流程需要在私有应用上具有相应的敏感数据作用域,否则读取会失败。
导出可能包含内部数据。工作流名称、属性名称、列表 ID 和通知文本都在 JSON 中。应将导出视为配置机密,保存在私有仓库中。