Skip to content

Codename One 推出邀请归因功能:让邀请码穿越安装流程 ​

译注:本文编译自 dev.to 平台 Codename One 官方博客文章《The Hard Part of Invite a Friend Is the Install》,原文链接见文末。Codename One 是一个开源框架,支持用单一 Java 或 Kotlin 代码库构建原生 iOS、Android、桌面和 Web 应用。

你花 100 美元为应用投放广告,如何判断这笔钱花得值?广告平台能统计点击量,但你需要知道点击之后发生了什么:这些人安装了吗?使用了吗?有人付费吗?缺少这层关联,你可能持续把钱投在几乎带不来业务的广告上。

邀请功能面临同样的问题。用户把链接分享给朋友,朋友可能要先经过应用商店,你的应用才能接收到任何信息。如果邀请码在安装过程中丢失,后续的注册或购买就与最初那次邀请失去了关联。

有些公司的整个产品就建立在这个缺口之上。Codename One 本周发布的版本把邀请流程内置到框架中,让一个精确的邀请码穿越安装过程,并接入现有的分析体系。在获得分析授权的前提下,后续的转化和购买事件会保留邀请所属的 campaign 和 channel,从而追踪点击之后发生的一切。

难点在于让同一个邀请码通过每一次交接。链接会从你的应用传到即时通讯应用,再传到浏览器或已安装的应用。如果中间隔着安装环节,邀请码也必须存活下来。这就像一场不断更换场地的排球赛。

在用户所在之处创建邀请 ​

使用 com.codename1.analytics.invite:

java
Invite invite = Invites.create(InviteRequest.create()
        .campaign("team-launch")
        .channel("share_sheet")
        .title("Join our team")
        .description("Keep the team's work in one place.")
        .build());

Invites.share(invite, "Come and try this with me");

创建操作立即返回,离线时也是如此。应用在本地生成邀请码,并在后台向链接服务注册。分享面板不会等待该请求完成。

分析层面的区分很重要:打开分享面板不等于完成分享。当平台确认分享时,流程上报 invite_shared;取消则上报 invite_share_dismissed。如果你用自己的 UI 发送邀请,请在分享回调中通过 Invites.reportShareResult() 上报结果。

通往同一邀请码的三条路径 ​

Android 有 install-referrer 路径,邀请码经过 Play 商店后返回已安装的应用。

App Store 不提供对应的参数。在 iOS 上,生成的 App Clip 接收邀请 URL,把邀请码存入共享的 App Group,并引导用户安装完整应用。安装完成后,应用读取这一交接信息。App Clip 是一个自动生成的小型 UIKit 应用,你无需为它维护第二套 Codename One UI。

归因结果会报告邀请码的到达方式:

匹配类型交接方式
MATCH_DIRECT链接直接打开了已安装的应用。
MATCH_REFERRERAndroid 通过 install referrer 返回邀请码。
MATCH_APP_CLIPiOS App Clip 把邀请码传递给完整应用。

三种方式都携带精确的邀请码,无需用设备指纹去猜测哪次安装对应哪次点击。精确归因负责识别邀请来源,而账号是否符合奖励条件仍由你的服务器决定。

在应用启动时接收邀请 ​

注册监听器,并在应用的 start() 流程中调用 checkForInvite():

java
Invites.setInviteListener(new InviteListener() {
    public void inviteReceived(InviteAttribution attribution) {
        showInvitedWelcome(attribution.getCampaign());
    }

    public void attributionUnavailable(String reason) {
        showOrdinaryWelcome();
    }
});
Invites.checkForInvite();

两个 show... 方法是应用自身的 UI 方法。没有邀请的安装是正常结果。该 API 每次安装只向监听器交付一个最终结果,并会保留早期结果直到监听器可用——这在冷启动时很重要,因为链接处理可能在你的 UI 注册之前就已完成。

Android 可以通过替换 Activity 的 intent 传递链接,iOS 则使用其启动属性路径。在 start() 中主动拉取,让应用代码只需在一个地方检查这两种情况。

完成平台配置 ​

当应用引用邀请包时,构建过程会自动加入原生接线:Android App Links 与 Play Install Referrer 依赖、iOS 关联域名,以及生成的 App Clip。

有些账号侧设置无法由构建自动完成。请在 Codename One 控制台完成邀请设置,并使用其链接前缀配置 Apple 的 App Clip Experience。

对于 Android,将已安装应用的签名 SHA-256 填入以下构建提示:

properties
codename1.arg.android.invite.signingFingerprint=YOUR_APP_SIGNING_SHA256

在 Play App Signing 下,这里应填 Play Console 中的 app-signing 证书,而非你的上传证书。App Links 验证检查的是设备上 APK 的签名。

对于 iOS:

properties
codename1.arg.ios.invite.appStoreId=YOUR_NUMERIC_APP_STORE_ID

在你的 App ID 上启用 Associated Domains 和 App Clip。注册生成的 app 与 clip 所使用的 App Group,并确保描述文件包含它。构建器会从包名派生一个 group,ios.invite.appGroup 可让你选择已注册的现有 group。

最后,在 App Store Connect 中为控制台显示的邀请前缀注册 Advanced App Clip Experience。授权域名和将 URL 映射到 App Clip 是两个独立步骤。没有该 Experience,链接不会展示预期的 clip 卡片。

如果你已经发布了自己的 App Clip,可用 ios.invite.appClip=false 禁用生成。此时你的 clip 需要写入预期的交接信息。Analytics 指南的邀请章节涵盖了相关构建提示与生命周期。

归因安装之后发生的事 ​

归因解析完成后,分析上下文会携带 cn1_campaign、cn1_channel、cn1_invite_code 和 cn1_invite_match。后续事件会继承这些维度,包括框架的购买事件。

对于其他业务里程碑,在转化实际发生时上报:

java
Invites.conversion("first_project_created");

这样你可以区分“带来安装的邀请”和“带来实际使用的邀请”。如果框架的购买事件已经代表同一行为,请避免重复计入显式的购买转化。

采集与上报遵循分析授权类别。Analytics.resetClientId() 会连同身份一起清除邀请归因,使新的 client ID 不会继续通过旧的推荐关系被关联。将归因窗口设为零会停止延迟查找,但仍允许链接已直接送达的精确邀请码。

少维护一层平台中转 ​

PR #5751 把链接、安装交接、生命周期处理和分析上下文整合在一起。按钮只是可见的部分;平台中转才是框架替你承担的工作。

结合本周的 vault 与后端工作,这让我们又多了一个把更安全的实现变成更便捷实现的场景:传递邀请码而非指纹;传输前先获得授权;身份重置时清除归因;奖励授权保留在服务器端。这些决策应当能跨越平台迁移而继续成立。

原文链接 ​

https://dev.to/codenameone/the-hard-part-of-invite-a-friend-is-the-install-5a72