mcpField
G
ga-taxonomy

ga-taxonomy

github.com/ogaeng数据与数据库143 次安装9 周前更新
代码仓库

关于 ga-taxonomy

ga-taxonomy 帮助营销人员从电子表格解析事件分类表、将其与 GA4 实际收集的数据对照,或根据实时数据起草分类表。它还支持列映射、警告处理和恢复旧版本。

主要功能

  1. 01解析电子表格事件分类表
  2. 02对照 GA4 实际收集事件
  3. 03根据实时数据起草分类表
  4. 04映射含义不明确的列
  5. 05恢复较早的分类表版本

适用场景

  1. 01导入现有事件规划
  2. 02查找规划与 GA4 收集数据的差异
  3. 03依据当前事件创建分类表

安装

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

$npx skills add https://github.com/ogaeng/ga4-skill --skill ga-taxonomy

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

包含的文件

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

requirements.txt
assets/
taxonomy_template.csv
taxonomy_template.xlsx
references/
taxonomy-guide.md
scripts/
custom_dims.py
ga4_common.py
ga4_events.py
param_naming.py
parse_taxonomy.py
sheets_reader.py
taxonomy_diff.py
taxonomy_draft.py
taxonomy_restore.py
taxonomy_schema.py

详细介绍

GA4 事件分类规范技能(ga-taxonomy)

帮助营销人员(1)从电子表格中解析事件分类规范,(2)核对实际由 GA4 收集的数据,以及(3)在从空白状态开始时,根据实时数据起草分类规范。确定性工作由 scripts/ 中的 Python 脚本完成。由你判断适用哪个步骤。

语言

使用用户的语言回复。如果用户用韩语提问,就用韩语回答;如果用英语提问,就用英语回答。这适用于每个步骤——设置说明、进度更新、结果和错误说明。

切勿翻译:GA4 API 标识符(eventCount、sessionSource、runReport)、文件和目录名(.ga4/token.json)、shell 命令和 JSON 字段名。

不得原样向用户展示脚本输出。 脚本始终会输出英文的 error/hint 字符串。当脚本返回 "ok": false 时,你必须先将 hint 改写成用户使用的语言,再展示给用户。绝不能直接贴出英文,也不能展示原始 JSON。在改写的文本中,标识符、路径和命令须保持原样——只翻译周围的说明文字。

示例——脚本返回: {"ok": false, "hint": "token.json is missing. Log in first with the ga-auth skill."} 对使用韩语的用户,应这样说: 登录信息(.ga4/token.json)不存在。我先使用 ga-auth 技能登录。 而不是:“token.json is missing. Log in first with the ga-auth skill.”

工作原则(重要)

受众是非技术背景的营销人员。请遵循以下规则:

  • 将工作拆分为小步骤。 每次引导一到两个步骤,确认结果后再继续。

  • 每个步骤都用一句话说明“做什么/为什么”。

  • 尽可能替用户完成繁重工作。 尽量自行处理文件放置和命令执行。

  • 优先使用操作模板的表头(9 列),但列名/顺序可以略有不同——别名词典会自动识别。 如果自动识别存在歧义,解析器会输出 needs_mapping;请使用 --map "original-header=canonical-field,..." 映射列,然后重新运行以修正(这是映射修正,不是拒绝处理)。

  • --map 可以使用电子表格列字母指定列——--map "B=up_ga4_name"——这是访问表头单元格为空的列的唯一方法。表头文本优先:如果工作表中确实有名为 B 的表头,那么这个键就表示该表头;如果某工作表中该列的表头已命名为某个字段,则不接受用列字母指定。响应中的 map_resolution 会说明每个键在每张工作表上是如何解析的(--map 键适用于整个工作簿,而同一个字母在不同工作表中代表不同的列)。不接受数字索引,因为 0 起始和 1 起始都有其合理性,读取者无法判断预期的是哪一种。

  • 映射只需提供一次。 映射会与分类规范一同保存,因此之后重新同步同一张工作表时,无需再提供 --map——只需使用来源重新运行。若发生这种情况,响应会注明 reused_column_map。这仅适用于同一来源:映射描述的是一张工作表的表头,跨工作表复用会导致列映射错误,而且不会报错。在此功能推出前保存的分类规范没有存储映射,因此需要再传一次 --map,之后就会记住该映射。--sheet 也会以同样方式记住。 已保存的映射会持续生效,直到通过显式的 --map 替换。 不带此标志重新运行不会清除映射,--map "" 也不会——空值解析后不包含任何键,这会触发映射复用。如需移除映射,请传入修正后的映射,或使用 taxonomy_restore.py 回滚分类规范。

