虚幻引擎 SDK - 支持推荐人短链接

文档

创建简短的推荐人链接

生成简短、可共享的推荐人链接,以实现用户到用户归因并跟踪来自有机推荐的应用程序安装。

版本要求:此功能需要 2.0.6 或更高版本的 SDK。短链接在创建后 30 天内保持有效。

概述

什么是推荐人短链接

短链接将冗长、充满参数的奇异链接转换为简洁、安全的 URL,便于通过短信、社交媒体或应用程序内的邀请进行分享。

动态创建短链接,以便用户与朋友分享,邀请他们下载和使用您的应用程序。每个短链接都会跟踪推荐用户,使您能够衡量病毒式增长,并将新安装归功于特定的拥护者。


实施要求

所需组件

在创建推荐人短链接之前,请先收集这些元素:

  • 单一链接:引导用户下载应用程序的基本跟踪链接。有关设置说明,请参阅奇异链接常见问题
  • 动态参数:用于为链接添加上下文的可选自定义参数。查看跟踪链接参数中的可用选项
  • 推荐人信息:分享链接的用户的姓名和 ID,以便将新安装归因于推荐人

SDK 实现

注册短链接代理

在字符类构造函数中配置委托回调处理程序,以接收短链接创建结果。

C++
// Add to your character header file (.h)
#include "SingularDelegates.h"

// Declare delegate pointer and callback method
USingularDelegates* SingularDelegates;

UFUNCTION()
void OnSingularShortLinkResolved(const FSingularShortLinkParams& LinkParams);

// In your character implementation file (.cpp)
// Register the delegate in the constructor
AYourCharacter::AYourCharacter()
{
    if (SingularDelegates == nullptr)
    {
        // Create and register the delegate handler
        SingularDelegates = CreateDefaultSubobject<USingularDelegates>(
            TEXT("SingularShortLinksHandler")
        );

        SingularDelegates->OnSingularShortLinksResolved.AddDynamic(
            this, 
            &AYourCharacter::OnSingularShortLinkResolved
        );

        UE_LOG(LogTemp, Log, TEXT("Short link delegate registered"));
    }
}

// Implement the callback method
void AYourCharacter::OnSingularShortLinkResolved(const FSingularShortLinkParams& LinkParams)
{
    // Extract the short link URL or error message
    const FString ShortLinkURL = LinkParams.SingularShortLinksParams["data"];
    const FString ErrorMessage = LinkParams.SingularShortLinksParams["error"];

    if (!ShortLinkURL.IsEmpty())
    {
        // Success - short link was created
        UE_LOG(LogTemp, Log, TEXT("Generated short link: %s"), *ShortLinkURL);

        // Share the link using your preferred sharing method
        ShareLinkWithUser(ShortLinkURL);
    }
    else if (!ErrorMessage.IsEmpty())
    {
        // Error occurred during link creation
        UE_LOG(LogTemp, Error, TEXT("Short link error: %s"), *ErrorMessage);

        // Implement retry logic or show error to user
        HandleShortLinkError(ErrorMessage);
    }
}

重要:在创建任何短链接之前,请在类构造函数中注册委托处理程序。回调处理程序要么在 "data "字段中接收成功的短链接 URL,要么在 "error "字段中接收错误信息,但绝不会同时接收这两种信息。


创建短链接

使用CreateReferrerShortLink 方法生成带有自定义参数的短链接。

方法签名

static void CreateReferrerShortLink(
    FString baseLink, 
    FString referrerName, 
    FString referrerId, 
    TMap<FString, FString> args
)

