You need to enable JavaScript to run this app.
导航

进阶能力:多应用/多主体/多ID类型

最近更新时间2024.04.18 22:36:40

首次发布时间2024.02.27 11:24:29

一、概述
  1. 名词解释
    1. 应用:数据的基本载体,可以直接对应一个APP、网页、小程序等。
    2. 主体:数据分析的对象,例如:用户、消费者、商家、车等,用于描述事件属于谁,即是谁触发的行为。
    3. ID类型:对于分析对象的唯一标识,例如:一个自然人可以通过身份证号精准标识,但此类精准标识过于敏感,一般需要通过设备ID、邮箱、手机号、注册账号等ID近似定义一个用户。
  2. 能力简述
    经过多应用的数据融合多口径下的ID-MAPPING计算,我们可以最大程度还原出一个消费者或一个自然人,从而串联起不同主体在多个应用中的行为。

图片

二、使用场景

针对同时运营多个触点/应用的企业,在Finder目前单应用层级只能看到单端的数据,对用户分析的视角相对孤立割裂。开通此能力后,可在单一项目中汇集多个应用,实现多应用之间的汇总统计,明确真实的用户资产,分析用户跨触点全生命周期的用户旅程。例如:

  1. 在抖音业务体系下,产设研需要知道抖音本体与抖音极速版之间用户重合度如何,行为模式上是否一致,从而判断某功能是否需要做差异化设计和实现。
  2. 某DTC品牌线上维护了多个触点,在认知、兴趣、首购等不同阶段的用户需要借由不同触点设计内容和活动进行触达,用户旅程愈发复杂,营销人员需要通过跨触点的归因能力准确衡量营销效果,从而确认后续的营销动作和预算分配。
  3. 某新势力车企发力智能化,通过OTA能力上新了APP与车机大屏联动的功能,团队希望可以了解该能力是否实现了预期的联动效果,驾驶员操作是否存在断点,从而确认后续的迭代方向。

从数据模型的角度来讲,在Finder目前默认统一通过“用户”模型定义分析对象,ID体系也相对单一。针对较为复杂的业务体系,仅通过一个用户主体往往不足以描述目前的业务状态,甚至出现错误。例如:

  1. 电商等平台类APP中,用户往往需要区分商家和消费者两种身份,每一身份下有独立的ID标识,此前虽然可以通过历史的分析主体切换功能实现使用不同ID去重统计用户数,但如果存在一个用户同时是商家又是消费者,描述该用户的属性(如:信用等级)会基于最新的值覆盖,业务分析时就会出现消费者的信用等级用于描述商家的错误情况。
  2. 某银行存在零售、对公和对内员工等各位业务支持系统,各业务服务的主体之间存在不同的口径ID,但其值有可能一致,如仍使用一套ID口径会导致主体之间错误关联。例如,某员工和某对公业务的操作员的工号都是1号,如不区分主体和口径,将默认两类主体的行为都是一个“用户”触发的。

此外,针对参与埋点工作的技术人员,常见各端沿用同一套埋点设计,但目在Finder单应用视角需要分别独立维护元数据,引入了较多额外的工作和出错的风险。开通此能力后,同一项目下的应用将共享埋点方案,从而可以更优雅的实现数据管理。

二、功能开通

该功能为进阶用法,目前主针对业务相对复杂的客户按需开放。

  1. 新购Finder的客户:云原生与私有化4.5版本后可自由按需开启,默认关闭。
  2. 已购Finder的客户:仅针对使用one_id服务的环境支持开启,如需要历史数据迁移需要人工执行。

三、操作说明
  1. 应用接入:开启多应用后,进入项目中心-项目详情中时便可以看到一个项目中应用可同时绑定多个。点击编辑进入编辑状态后,下拉找到“创建应用”即可完成添加。

图片
目前主体和口径ID的配置暂未界面化,需要联系研发于后台手动配置。

  1. 数据上报:每一应用仍以appid为标识上报行为数据,而针对口径ID则需要进行特殊设置独立绑定。

Web

window.collectEvent('config', {
 user_unique_id: 'zhangsan',
 user_unique_id_type: 'testtype' // string //用户id类型
})

Mp(小程序)

$$sdk.config({
  // ...
  user_unique_id: 'zhangsan',
  user_unique_id_type: 'huoshan',//用户id类型
});

Android

@param uniqueID 用户id,如无特殊需求,请勿传 空字符串 或者 全是空格的字符串
@param type  用户id类型
AppLog.setUserUniqueID(String uuid, String uuidType)

iOS

*! @abstract UserUniqueID发生变化时设置
 @discussion 有值,则设置为ID值;登出 请调用 [BDAutoTrack clearUserUniqueID] 或者传 nil
 @discussion SDK会保存,因此只需要变化的时候设置。
 @param uniqueID 用户id,如无特殊需求,请勿传 空字符串 或者 全是空格的字符串
 @param type  用户id类型
 @return 是否成功设置或登出。
 */
- (BOOL)setCurrentUserUniqueID:(nullable NSString *)uniqueID withType:(nullable NSString *)type;

服务端

在header下使用user_unique_id_type来标记user_unique_id的口径类型