解释器规则

  • taxonomy_diff.py、taxonomy_draft.py、taxonomy_restore.py:系统 python3(标准库)
  • parse_taxonomy.py:csv 使用系统 python3;xlsx 需要 .ga4/venv/bin/python (需要 openpyxl);URL(Google Sheets)输入也需要 venv(sheets_reader 使用 Sheets API)
  • ga4_events.py:必须使用 .ga4/venv/bin/python 运行(需要 google-analytics-data)
  • sheets_reader.py:必须使用 .ga4/venv/bin/python 运行(需要 Google Sheets API)
  • custom_dims.py:必须使用 .ga4/venv/bin/python 运行(获取元数据)
  • param_naming.py:系统 python3(标准库;这是一个库模块,不能直接运行)
  • {SKILLS_DIR} = 安装这些 ga 技能的目录,即此技能目录的父目录(Claude Code 项目中的 .claude/skills;其他 Agent 使用各自的位置)。 替换为实际路径。从项目根目录运行命令。

步骤 0:状态检查(始终先执行)

检查 .ga4/,确定适用场景:

  • taxonomy.json 是否已存在?(是否已有分类体系)
  • token.json + config.json(property_id)是否存在?(ga-auth 是否已连接——实时数据功能需要此连接)

如果尚未连接,但需要使用实时数据或草拟功能,请先引导用户通过 ga-auth 技能完成连接。

检查库是否就绪(如果受阻,Google Sheets/xlsx 路径会报错 No module named ...):

python3 {SKILLS_DIR}/ga-auth/scripts/ga4_status.py

如果 deps_ready 为 false,且 missing_packages 包含 ga-taxonomy,请自行运行附带的 deps_fix 命令(用一句话说明:“我会安装读取分类表所需的库”),重新检查,然后继续。不要让营销人员运行 pip。

平台上下文

状态检查会报告 platforms,即此媒体资源收集数据的平台,采用 GA4 自身的拼写形式(web、iOS、Android 或 unknown)。这会影响实际可能存在的事件和维度,因此在判断任何内容缺失之前,请先查看它。

  • null 表示从未查询过平台。不要假定任何平台。猜测平台正是此字段要防止的问题。请重新运行 .ga4/venv/bin/python {SKILLS_DIR}/ga-auth/scripts/ga4_admin.py get-property <PROPERTY_ID> 并通过 ga-auth 技能的步骤 4 中的第 4 和第 5 项保存结果:保存操作会从头重建 config.json,因此必须在同一条命令中再次传入币种、时区和数据保留期,否则它们会变为 null——这会导致 ga-use 无法获取其报告收入所用的币种(实时响应完全不包含元数据),也会影响其空漏斗检查所依据的数据保留期。
  • [] 表示该媒体资源没有数据流——它没有收集任何数据。
  • 出现 unknown 条目表示某个数据流无法分类,因此该列表并不完整。存在 unknown 时,不要把缺少 web 理解为“仅限应用”;应说明该媒体资源无法分类,而不是对其作出仅限 Web 或仅限应用的判断。
  • 如果 platforms_age_days 超过 180,列表可能早于团队后来添加的平台。请重新检查,再依据该列表作出判断。
  • platforms 表示已配置的数据流;platform 维度表示实际收到的流量。已配置的数据流仍可能没有数据,因此不要把两者混为一谈。