参数

  • baseLink:原始奇异跟踪链接 URL
  • referrerName:引用用户的显示名称:引用用户的显示名称
  • referrerId:引用用户的唯一标识符
  • args:包含附加动态参数的 TMap(可以为空

使用示例

创建一个带有自定义参数的短链接,并在委托回调中处理响应。

C++
// Example: User clicks "Invite Friends" button
void AYourCharacter::OnInviteFriendsClicked()
{
    // Add custom parameters to the link
    TMap<FString, FString> LinkParameters;
    LinkParameters.Add(TEXT("channel"), TEXT("sms"));
    LinkParameters.Add(TEXT("campaign_id"), TEXT("summer_referral_2025"));
    LinkParameters.Add(TEXT("referral_type"), TEXT("friend_invite"));

    // Create the short referrer link
    USingularSDKBPLibrary::CreateReferrerShortLink(
        TEXT("https://sample.sng.link/B4tbm/v8fp?_dl=https%3A%2F%2Fmyapp.com"),  // Base link
        TEXT("John Doe"),                                                         // Referrer name
        TEXT("user_12345"),                                                       // Referrer ID
        LinkParameters                                                            // Custom parameters
    );

    UE_LOG(LogTemp, Log, TEXT("Short link creation requested"));
}

// Handle successful link creation
void AYourCharacter::ShareLinkWithUser(const FString& ShortLinkURL)
{
    // Example: Show share UI with the short link
    FString ShareMessage = FString::Printf(
        TEXT("Join me in this awesome game! %s"), 
        *ShortLinkURL
    );

    // Platform-specific sharing implementation
    #if PLATFORM_ANDROID
        ShareOnAndroid(ShareMessage);
    #elif PLATFORM_IOS
        ShareOnIOS(ShareMessage);
    #else
        // Fallback: Copy to clipboard
        FPlatformApplicationMisc::ClipboardCopy(*ShortLinkURL);
        UE_LOG(LogTemp, Log, TEXT("Link copied to clipboard: %s"), *ShortLinkURL);
    #endif
}

// Handle link creation errors
void AYourCharacter::HandleShortLinkError(const FString& ErrorMessage)
{
    // Log the error
    UE_LOG(LogTemp, Warning, TEXT("Short link failed: %s"), *ErrorMessage);

    // Retry logic for transient errors
    if (ErrorMessage.Contains(TEXT("network")) || ErrorMessage.Contains(TEXT("timeout")))
    {
        // Retry after delay
        FTimerHandle RetryTimer;
        GetWorldTimerManager().SetTimer(
            RetryTimer,
            this,
            &AYourCharacter::OnInviteFriendsClicked,
            2.0f,  // Retry after 2 seconds
            false
        );
    }
    else
    {
        // Show error message to user
        ShowErrorMessage(TEXT("Unable to create share link. Please try again later."));
    }
}

最佳实践:包含有意义的自定义参数,帮助您分析哪些分享渠道和营销活动能带来最多的安装量。使用与内部用户识别系统一致的推荐人 ID,以便准确归因。


实施最佳实践

错误处理

在回调中实施强大的错误处理功能,以管理网络故障、无效参数或服务器问题。

  • 重试逻辑:针对瞬时网络错误实施指数回退
  • 用户反馈:链接创建失败时显示清晰的错误信息
  • 回退选项:提供其他共享方式(例如,如果短链接创建失败,则共享完整的奇异链接
  • 验证:在调用CreateReferrerShortLink 之前验证参数,以便及早发现问题

网络依赖性:创建短链接需要激活互联网连接。始终从容应对网络故障,并在链接创建失败时向用户提供反馈。


跟踪和分析

利用推荐人信息建立病毒循环并衡量有机增长。

病毒式增长指标:使用一致的推荐人 ID

  • 将新安装归因于特定的推荐用户
  • 奖励成功推荐的用户
  • 跟踪病毒系数和 K 因子指标
  • 识别最有价值的品牌拥护者

链接过期

在分享策略中规划 30 天的链接生命周期。

重要:短链接在 30 天后失效。对于长期活动或持续分享功能,请定期生成新的短链接,或使用完整的奇异链接作为备用。


常用案例

应用内推荐计划

让用户可以通过个性化推荐链接直接从应用中邀请朋友。

  • 奖励系统:跟踪推荐并奖励成功注册朋友的用户
  • 社交分享:与短信、社交媒体和消息应用程序的平台原生共享功能集成
  • 个人邀请:在共享信息中包含推荐人姓名,实现个性化
C++
// Example: Referral reward system
void AReferralManager::ProcessSuccessfulReferral(const FString& ReferrerId, const FString& NewUserId)
{
    // Track the referral event
    TMap<FString, FString> ReferralData;
    ReferralData.Add(TEXT("referrer_id"), ReferrerId);
    ReferralData.Add(TEXT("new_user_id"), NewUserId);
    ReferralData.Add(TEXT("referral_source"), TEXT("in_app_share"));

    USingularSDKBPLibrary::SendEventWithArgs(TEXT("referral_success"), ReferralData);

    // Award reward to referring user
    AwardReferralReward(ReferrerId);

    UE_LOG(LogTemp, Log, TEXT("Referral processed: %s referred %s"), *ReferrerId, *NewUserId);
}

用户生成的内容

当用户生成想要与他人分享的内容时,创建可分享链接。

  • 内容归因:跟踪哪些内容推动了最多的应用安装
  • 创作者识别:将新用户归属于内容创作者,实现游戏化
  • 活动标签:根据内容类型或类别添加动态参数
C++
// Example: Share user-generated content
void AContentManager::ShareUserContent(const FString& ContentId, const FString& CreatorId, const FString& CreatorName)
{
    // Add content-specific parameters
    TMap<FString, FString> ContentParams;
    ContentParams.Add(TEXT("content_id"), ContentId);
    ContentParams.Add(TEXT("content_type"), TEXT("custom_level"));
    ContentParams.Add(TEXT("share_source"), TEXT("ugc_gallery"));

    // Create short link with content creator as referrer
    USingularSDKBPLibrary::CreateReferrerShortLink(
        TEXT("https://mygame.sng.link/Ab3d/cdef?_dl=mygame://content"),
        CreatorName,
        CreatorId,
        ContentParams
    );
}

活动邀请

为活动邀请函生成唯一链接,跟踪哪些与会者带来了新用户。

  • 活动背景:在链接参数中包含活动 ID 和详细信息
  • 与会者跟踪:衡量活动之间的病毒传播
  • 网络效应:识别转换率最高的活动
C++
// Example: Share event invitation
void AEventManager::InviteToEvent(const FString& EventId, const FString& EventName, const FString& HostId, const FString& HostName)
{
    // Add event-specific parameters
    TMap<FString, FString> EventParams;
    EventParams.Add(TEXT("event_id"), EventId);
    EventParams.Add(TEXT("event_name"), EventName);
    EventParams.Add(TEXT("event_date"), GetEventDateString(EventId));
    EventParams.Add(TEXT("invite_type"), TEXT("host_invite"));

    // Create short link with event host as referrer
    USingularSDKBPLibrary::CreateReferrerShortLink(
        TEXT("https://mygame.sng.link/Ev2nt/wxyz?_dl=mygame://event"),
        HostName,
        HostId,
        EventParams
    );

    UE_LOG(LogTemp, Log, TEXT("Event invitation link created for: %s"), *EventName);
}

特定平台共享

安卓共享实现

使用 JNI 来调用系统共享表单,实现本地 Android 共享。

C++
#if PLATFORM_ANDROID
void AYourCharacter::ShareOnAndroid(const FString& Message)
{
    if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
    {
        // Get the Intent class
        jclass IntentClass = FAndroidApplication::FindJavaClass("android/content/Intent");

        // Create Intent with ACTION_SEND
        jfieldID ActionSendField = Env->GetStaticFieldID(IntentClass, "ACTION_SEND", "Ljava/lang/String;");
        jobject ActionSend = Env->GetStaticObjectField(IntentClass, ActionSendField);

        jmethodID IntentConstructor = Env->GetMethodID(IntentClass, "<init>", "()V");
        jobject IntentObject = Env->NewObject(IntentClass, IntentConstructor);

        // Set action and type
        jmethodID SetActionMethod = Env->GetMethodID(IntentClass, "setAction", "(Ljava/lang/String;)Landroid/content/Intent;");
        Env->CallObjectMethod(IntentObject, SetActionMethod, ActionSend);

        jmethodID SetTypeMethod = Env->GetMethodID(IntentClass, "setType", "(Ljava/lang/String;)Landroid/content/Intent;");
        jstring TypeString = Env->NewStringUTF("text/plain");
        Env->CallObjectMethod(IntentObject, SetTypeMethod, TypeString);

        // Add the message
        jmethodID PutExtraMethod = Env->GetMethodID(IntentClass, "putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;");
        jfieldID ExtraTextField = Env->GetStaticFieldID(IntentClass, "EXTRA_TEXT", "Ljava/lang/String;");
        jobject ExtraText = Env->GetStaticObjectField(IntentClass, ExtraTextField);
        jstring MessageString = Env->NewStringUTF(TCHAR_TO_UTF8(*Message));
        Env->CallObjectMethod(IntentObject, PutExtraMethod, ExtraText, MessageString);

        // Create chooser and start activity
        jmethodID CreateChooserMethod = Env->GetStaticMethodID(IntentClass, "createChooser", "(Landroid/content/Intent;Ljava/lang/CharSequence;)Landroid/content/Intent;");
        jstring ChooserTitle = Env->NewStringUTF("Share via");
        jobject ChooserIntent = Env->CallStaticObjectMethod(IntentClass, CreateChooserMethod, IntentObject, ChooserTitle);

        // Start the activity
        FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "startActivity", "(Landroid/content/Intent;)V", false), ChooserIntent);

        // Cleanup
        Env->DeleteLocalRef(IntentClass);
        Env->DeleteLocalRef(ActionSend);
        Env->DeleteLocalRef(IntentObject);
        Env->DeleteLocalRef(TypeString);
        Env->DeleteLocalRef(MessageString);
        Env->DeleteLocalRef(ExtraText);
        Env->DeleteLocalRef(ChooserTitle);
        Env->DeleteLocalRef(ChooserIntent);

        UE_LOG(LogTemp, Log, TEXT("Android share dialog opened"));
    }
}
#endif

iOS 共享实现

使用 Objective-C++ 实现本地 iOS 共享,以呈现 UIActivityViewController。

实现注意事项:iOS 共享需要 Objective-C++ 实现。为特定平台代码创建单独的 .mm 文件,并公开 C++ 可调用方法。