一款好用的前端埋点系统,神策数据埋点用户数据联通逻辑浅析

1,408 阅读3分钟

因为最近要重构公司项目中的埋点,而且最好是能满足业务的同时也能做到前端监控的功能,最终选择了神策数据的埋点系统。

本篇文章主要叙述一下神策埋点小程序与H5的用户数据打通的逻辑,顺便再说说神策数据的小程序与H5接入与使用方式。

SDK引入

小程序

app.js中引入SDK并初始化设置:

var sensors = require('./utils/sensorsdata.cjs.js');

sensors.setPara({
  // name的作用就是getApp()可以全局访问到 比如name是sensors,那getApp().sensors就能访问
  name: 'sensors',
  server_url: 'http://.../sa',
  // 全埋点控制开关
  autoTrack:{
    appLaunch: true, // 默认为 true,false 则关闭 $MPLaunch 事件采集
    appShow: true, // 默认为 true,false 则关闭 $MPShow 事件采集
    appHide: true, // 默认为 true,false 则关闭 $MPHide 事件采集
    pageShow: true, // 默认为 true,false 则关闭 $MPViewScreen 事件采集
    pageShare: true, // 默认为 true,false 则关闭 $MPShare 事件采集
    mpClick: false, // 默认为 false,true 则开启 $MPClick 事件采集
    mpFavorite: true, // 默认为 true,false 则关闭 $MPAddFavorites 事件采集
    pageLeave: false // 默认为 false, true 则开启 $MPPageLeave事件采集
  },
  // 是否允许控制台打印查看埋点数据(建议开启查看)
  show_log: true
});

H5

从npm获取:

 npm install sa-sdk-javascript -E

main.js中引入:

var sensors = require('sa-sdk-javascript'); 
sensors.init({
  server_url: '数据接收地址',
  is_track_single_page:true, // 单页面配置,默认开启,若页面中有锚点设计,需要将该配置删除,否则触发锚点会多触发 $pageview 事件
  use_client_time:true, 
  send_type:'beacon',
  heatmap: {
     //是否开启点击图,default 表示开启,自动采集 $WebClick 事件,可以设置 'not_collect' 表示关闭。
     clickmap:'default',
     //是否开启触达图,not_collect 表示关闭,不会自动采集 $WebStay 事件,可以设置 'default' 表示开启。
     scroll_notice_map:'not_collect'
  }
});
sensors.quick('autoTrack'); //用于采集 $pageview 事件。

Vue.prototype.$sensors = sensors;

用户数据关联策略

未登录关联

对于未登录的用户,会根据用户手机生成匿名ID也可以称为UUID,神策生成的UUID会存在storage中,所以在小程序被删除后,再次打开就会生成新的UUID

这种情况就会导致同一用户的操作被记录为多个用户行为,为了避免这种情况的出现,需要在神策初始化的时候用openid作为未登录用户的UUID

wx.login({
  success: res => {
    // 通过业务接口获取openid
    getOpenId({
      code: res.code
    }).then(res => {
      sensors.setOpenid(res.openid);
    })
  },
  complete: () => {
    // 初始化写在complete回调是为了保证sensors会初始化完成
    sensors.init()
  }
})

因为执行完sensors.init(),神策就会开始收发数据,而获取openid是个异步过程,所以init执行在获取到openid之后就能确保数据中的UUID是一致的。

登录关联

对于执行过登录操作的用户,需要调用login接口实现用户信息的关联:

getUserInfo().then(res => {
  getApp().sensors.login(res.id)
  getApp().sensors.bind("$identity_phone",res.phone);
})

通过业务接口获取到用户唯一ID,再通过login将唯一ID覆盖之前的UUID,同样可以设置一些用户的公共属性,如$identity_phone

因为神策的用户表分为设备ID和登录ID,所以通过login登录的用户会和之前的UUID关联上:

img

上图中events表中的anonymous_id就是调用login之前用的UUID,根据前面所说,有可能是随机生成的也有可能是openidlogin_id就是登录后的真实用户ID。

简单分析这套逻辑已经很大程度上已经实现了跨设备的用户贯通,但依然会发现有两个问题:

  • 当用户换手机后,虽然登录账号之后的行为与换手机之前的行为贯通了,但是在新设备上首次登录之前的行为仍没法贯通,仍被识别为新的用户的行为。
  • 当用户把旧手机送给朋友之后,由于旧手机已被关联到自己的登录 ID 了,无法再与朋友的登录 ID 关联。后续使用这台旧手机的用户们,若不登录就操作,则都会被识别为同一个用户(旧手机成功关联的登录 ID )。