{
    "user": {
        "user_unique_id": "test_phone",
        "user_unique_id_type": "phone_id"
    },
    "header": {
        "app_id": "10000000",
        "ab_sdk_version": "91223,83097",
        "app_channel": "App Store",
        "app_package": "com.ss.android.article.news",
        "app_version": "5.1.3",
        "client_ip": "10.100.1.1",
        "device_model": "SM-G9250",
        "os_name": "Android",
        "os_version": "6.0.1",
        "custom": "{\"pub_A\":\"bbbbbbbbbb\"}"
    },
    "events": [
        {
            "ab_sdk_version": "91223,83097",
            "event": "test_event_x",
            "params": "{\"test_pro\": \"0824属性值\"}",
            "local_time_ms": 1668996744509
        }
    ]
}

通过上述方式实现了基础的口径切换,但在一些场景下,我们可以获取到主体关联的其他ID类型,为保证关联关系的准确性,我们建议实时上报口径与口径之间的关系。
举个例子,客户在登陆状态下可以获取到手机号phone_id,在绑卡之后可以获取到卡号card_id,并且在绑卡时能够获取到phone_id和card_id的关系。假设有个用户在登陆状态下获取到了phone_id1,phone_id1绑定到了ssid1上,那么所有以phone_id1进行上报的事件,都会归属于ssid1,假设在绑卡之后可以获取到card_id1,如果直接以card_id1来进行上报,由于id服务未收到任何与card_id1的关系,那么会新生成一个ssid2,用card_id1来进行上报的事件,都会归属到ssid2上。使用卡号前后的行为无法进行关联,这显然不符合预期。
因此,服务端以及客户端都提供了id_bind的方式,提前将绑定关系上报。
在使用card_id1进行上报之前,就应该调用id_bind,把phone_id1和card_id1进行绑定,card_id1也会绑定到ssid1上,之后用card_id1来进行上报的事件,都会归属到ssid1上,使用卡号前后的行为就可以进行精准关联。
id_bind的方式说明:
客户端目前只有 android/ios 在6.14.1 之后版本支持。

iOS

@interface BDAutoTrack (OneID)

- (void)bind:(NSDictionary<NSString *,NSString *> *)idmappings
  completion:(void (^)(BOOL success,NSError *error))completion;

@end

示例

NSDicitionary *idMappings = @{
    @"id_type_1":@"id_type_value_1",
    @"id_type_2":@"id_type_value_2"
}

[BDAutoTrack.sharedTrack bind:idMappings completion:^(BOOL success,
                      NSError *error) {
    if (success) {
        [BDAutoTrack.sharedTrack setCurrentUserUniqueId:@"id_type_value_1" withType:@"id_type_1"];
    }
            
}];

Android

定义

// Bind API
interface IDBindCallback {
    void onSuccess(IDBindResult result);
    void onFail(int code);
}

class IDBindResult {
    String newSsid;
    String failedIdList;
}

// AppLog
void bind(Map<String, String> identities, IDBindCallback callback);

示例

Map<String, String> ids = new HashMap<String, String>
ids.put("phone", "1230000000");
ids.put("email", "1230000000@xx.com");
AppLog.bind(ids, new IDBindCallback() {
    void onSuccess(IDBindResult result) {
        // 可选,更新本地登录态
        AppLog.setUserUniqueId()
    }
    void onFail(int code) {
        // 绑定请求失败
    }
});

服务端

服务端ID绑定通过上报特殊的事件完成:
事件名:"__id_bind"
在params中增加需要绑定的id,key为id_code,value为id的值,ssid的key固定为ssid
user_unique_id固定为__rangers。
示例:

{
    "user": {
        "user_unique_id": "__rangers"
    },
    "header": {
        "app_id": "10000000"
    },
    "events": [
        {
            "event": "__id_bind",
            "local_time_ms": 1668755974348,
            "params": {
                "finder_uid": "111",
                "phone_id": "12222",
                "ssid": "1729632945561403409"
            }
        }
    ]
}
  1. 数据管理:事件/属性等元数据统一在项目层级管理,便于管理同一业务在不同端使用同一埋点方案。

图片

  1. 数据分析:分析模式从应用粒度切换为项目+主体粒度,同项目同主体下的多个应用可以联合进行分析,同时,支持在筛选器中切换过滤应用,便于分析者更自由的构造参与分析的数据。进入分析功能后,默认查询当前项目下所有应用的汇总数据。

图片

  1. 看板与基本分析:看板以项目粒度聚合,一个看板中的图表可以是不同主体或不同app_id下创建的分析结果,便于创建全局视角的数据看板;全局筛选支持以app_id筛选,便于切换同一业务在不同端的数据表现。

图片

四、常见问题
  1. 主体和item(业务对象)有什么区别?

Finder默认的主体是用户,引入item业务对象主要解决的场景是在用户操作了某个物品时,对这个物品本身进行属性的扩充,主体本身没有发生变化,依旧是“人”。
而对于多主体,最常见的场景是区分“人”与“非人”的场景,例如:人、车,以人为主体分析行为,以车为主体分析车的行为。采用不同的主体核心原因是分析主体的ID体系不一样,就像车有车牌号、人没有车牌号;人有身份证号,但是车没有身份证号;从功能通用性上来说,我们也支持判定“司机”和“乘客”、“医生”和“患者”等作为不同的分析主体,因为他们的ID体系不一样,虽然他们都是“人”。

  1. 原来不是有分析主体吗?和这个多主体有什么区别呢?

除数据模型层面的概念外,新的主体在分析场景下主要用于快速找到与主体关联的所有应用数据,而原分析主体则仅用于确认分析时用哪一属性为标准去重计算对应的主体数。为避免产生歧义,我们已将原有的“分析主体”更名为“统计口径”。

五、视频解读