|
|
@@ -0,0 +1,641 @@
|
|
|
+# H5 任务页埋点与结果回传规范
|
|
|
+> 文档版本:v1.0
|
|
|
+> 最后更新:2026-04-05 12:36:25
|
|
|
+
|
|
|
+本文档用于定义当前项目中,**原生内容卡、H5 详情页、H5 互动任务页、增强结果页** 的最小埋点口径与结果回传结构,避免后续出现“曝光、点击、任务完成、业务落库”混为一谈的情况。
|
|
|
+
|
|
|
+核心结论:
|
|
|
+
|
|
|
+**展示埋点、交互埋点、任务结果回传必须分层定义;H5 可以上报行为与任务结果,但不能直接决定打点成功或比赛状态。**
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 目标
|
|
|
+
|
|
|
+本文档重点解决以下问题:
|
|
|
+
|
|
|
+- 如何统一原生内容卡与 H5 页的埋点事件口径
|
|
|
+- 如何区分“浏览行为”与“任务完成结果”
|
|
|
+- 如何通过 `submitResult` 回传 H5 任务页结果
|
|
|
+- 如何让内容面 API 稳定承接任务结果落库
|
|
|
+- 如何保证埋点失败或回传失败时不阻断主流程
|
|
|
+
|
|
|
+适用范围:
|
|
|
+
|
|
|
+- 打点后原生内容卡
|
|
|
+- 原生内容卡 CTA 进入的 H5 详情页
|
|
|
+- H5 互动任务页
|
|
|
+- H5 增强结果页
|
|
|
+
|
|
|
+不适用范围:
|
|
|
+
|
|
|
+- 打点判定本身
|
|
|
+- 地图主链状态流转
|
|
|
+- 高频 telemetry 主链
|
|
|
+- 实时网关事件流替代方案
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. 边界原则
|
|
|
+
|
|
|
+### 2.1 任务结果不等于比赛结果
|
|
|
+
|
|
|
+H5 回传的任务结果只表示:
|
|
|
+
|
|
|
+- 某个互动任务是否完成
|
|
|
+- 某个表单是否提交
|
|
|
+- 某个作品是否生成
|
|
|
+- 某个增强页是否完成关键动作
|
|
|
+
|
|
|
+它不直接表示:
|
|
|
+
|
|
|
+- 打点是否成功
|
|
|
+- 本局是否完赛
|
|
|
+- 成绩是否生效
|
|
|
+
|
|
|
+### 2.2 埋点事件不等于业务落库
|
|
|
+
|
|
|
+埋点事件主要用于:
|
|
|
+
|
|
|
+- 行为分析
|
|
|
+- 页面漏斗观察
|
|
|
+- 体验优化
|
|
|
+- 运营数据统计
|
|
|
+
|
|
|
+业务落库主要用于:
|
|
|
+
|
|
|
+- 记录任务完成事实
|
|
|
+- 记录作品或表单提交结果
|
|
|
+- 记录奖励发放依据
|
|
|
+
|
|
|
+这两者可以共用部分字段,但不能视为同一条链路。
|
|
|
+
|
|
|
+### 2.3 埋点失败不阻断体验
|
|
|
+
|
|
|
+若埋点上报失败:
|
|
|
+
|
|
|
+- 页面仍可继续浏览
|
|
|
+- 任务仍可继续操作
|
|
|
+- 比赛主流程不应被中断
|
|
|
+
|
|
|
+### 2.4 结果回传失败不反向控制主流程
|
|
|
+
|
|
|
+若 `submitResult` 或内容面 API 落库失败:
|
|
|
+
|
|
|
+- 不应改写打点成功状态
|
|
|
+- 不应强制比赛中断
|
|
|
+- 允许重试、缓存或降级提示
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. 推荐分层模型
|
|
|
+
|
|
|
+建议将相关事件分为三层:
|
|
|
+
|
|
|
+### 3.1 展示层事件
|
|
|
+
|
|
|
+用于记录页面或卡片是否被看到。
|
|
|
+
|
|
|
+例如:
|
|
|
+
|
|
|
+- 内容卡进入
|
|
|
+- H5 页面曝光
|
|
|
+- 结果页进入
|
|
|
+
|
|
|
+### 3.2 交互层事件
|
|
|
+
|
|
|
+用于记录用户在页面中的关键操作。
|
|
|
+
|
|
|
+例如:
|
|
|
+
|
|
|
+- CTA 点击
|
|
|
+- 页面关闭
|
|
|
+- 按钮点击
|
|
|
+- 表单提交点击
|
|
|
+- 分享点击
|
|
|
+
|
|
|
+### 3.3 结果层事件
|
|
|
+
|
|
|
+用于记录任务是否完成,以及完成后产出的结果对象。
|
|
|
+
|
|
|
+例如:
|
|
|
+
|
|
|
+- 拍照任务完成
|
|
|
+- 留言任务完成
|
|
|
+- 答题任务完成
|
|
|
+- 作品提交成功
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. 统一标识字段
|
|
|
+
|
|
|
+无论是原生内容卡还是 H5 页面,建议统一携带以下字段:
|
|
|
+
|
|
|
+- `eventId`
|
|
|
+ 活动标识
|
|
|
+- `sessionId`
|
|
|
+ 对局标识
|
|
|
+- `controlId`
|
|
|
+ 点位标识;非点位页面可为空
|
|
|
+- `taskId`
|
|
|
+ 任务标识;非任务页面可为空
|
|
|
+- `pageCode`
|
|
|
+ H5 页面编码
|
|
|
+- `pageType`
|
|
|
+ 页面类型
|
|
|
+- `bridgeVersion`
|
|
|
+ Bridge 协议版本
|
|
|
+- `contentSource`
|
|
|
+ 内容来源
|
|
|
+- `triggerSource`
|
|
|
+ 触发来源
|
|
|
+- `timestamp`
|
|
|
+ 事件时间
|
|
|
+
|
|
|
+建议补充字段:
|
|
|
+
|
|
|
+- `userId`
|
|
|
+- `tenantId`
|
|
|
+- `variantId`
|
|
|
+- `resultId`
|
|
|
+- `deviceType`
|
|
|
+- `networkType`
|
|
|
+
|
|
|
+字段说明:
|
|
|
+
|
|
|
+- `contentSource`
|
|
|
+ 建议取值:`native-card` `h5-content` `h5-task` `h5-result`
|
|
|
+- `triggerSource`
|
|
|
+ 建议取值:`auto-popup` `card-cta` `map-click` `result-action`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. 页面类型建议
|
|
|
+
|
|
|
+建议统一定义以下 `pageType`:
|
|
|
+
|
|
|
+- `native-content-card`
|
|
|
+- `h5-content-page`
|
|
|
+- `h5-task-page`
|
|
|
+- `native-result-page`
|
|
|
+- `h5-result-page`
|
|
|
+
|
|
|
+这样可以保证:
|
|
|
+
|
|
|
+- 原生与 H5 事件可以统一分析
|
|
|
+- 同一任务可横跨内容卡和任务页追踪
|
|
|
+- 结果页增强链不会混进地图主链事件
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 6. 原生内容卡最小事件集
|
|
|
+
|
|
|
+结合当前待办中的口径,建议先正式收口以下事件:
|
|
|
+
|
|
|
+### 6.1 `content_card_enter`
|
|
|
+
|
|
|
+表示内容卡实际展示给用户。
|
|
|
+
|
|
|
+建议时机:
|
|
|
+
|
|
|
+- 卡片完成入场动画后
|
|
|
+- 卡片真实可见时
|
|
|
+
|
|
|
+### 6.2 `content_card_close`
|
|
|
+
|
|
|
+表示内容卡被关闭。
|
|
|
+
|
|
|
+建议补充原因字段:
|
|
|
+
|
|
|
+- `closeReason = auto-dismiss`
|
|
|
+- `closeReason = user-close`
|
|
|
+- `closeReason = replaced`
|
|
|
+- `closeReason = open-h5`
|
|
|
+
|
|
|
+### 6.3 `content_card_cta_click`
|
|
|
+
|
|
|
+表示用户点击内容卡主 CTA。
|
|
|
+
|
|
|
+建议补充字段:
|
|
|
+
|
|
|
+- `ctaKey`
|
|
|
+- `targetType`
|
|
|
+- `targetPageCode`
|
|
|
+
|
|
|
+### 6.4 `result_page_enter`
|
|
|
+
|
|
|
+表示原生结果页进入。
|
|
|
+
|
|
|
+该事件用于与 H5 增强结果页做漏斗对比。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 7. H5 页面最小事件集
|
|
|
+
|
|
|
+### 7.1 `h5_page_enter`
|
|
|
+
|
|
|
+表示 H5 页面真实进入。
|
|
|
+
|
|
|
+建议在:
|
|
|
+
|
|
|
+- 页面初始化完成
|
|
|
+- 基础上下文已拿到
|
|
|
+- 主视图可见
|
|
|
+
|
|
|
+之后触发,而不是在 `web-view` 打开瞬间就记。
|
|
|
+
|
|
|
+### 7.2 `h5_page_exit`
|
|
|
+
|
|
|
+表示 H5 页面退出。
|
|
|
+
|
|
|
+建议补充:
|
|
|
+
|
|
|
+- `exitReason = close`
|
|
|
+- `exitReason = back`
|
|
|
+- `exitReason = bridge-close`
|
|
|
+- `exitReason = replaced`
|
|
|
+- `exitReason = error`
|
|
|
+
|
|
|
+### 7.3 `h5_cta_click`
|
|
|
+
|
|
|
+表示 H5 页内关键 CTA 被点击。
|
|
|
+
|
|
|
+建议至少带:
|
|
|
+
|
|
|
+- `ctaKey`
|
|
|
+- `ctaLabel`
|
|
|
+- `taskId`
|
|
|
+
|
|
|
+### 7.4 `h5_interaction`
|
|
|
+
|
|
|
+表示任务页关键互动动作。
|
|
|
+
|
|
|
+建议只用于关键动作,不记录所有噪声操作。
|
|
|
+
|
|
|
+推荐 `actionKey`:
|
|
|
+
|
|
|
+- `start-task`
|
|
|
+- `take-photo`
|
|
|
+- `record-audio`
|
|
|
+- `submit-form`
|
|
|
+- `share`
|
|
|
+- `retry`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 8. 任务生命周期事件
|
|
|
+
|
|
|
+若页面属于互动任务页,建议增加一组任务态事件:
|
|
|
+
|
|
|
+### 8.1 `task_viewed`
|
|
|
+
|
|
|
+表示用户已看到任务主体。
|
|
|
+
|
|
|
+### 8.2 `task_started`
|
|
|
+
|
|
|
+表示用户开始任务,不再只是浏览。
|
|
|
+
|
|
|
+### 8.3 `task_progressed`
|
|
|
+
|
|
|
+表示阶段性推进。
|
|
|
+
|
|
|
+适用场景:
|
|
|
+
|
|
|
+- 多步表单
|
|
|
+- 连续拍照
|
|
|
+- 多题答题
|
|
|
+- 分阶段收集
|
|
|
+
|
|
|
+建议带:
|
|
|
+
|
|
|
+- `stepId`
|
|
|
+- `stepIndex`
|
|
|
+- `stepStatus`
|
|
|
+
|
|
|
+### 8.4 `task_completed`
|
|
|
+
|
|
|
+表示任务完成,但不代表业务一定已成功落库。
|
|
|
+
|
|
|
+### 8.5 `task_failed`
|
|
|
+
|
|
|
+表示任务失败。
|
|
|
+
|
|
|
+建议补充:
|
|
|
+
|
|
|
+- `errorCode`
|
|
|
+- `errorStage`
|
|
|
+
|
|
|
+### 8.6 `task_cancelled`
|
|
|
+
|
|
|
+表示用户主动放弃任务。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 9. `submitResult` 推荐结构
|
|
|
+
|
|
|
+建议将 `submitResult` 视为“结果层回传”,而不是普通点击埋点。
|
|
|
+
|
|
|
+推荐最小结构:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "id": "req-002",
|
|
|
+ "channel": "request",
|
|
|
+ "type": "submitResult",
|
|
|
+ "payload": {
|
|
|
+ "taskId": "task-photo-control-3",
|
|
|
+ "taskType": "photo-checkin",
|
|
|
+ "attemptId": "attempt-001",
|
|
|
+ "status": "completed",
|
|
|
+ "pageCode": "task-control-3-photo",
|
|
|
+ "controlId": "control-3",
|
|
|
+ "result": {
|
|
|
+ "assetId": "img-001"
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+字段建议:
|
|
|
+
|
|
|
+- `taskId`
|
|
|
+ 任务标识
|
|
|
+- `taskType`
|
|
|
+ 任务类型
|
|
|
+- `attemptId`
|
|
|
+ 一次任务尝试标识
|
|
|
+- `status`
|
|
|
+ 任务结果状态
|
|
|
+- `pageCode`
|
|
|
+ 页面编码
|
|
|
+- `controlId`
|
|
|
+ 关联点位
|
|
|
+- `result`
|
|
|
+ 结构化结果对象
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 10. `submitResult.status` 建议口径
|
|
|
+
|
|
|
+建议第一阶段只正式支持:
|
|
|
+
|
|
|
+- `completed`
|
|
|
+- `failed`
|
|
|
+- `cancelled`
|
|
|
+- `skipped`
|
|
|
+
|
|
|
+建议解释:
|
|
|
+
|
|
|
+- `completed`
|
|
|
+ 用户已完成任务目标
|
|
|
+- `failed`
|
|
|
+ 本次任务尝试失败
|
|
|
+- `cancelled`
|
|
|
+ 用户主动退出或放弃
|
|
|
+- `skipped`
|
|
|
+ 允许跳过的任务被明确跳过
|
|
|
+
|
|
|
+当前不建议第一阶段就把过多中间状态做成业务落库状态。
|
|
|
+
|
|
|
+例如:
|
|
|
+
|
|
|
+- `viewed`
|
|
|
+- `started`
|
|
|
+- `progressed`
|
|
|
+
|
|
|
+这些更适合作为埋点事件,而不是最终任务结果状态。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 11. `result` 结果对象建议
|
|
|
+
|
|
|
+不同任务类型建议分别约定 `result`:
|
|
|
+
|
|
|
+### 11.1 拍照任务
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "assetId": "img-001",
|
|
|
+ "assetType": "image",
|
|
|
+ "count": 1
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 11.2 录音任务
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "assetId": "audio-001",
|
|
|
+ "assetType": "audio",
|
|
|
+ "durationMs": 12000
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 11.3 表单任务
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "formId": "form-001",
|
|
|
+ "submissionId": "sub-001"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 11.4 问答任务
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "questionSetId": "quiz-001",
|
|
|
+ "score": 3,
|
|
|
+ "total": 5
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+原则:
|
|
|
+
|
|
|
+- `result` 保持结构化
|
|
|
+- 不直接塞整页原始页面状态
|
|
|
+- 不把分析事件数组混进 `result`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 12. 内容面 API 落库建议
|
|
|
+
|
|
|
+建议内容面 API 承接:
|
|
|
+
|
|
|
+- H5 页面入口鉴权
|
|
|
+- H5 上下文初始化
|
|
|
+- `submitResult` 后的业务落库
|
|
|
+- 上传结果对象登记
|
|
|
+
|
|
|
+建议最小落库对象至少包含:
|
|
|
+
|
|
|
+- `eventId`
|
|
|
+- `sessionId`
|
|
|
+- `controlId`
|
|
|
+- `taskId`
|
|
|
+- `attemptId`
|
|
|
+- `pageCode`
|
|
|
+- `status`
|
|
|
+- `resultJson`
|
|
|
+- `submittedAt`
|
|
|
+
|
|
|
+建议能力边界:
|
|
|
+
|
|
|
+- 内容面 API 记录任务完成事实
|
|
|
+- 主系统继续负责比赛核心状态
|
|
|
+- 不通过内容面 API 直接判定打点成功或比赛结束
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 13. 去重与幂等建议
|
|
|
+
|
|
|
+为避免重复点击、网络重试或页面重进导致重复落库,建议:
|
|
|
+
|
|
|
+### 13.1 任务尝试幂等
|
|
|
+
|
|
|
+建议以:
|
|
|
+
|
|
|
+- `sessionId`
|
|
|
+- `taskId`
|
|
|
+- `attemptId`
|
|
|
+
|
|
|
+作为一次任务尝试的幂等键。
|
|
|
+
|
|
|
+### 13.2 埋点去重
|
|
|
+
|
|
|
+建议以下事件在单次页面进入内只记一次:
|
|
|
+
|
|
|
+- `h5_page_enter`
|
|
|
+- `task_viewed`
|
|
|
+- `task_started`
|
|
|
+- `task_completed`
|
|
|
+
|
|
|
+### 13.3 可重复事件
|
|
|
+
|
|
|
+以下事件允许多次:
|
|
|
+
|
|
|
+- `h5_cta_click`
|
|
|
+- `h5_interaction`
|
|
|
+- `task_progressed`
|
|
|
+
|
|
|
+但建议带:
|
|
|
+
|
|
|
+- `sequence`
|
|
|
+- `stepId`
|
|
|
+- `timestamp`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 14. 推荐上报时机
|
|
|
+
|
|
|
+建议的最小时机如下:
|
|
|
+
|
|
|
+### 14.1 原生内容卡
|
|
|
+
|
|
|
+- 卡片入场完成后:`content_card_enter`
|
|
|
+- 用户关闭时:`content_card_close`
|
|
|
+- CTA 点击时:`content_card_cta_click`
|
|
|
+
|
|
|
+### 14.2 H5 内容页 / 任务页
|
|
|
+
|
|
|
+- 页面首屏稳定后:`h5_page_enter`
|
|
|
+- 任务主体真正可见后:`task_viewed`
|
|
|
+- 用户开始实际互动后:`task_started`
|
|
|
+- 关键阶段完成后:`task_progressed`
|
|
|
+- 调用 `submitResult(completed)` 前:`task_completed`
|
|
|
+
|
|
|
+### 14.3 结果页
|
|
|
+
|
|
|
+- 原生结果页进入:`result_page_enter`
|
|
|
+- H5 增强结果页进入:`h5_page_enter`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 15. fallback 规则
|
|
|
+
|
|
|
+### 15.1 H5 打不开
|
|
|
+
|
|
|
+- 记一条 `h5_open_failed`
|
|
|
+- 回退到原生内容卡或原生结果页
|
|
|
+
|
|
|
+### 15.2 埋点接口失败
|
|
|
+
|
|
|
+- 允许静默失败或批量补报
|
|
|
+- 不阻断用户当前操作
|
|
|
+
|
|
|
+### 15.3 `submitResult` 失败
|
|
|
+
|
|
|
+- 页面应拿到明确失败回执
|
|
|
+- 允许用户重试
|
|
|
+- 原生可决定是否保留最小完成提示
|
|
|
+
|
|
|
+### 15.4 Bridge 未就绪
|
|
|
+
|
|
|
+- 禁用依赖原生能力的操作
|
|
|
+- 仅保留静态浏览能力
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 16. 第一阶段建议收口的正式事件
|
|
|
+
|
|
|
+建议第一阶段只先正式收口以下事件,不一开始扩太大:
|
|
|
+
|
|
|
+- `content_card_enter`
|
|
|
+- `content_card_close`
|
|
|
+- `content_card_cta_click`
|
|
|
+- `result_page_enter`
|
|
|
+- `h5_page_enter`
|
|
|
+- `h5_page_exit`
|
|
|
+- `h5_cta_click`
|
|
|
+- `task_viewed`
|
|
|
+- `task_started`
|
|
|
+- `task_completed`
|
|
|
+- `task_failed`
|
|
|
+- `task_cancelled`
|
|
|
+
|
|
|
+以及一个正式回传动作:
|
|
|
+
|
|
|
+- `submitResult`
|
|
|
+
|
|
|
+这样已经足够支撑:
|
|
|
+
|
|
|
+- 内容卡漏斗
|
|
|
+- H5 页面进入漏斗
|
|
|
+- 任务页完成率
|
|
|
+- 原生页与 H5 页联动链路
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 17. 当前阶段不建议做的事
|
|
|
+
|
|
|
+- 不建议把所有按钮点击都做成正式公共事件
|
|
|
+- 不建议把页面内局部滚动、每次切 tab 都纳入统一业务口径
|
|
|
+- 不建议让 `submitResult` 兼做曝光埋点
|
|
|
+- 不建议让 H5 页面自己定义完全不同的一套事件命名
|
|
|
+- 不建议直接把原始页面表单全文落到统一分析事件里
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 18. 与现有文档的关系
|
|
|
+
|
|
|
+本规范补充收口以下文档中的未定项:
|
|
|
+
|
|
|
+- `原生与 H5 Bridge 规范`
|
|
|
+- `H5 增强与内容扩展层方案`
|
|
|
+- `混合体验架构方案`
|
|
|
+- `API 与发布物边界约定`
|
|
|
+- `MyToDo` 中已出现的内容卡与结果页事件线索
|
|
|
+
|
|
|
+定位上:
|
|
|
+
|
|
|
+- `Bridge 规范` 负责通信动作
|
|
|
+- 本文负责埋点口径与任务结果口径
|
|
|
+- 内容面 API 文档后续再细化具体落库接口
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 19. 一句话结论
|
|
|
+
|
|
|
+最适合当前项目的做法不是让 H5 自己发明一套任务体系,而是:
|
|
|
+
|
|
|
+**由主系统定义统一上下文、统一事件口径、统一结果回传结构,让 H5 只负责增强体验与任务执行。**
|