小程序内H5关联

小程序与 H5 的数据打通,是小程序将UUID通过 URL 方式传递给 H5 端,H5 端替换该UUID,达到统一用户标识的目的。

// 页面的 wxml
<web-view src={{ url }}></web-view>

//页面的 js
Page({
    data: {        
      // 跳转的 h5 的地址
      url: ''
    },
    onLoad() {     
       // 获取匿名 ID 
       var distinctID = app.sensors.getAnonymousID();
       // 更新跳转 H5 的 url
       this.setData({ 
           url: 'https://example.com?distinctID=' + distinctID  
       })
    }
})

小程序中的H5页面:

// sensors.init 初始化代码
...
// 自行解析 url 中携带的 distinctID
var distinctID = getQueryString('distinctID');
// 修改 H5 上报数据的 distinctID 
sensors.identify(distinctID, true)
// 再执行全埋点 autoTrack 其他操作
...

H5数据关联

常规的H5也可以被称为M站,意为移动端页面,不同于小程序的一键获取手机号登录,这里就需要账号密码登录或者账号验证码登录,之前小程序登录后使用用户ID作为login_id登录神策,所以要求H5端登录后也能通过接口获取到用户ID,以此实现H5与小程序用户信息的关联。

getUserInfo().then(res => {
  sensors.login(res.id)
  sensors.bind("$identity_phone",res.phone);
})

当然如果登录的账号已经绑定过一个UUID,那么未登录时神策的自动生成的UUID,并不能关联到当前登录的账号,也就是下图中设备ID为Y的情况:

img

关联逻辑图

img

埋点事件

这里只罗列一些小程序常用的事件:

事件名称类型微信小程序H5后端事件描述
$MPLaunch神策内置小程序启动。小程序初始化完成时触发或者小程序进入后台一定时间后被微信杀死进程后再次启动小程序时触发。
$MPShow神策内置小程序显示。小程序启动时触发或者从后台切换到前台时触发。
$MPViewScreen神策内置小程序页面浏览。打开一个小程序页面时触发。
$MPHide神策内置小程序进入后台。小程序从前台进入后台。
$MPShare神策内置小程序分享。设置 Page.onShareAppMessage 这个函数后,点击小程序右上角三个点,然后点击”发送给朋友“触发上报。
$MPAddFavorites神策内置小程序收藏。
normal_click自定义常规点击事件。
skip_url自定义链接跳转。

小程序自定义事件调用方式:

App.sensors.track('skip_url', {
  label: '链接跳转',
  skipPath: 'http://xxxx',
  ...
})

H5自定义事件调用方式:

const { proxy } = getCurrentInstance();
proxy.$sensors.track('skip_url', {
	label: '链接跳转',
	skipUrl: 'http://xxxx',
  ...
})

其中第一个参数是自定义事件名,第二个参数会合并到埋点数据中的properties字段中,数据格式如下:

{
  anonymous_id: 'oyRyq**************odxA',
  distinct_id: 'oyRyq**************odxA',
  event: 'skip_url',
  identities: {
    $identity_anonymous_id: 'oyRyq**************odxA',
    $identity_mp_id: '1734508310672-15268241',
    $identity_mp_wxfe7e43282b295f06_openid: 'oyRyq**************odxA',
  },
  lib: {
    $lib: 'MiniProgram',
    $lib_method: 'code',
    $lib_version: '1.21.3',
  },
  properties: {
    $app_id: 'wx**********06',
    $brand: 'DEVTOOLS',
    $is_first_day: true,
    $latest_scene: 'wx-1001',
    $lib: 'MiniProgram',
    $lib_version: '1.21.3',
    $manufacturer: 'devtools',
    $model: 'iPhone X',
    $mp_client_app_version: '8.0.5',
    $mp_client_basic_library_version: '2.25.3',
    $network_type: 'WIFI',
    $os: 'devtools',
    $os_version: '10.0.1',
    $referrer: 'pages/index/index',
    $referrer_title: '',
    $screen_height: 812,
    $screen_width: 375,
    $timezone_offset: -480,
    $title: '',
    $url: 'pages/index/index',
    $url_path: 'pages/index/index',
    $url_query: '',
    label: '链接跳转',
    skipUrl: 'http://xxxx',
  },
  time: 1734510723364,
  type: 'track',
  _flush_time: 1734510724267,
  _track_id: 998893364,
}

到这里搞懂了神策的用户关联逻辑,就可以正常接入神策埋点,也能看懂后台埋点数据的关联逻辑了。