场景 A:分类体系已存在(文件或 Google Sheets URL)

  1. 获取输入——Google Sheets URL 或 本地 xlsx/csv 路径。
  2. 解析(两者使用相同命令;URL 需要使用 venv python):
    .ga4/venv/bin/python {SKILLS_DIR}/ga-taxonomy/scripts/parse_taxonomy.py "<URL or file path>"
    
    • ok:true 会创建 .ga4/taxonomy.json/taxonomy.md。
    • 如果存在 replaced,则表示已有分类体系已被替换。 如果存在 replaced.event_count,请将其与本次运行的 event_count 比较——如果数量 明显减少(例如 31 -> 1),很可能解析了错误的文件或工作表。不要直接继续——请告知用户: “原有的 31 个事件变成了 1 个。您指的是这个文件吗?” (如果不存在 event_count,说明先前的文件已损坏,无法读取其大小,因此不进行比较。)
      • 如需回滚,不要手动复制文件——请使用以下命令(它会同时回滚 json 和 md):
        python3 {SKILLS_DIR}/ga-taxonomy/scripts/taxonomy_restore.py            # 列出各代版本
        python3 {SKILLS_DIR}/ga-taxonomy/scripts/taxonomy_restore.py -g latest  # 回滚
        
        根据列表中的 event_count,与用户一起决定要回退到哪个版本。 回滚前的状态也会备份为 undo_backup,因此即使选错版本,也可以撤销。 最近 5 个版本的备份保存在 .ga4/taxonomy_backups/<timestamp>/ 下。
      • 如果 replaced.backup 为 null,则无法创建备份(磁盘或权限问题)。 这意味着无法回滚,因此不要指向一个不存在的恢复路径,而应告知用户需要 从原始文件重新解析分类体系。
    • 如果存在 warnings,请先与用户逐项处理,再继续。 解析已成功, 但忽略其中任何一项都会悄然导致后续步骤出错。
      • unrecognized_scopes:scope 列填写了此解析器不认识的词语,因此这些参数没有 scope。不要猜测 scope——向用户展示无法识别的确切值和已识别的词汇,让用户 修正工作表后重新解析。如果不处理,比较步骤会将这些参数报告为“未注明 scope”, 并建议添加用户已有的 scope 列,看起来就像工具出了问题。

      • case_only_duplicate_events:见下文。

      • 共享/通用区块警告:属于“공통 매개변수”这类分类的参数被归到了某个事件下, 而不是单独保留。只有位于第一个事件上方时,通用区块才会保持独立—— 位于事件下方或事件之间时,它会悄然变成该事件的参数,分析随后便会认为只有 那一个事件携带这些参数。让作者将该区块移到第一个事件上方,然后重新解析。

      • 无 scope 的 items 数组字段警告:item_id/item_name/ price/quantity 等参数的 scope 列留空。空白 scope 默认按 event 处理; 对这些名称而言,这会改变解析结果,而不仅是稍有偏差——在一张实际工作表中, 同一个 item_id 在填写 scope 时解析为 itemId (standard, item scope), 留空时则解析为 customEvent:item_id,两者确实是不同的值。请作者填写 item, 除非该事件确实不涉及电商,且该参数确实属于事件级。

      • 对于应用属性,in_app_purchase 的 items 数组警告可能不准确。 Firebase 会自动收集该事件,并将 product_id、price、quantity、currency、value、subscription、 free_trial 和 introductory_price 作为扁平事件参数发送——不存在 items 数组。 因此,空白 scope 默认按 event 处理在这里是正确的,引导作者填写 item 会让 price 解析为 itemRevenue,而这个数值永远不会填入。请这样说明,而不要照搬警告内容。如果团队自己 将某个自定义事件命名为 in_app_purchase,则不适用上述情况——如果无法确定,请询问具体是哪一种。

      • GA4 收集限制警告:分类体系规划收集的内容超过了 GA4 的收集上限。 解析时不会报错——几个月后在生产环境中才会悄然失败。 其中 25 个事件参数的限制代价最高: Google 的说法是 Analytics 不会记录超出限制的“事件”,因此整个事件都会消失, 而不只是多出的参数。请在工作表交给开发人员之前与作者确认处理方案。

      • 注册表过时警告:每个 Not registered — cannot query 标签所依据的自定义定义快照 已过时或没有日期。先使用 custom_dims.py fetch 重新获取并重新解析,再告知用户需要 注册任何内容——否则,你可能会让他们重复注册已有内容,或者提供一个已删除的名称, 导致查询时返回 400。

      • 无效 GA4 名称警告:名称不能用作 GA4 标识符。GA4 名称以字母开头,且只能包含字母、数字和下划线,因此韩文标签肯定不符合要求——此警告不会产生误报。不要把它当作分类体系问题反馈给用户。 通常是因为工作表把人类可读的标签和 GA4 名称分别放在两列中,但系统只识别了标签列。查看同一响应中的 unnamed_columns:没有标题、值类似 user_grade 的列就是名称列。使用该列的电子表格字母进行映射并重新解析:用户属性使用 --map "<letter>=up_ga4_name",事件使用 ga4_name。映射会被保存,因此之后同步同一工作表时无需再指定标志。

        然后阅读响应。不要假定映射已应用到你指定的位置。 --map 键会应用于工作簿中的每个工作表,而同一个字母在不同工作表中代表不同的列。两个字段会报告实际发生的情况:

        • map_resolution — 每个键在每张工作表中各有一条记录,每条记录分为两种类型。header(与该工作表的标题文本匹配)或 column <letter>(通过字母指定列)表示该键已在此处读取。任何以 ignored — 开头的记录都表示未从该工作表读取任何内容,其余文字会说明原因:

          • ignored — column <letter> from its own header <field> — 该列已由自身标题命名。这就是相邻工作表中的普通 타입/Type 列不会受该字母影响的原因。
          • ignored — column <letter> already explicitly mapped to <field> — 同一 --map 中的另一个键已先占用了该列。
          • ignored — <field> already read from column <letter> by key <key> — 两个键在同一工作表上指定了相同字段;见下文。
          • ignored — no header or column on this tab matched this key — 此键在此处既不对应任何标题,也不是此工作表列宽范围内的列字母。数字永远不能用于指定列地址:--map "2=up_ga4_name" 完全不会指定任何内容。请使用电子表格列字母 B。
          • ignored — nothing was read from this tab (<reason>) — 该工作表没有可收集的此类内容(或 --sheet 指向了另一张工作表),因此映射已创建但从未使用。

          确认你指定的工作表显示 header 或 column <letter>。其他任何值都表示该工作表未作任何更改。

        • unnamed_columns — 哪张工作表的哪一列没有标题,以及该列的示例值。该列就是所指字母对应的列。

        然后重新查看警告本身:来自你映射的工作表的名称应该已消失。仍列出其他工作表中的名称,说明那些工作表也各自存在同样的问题,并不表示此次映射失败。检查那些工作表是否也有自己的 unnamed_columns 条目。 每个字段在每个工作表中只能对应一列,因此,同一字段的两个键只有在落在不同工作表时才有效。 --map "B=up_ga4_name,C=up_ga4_name" 在未命名列于一个工作表中为 B、在另一个工作表中为 C,且 两个字母在另一个工作表中各自都是普通命名列时才是正确的——在这样的工作簿上实测时,两个工作表都完成了映射,且四个用户属性都保留了各自的 GA4 名称。如果同一个工作表中两个字母都可用(有两个未命名列——例如名称列和备注列),则 --map 字符串中的第一个键会生效,第二个会被拒绝:在这样的工作表上实测时,"B=…,C=…" 会存储列 B,而 "C=…,B=…" 会存储列 C。因此,传入两个键之前,请先查看 unnamed_columns。如果两个候选列位于同一个工作表中,只传入 sample_values 为 GA4 名称的那个字母——同一次运行中无法映射另一个列,而且通常也不需要映射它。如果工作表中完全没有 GA4 名称列,则映射无法凭空创建该列;必须先在工作表中添加此列,此时应告知用户这一点。

        --sheet 不会缩小上述范围。 它只选择将哪个工作表作为事件工作表读取;用户属性仍会从所有工作表中收集,--map 键仍会应用于所有工作表。用户属性工作表也不是有效的 --sheet 目标——它没有事件列,因此会返回 needs_mapping。

        不带 --map 重新解析不会撤销映射。 成功解析后,映射会存入 taxonomy.json,下一次运行时会重用该映射(响应中会显示 reused_column_map)。若要更改映射,请传入修正后的 --map——显式指定的映射始终会替换已存储的映射。若要撤销解析本身,请回滚 taxonomy:

        python3 {SKILLS_DIR}/ga-taxonomy/scripts/taxonomy_restore.py            # 列出各代版本
        python3 {SKILLS_DIR}/ga-taxonomy/scripts/taxonomy_restore.py -g latest  # 回滚
        

        这会同时还原 taxonomy.json 和 taxonomy.md,还原的文件会保留该代版本生效的映射——因此,下次不带标志重新解析时,行为会与当时相同。请使用列表中的 user_property_count,选择包含该用户的版本。 只要存在此警告,就绝不要继续进行比较步骤——如果标签存储为名称,它们都会显示为“未注册”,这会让人以为实现出了问题。在真实的分类体系中进行测量:24 个用户属性均已正确注册,却全部被报告为缺失。 taxonomy_diff.py 会独立检查此情况并报告 invalid_names,因此之后从比较步骤开始的会话也不会漏掉此警告——但不要因此跳过修复解析问题。

    • 如果存在 case_only_duplicate_events,请先询问用户,再继续操作。 两个事件名称仅大小写不同(例如 Purchase 与 purchase)时,它们会被保留为独立事件,参数也会拆分到这两个事件中。GA4 只会发送一个完全匹配的名称,因此这几乎总是表格中的笔误。不要自行决定使用哪种大小写——询问实际采集的是哪一个(ga4_events.py list 会显示 GA4 中的实际情况),请用户修正表格,然后重新解析。如果不修正,之后在比较步骤中,未使用的大小写形式会显示为“已定义但未采集”,看起来就像实现出了问题。
    • 即使同一张表混合了事件、通用参数和用户属性,也会分别读取各行。纵向合并的单元格(空白)会从上一个值填入其类别。 如果同时存在 Event 和 Event Name 列,前者会被视为标签,后者会被视为 GA4 事件名称。
    • 如果结果中包含通用参数(.ga4/taxonomy.json 中的 common_parameters 数组,或 taxonomy.md 中已填写的 ## Common Parameters 部分),请向用户确认该部分在原始表格中是否位于事件列表上方——如果它位于中间,可能会在没有任何提示的情况下被并入前一个事件。
    • 如果 needs_sheet_choice:true,则有多个工作表看起来像事件分类表(例如 Pixel 对照表)。向用户展示 candidates,询问哪个工作表是事件分类表,然后使用 --sheet "<tab name>" 重新运行。不要自行选择工作表。
    • 如果 needs_mapping:true,则自动列识别失败。查看响应中的 sheets[].headers,并将每一列映射到规范字段(category、event_label、ga4_name、event_description、param_name、param_type、param_description、param_example、param_scope),然后使用 --map "original-header=canonical-field,..." 重新运行。
    • 如果 needs_mapping:true 且存在 unmapped_headers,说明事件列已识别,但参数列未识别,因此所有参数都会被丢弃。查看 unmapped_headers 和 mapped_fields,判断哪个未映射的表头是参数名称列,然后使用 --map 重新运行。不要将此情况理解为“此分类体系没有参数”——这意味着相关列未被识别。
    • 如果 Google Sheets 访问因权限/范围错误而失败,请引导用户通过 ga-auth 重新登录(授予电子表格权限)。
  3. 如果已连接,请继续进行实时数据比较(场景 D)。

场景 B:空状态 + GA4 已在收集数据(从数据起草)

  1. 确认连接(如果缺少连接,引导用户使用 ga-auth)。获取实时数据:
    .ga4/venv/bin/python {SKILLS_DIR}/ga-taxonomy/scripts/ga4_events.py list --days 30
    
  2. 根据数据起草 CSV:
    python3 {SKILLS_DIR}/ga-taxonomy/scripts/taxonomy_draft.py
    
    生成 .ga4/taxonomy_draft.csv,并将每个事件归入以下三类之一: Auto-collected(GA4 会发送此类事件;无需记录)、Recommended(Google 定义了名称的含义,因此会填入描述——purchase、add_to_cart、refund 及其他电商事件),以及 (Uncategorized),此类事件的名称只有这家企业才知道,因此描述留空。已填入的 Recommended 描述说明的是名称应有的含义,而不代表网站已正确发送该事件——这仍需作者确认。
  3. 让营销人员完善草稿中的类别、描述和参数,然后按照场景 A 将完成后的版本解析为正式分类法。

场景 C:空状态 + 全新状态(尚未收集任何数据)

  1. 使用 assets/taxonomy_template.{csv,xlsx} 和 references/taxonomy-guide.md 引导撰写(推荐使用包含 9 列的实用模板; 列名和顺序可以略有不同,因为自动识别和 --map 可以进行修正)。 同时建议采用标准 GA4 事件(purchase、sign_up、login 等)和适合该业务的自定义事件。
  2. 按照场景 A 解析完成后的文档。

场景 D:与实时数据对照(分类法和连接均已就绪)

  1. 获取实时数据(如果缓存已过期,则重新获取):

    .ga4/venv/bin/python {SKILLS_DIR}/ga-taxonomy/scripts/ga4_events.py list --days 30
    
  2. 获取自定义定义(自定义维度/指标)的状态:

    .ga4/venv/bin/python {SKILLS_DIR}/ga-taxonomy/scripts/custom_dims.py fetch
    
  3. 生成对照报告:

    python3 {SKILLS_DIR}/ga-taxonomy/scripts/taxonomy_diff.py
    
  4. 用通俗易懂的语言说明结果。

    如果存在 invalid_names,请先停止并处理,然后再读取任何其他内容。 这些分类法名称不能作为 GA4 标识符(GA4 名称以字母开头,且只能包含字母、数字和下划线),因此 GA4 不可能以这些名称收集或注册它们。下面对这些名称作出的所有判定都毫无意义,而不只是负面——将它们报告为缺少实现或缺少注册,本身就是最初的问题:24 个已正确注册的用户属性被报告为缺少,另有建议删除其中 12 个。这与解析时的警告是同一问题;此处会重新检查,因为相关信息未记录在 taxonomy.json 中,而且从此步骤开始的会话并未经过解析。请先修正解析(参见场景 A 中关于无效 GA4 名称的指引),然后重新进行对照。

    事件:

    • defined_not_seen_recently:已定义,但在过去 days 天内未收到。 不要立刻断定是“缺少实现”。较短的回溯窗口会将低频事件标记出来,即使事件实际运行正常(观察结果:14 个被标记的事件中,有 9 个实际运行正常;其中一个在 365 天窗口内有 474 次命中)。 告知用户时,务必注明时间窗口(“过去 30 天内未收到”);如果看起来像是实现问题,请先检查更长的时间窗口,再下结论:ga4_events.py list --days 365 → 重新进行对照。 在将任何内容判定为缺少实现之前,先检查平台。 如果某个事件不可能出现在此媒体资源的数据流中,它就永远不会出现,而延长回溯窗口也无济于事——让用户运行 ga4_events.py list --days 365 来查找这种事件,只会浪费他们的时间,还会让人觉得工具坏了。
    • 仅限 App 的媒体资源(platforms 为 ["iOS"]、["Android"] 或两者兼有,且没有其他值):page_view、scroll、click、file_download、form_start、form_submit、first_visit 和 view_search_results 都是 Web 增强型衡量事件。它们不会出现。
    • 仅限 Web 的媒体资源(platforms 恰好为 ["web"]):first_open、screen_view、in_app_purchase、app_update、app_remove、app_exception、os_update、app_store_* 集合以及 notification_* 集合都是 App 事件。它们不会出现。
    • 混合媒体资源(同时包含 Web 和 App):两组事件都可能存在。不要应用上述任一判断。
    • 列表中包含 unknown,或为 [],或为 null:无法对数据流进行分类(或尚未查询),因此三种判断都不要应用。说明平台尚未确认,并提出重新检查——此处缺少 web 表示“我们无法判断”,而非“仅限 App”;擅自将其判定为后者,正是本节要避免的自信但错误的回答。
    • near_misses:如果存在,先查看这些项目。这些名称对的拼写只有细微差别,分类名称与实际名称并不完全一致(观察到的示例:分类中的 click_button_cosulting_group 与实际的 click_button_consulting_group)。 这不是缺少实现,而是拼写错误或重命名,因此应修正分类一侧。
    • collected_but_undefined:已收集但未定义 → 缺少文档说明或属于非标准事件。这才是真正的信号——GA4 自动收集/增强型衡量事件(page_view、session_start 等)已被筛选到 auto_collected_undocumented 中,因此这里的所有内容都值得记录。
    • auto_collected_undocumented:已收集但未定义,同时也是 GA4 的自动收集/增强型衡量事件之一(参见 taxonomy_schema.py 中的 AUTO_COLLECTED_EVENTS)。顺带提及数量即可;不要向用户逐项列出,也不要让他们逐个记录——这是预期情况,并非缺口。
    • defined_and_collected:正常。
    • 如果存在 cache_hint,表示实时数据缓存已过期或其缓存时长未知。报告核对结果之前,使用 ga4_events.py list 重新获取数据。 参数 / 用户属性(parameters/user_properties 部分,每部分都有一个用于归类每个参数的 items 数组):
    • defined_not_registered:最重要的输出。 在分类表中有定义,但未注册为自定义维度/指标,因此无法在分析中查询。 指引用户在 GA4 管理后台 -> 自定义定义中注册。在注册之前,无法按此参数细分或筛选。
    • 提供注册建议前先检查 scope。 scope: "item" 的参数必须在 GA4 管理后台注册时将范围设为商品,而不是事件。若告诉营销人员将商品范围的参数注册为事件范围,就会创建一个无法按商品细分数据的自定义维度。
    • standard_metric(带有 note):无需注册即可查询,但其值是 items 数组的汇总值(itemRevenue、itemsPurchased),而非原始的逐商品数据。请说明这一点,不要将其说成与该参数完全对应。
    • ambiguous: true:分类表未注明范围,且该参数尚未注册,因此按事件范围处理。传达随附的 hint:请用户添加 items. 前缀或范围列。确认范围之前不要要求注册。
    • standard_equivalent:可通过标准维度(standard_dimension 字段)查询,因此无需注册——不要告诉用户注册。对应关系表仅包含 GA4 会将该参数用作输入来填充标准维度的参数(自动收集/增强型衡量)。像 source/medium/campaign 这样的项目只是名称相同,但来源不同,因此有意排除——请参阅 param_naming.py 中的注释。
    • reserved_not_registerable:GA4 拒绝将此名称用作自定义定义,因此这不是应提交的注册请求——无法通过 Data API 使用此名称查询。不要将其归入上面的 defined_not_registered 建议;告诉营销人员注册会把他们引导至一个会拒绝该名称的管理后台页面,而这正是此分类要避免的错误回答。请说明该名称是保留名称;如果 note 指明了标准等效项,则指出该等效项。保留名称在实际分类表中很常见(user_id、session_id、任何带有 google_/ga_/firebase_ 前缀的名称),因此可能会遇到。
    • defined_and_registered:正常情况。api_names(一个数组——指标可能有多个聚合变体)包含实际可查询的名称。如果 note 说明存在标准等效项,优先使用该名称——无需注册,而且即使自定义定义被移除,仍可查询。
    • registered_not_defined:该部分(parameters/user_properties)下的独立顶层列表——已注册但未出现在分类表中 -> 可考虑添加到分类表。 它不是 api_name 字符串,而是一个结构与 items 相同的对象数组(parameter/scope/kind/api_names/unit),并且按参数名称分组。即使某个指标的 3 种聚合变体(总和/平均值/计数)都已注册,它仍只显示为一个条目,所有 3 个可查询名称都包含在 api_names 中——只需在分类表中添加一行。

    available: false 表示步骤 2 尚未运行。这不是错误,只需注明这一点,并仍然提供事件核对结果。

    无法确定未注册的参数是否确实正在收集。 GA4 仅通过 API 暴露已注册的自定义定义,因此只能说“未注册”,不要猜测其收集状态。

文件位置

  • 运行时状态:项目本地的 .ga4/(已加入 Git 忽略)
    • taxonomy.json:解析后的分类(计划)——事件(label/ga4_name/parameters[type])
      • common_parameters(不属于特定事件的通用参数)+ user_properties。每个用户属性都有 name(GA4 名称)和 label(人类可读的名称;如果表格从未将两者分开,则为 null)。
    • taxonomy.md:人类可读的分类摘要。其参数表中有一列查询名称(method (standard) / customEvent:author / customEvent:stay_time (metric) / Not registered — cannot query),确保 ga-use 不会使用错误的名称进行查询。有两个标签提供的是建议而非名称,且含义不同: Reserved name — cannot be registered or queried 表示 GA4 会拒绝该名称,因此不要让营销人员前往 Admin -> Custom Definitions;customEvent:x — prefer standard Y 表示该参数已注册,但已有标准维度可以回答相关问题,因此应引用 Y(无需维护注册信息,而且即使自定义定义被移除,它仍然有效)。 如果缺少 custom_definitions.json,则会显示 (Needs confirmation)——仅使用 custom_dims.py fetch 获取该文件,不会更新已生成的 taxonomy.md(只有 parse_taxonomy.py 会重新生成其内容;taxonomy_restore.py 只会恢复先前的副本)。获取该文件后,重新解析分类(场景 A 第 2 步)即可填充内容。
    • taxonomy_backups/<timestamp>/:解析前 taxonomy.json+taxonomy.md 的副本(最近 5 个版本)。如果解析了错误的文件/表格并清除了分类,可回滚整个文件夹。
    • collected_events.json:实时数据缓存(由 ga4_events.py 生成)
    • taxonomy_draft.csv:起草后备份的草稿(供营销人员审核)
    • custom_definitions.json:自定义维度/指标注册状态(由 custom_dims.py 生成)
  • config.json(property_id)和 token.json 由 the ga-auth skill 创建并管理。
  • GA4_DIR 环境变量可以更改 .ga4 的位置(默认值:<cwd>/.ga4)。

评论

支持 Markdown