创建简短的推荐人链接
生成简短、可共享的推荐人链接,以实现用户到用户归因并跟踪来自有机推荐的应用程序安装。
版本要求:此功能需要 2.0.6 或更高版本的 SDK。短链接在创建后 30 天内保持有效。
概述
什么是推荐人短链接
短链接将冗长、充满参数的奇异链接转换为简洁、安全的 URL,便于通过短信、社交媒体或应用程序内的邀请进行分享。
动态创建短链接,以便用户与朋友分享,邀请他们下载和使用您的应用程序。每个短链接都会跟踪推荐用户,使您能够衡量病毒式增长,并将新安装归功于特定的拥护者。
实施要求
所需组件
在创建推荐人短链接之前,请先收集这些元素:
- 单一链接:引导用户下载应用程序的基本跟踪链接。有关设置说明,请参阅奇异链接常见问题
- 动态参数:用于为链接添加上下文的可选自定义参数。查看跟踪链接参数中的可用选项
- 推荐人信息:分享链接的用户的姓名和 ID,以便将新安装归因于推荐人
SDK 实现
注册短链接代理
在字符类构造函数中配置委托回调处理程序,以接收短链接创建结果。
// 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(可以为空
使用示例
创建一个带有自定义参数的短链接,并在委托回调中处理响应。
// 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 天后失效。对于长期活动或持续分享功能,请定期生成新的短链接,或使用完整的奇异链接作为备用。
常用案例
应用内推荐计划
让用户可以通过个性化推荐链接直接从应用中邀请朋友。
- 奖励系统:跟踪推荐并奖励成功注册朋友的用户
- 社交分享:与短信、社交媒体和消息应用程序的平台原生共享功能集成
- 个人邀请:在共享信息中包含推荐人姓名,实现个性化
// 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);
}
用户生成的内容
当用户生成想要与他人分享的内容时,创建可分享链接。
- 内容归因:跟踪哪些内容推动了最多的应用安装
- 创作者识别:将新用户归属于内容创作者,实现游戏化
- 活动标签:根据内容类型或类别添加动态参数
// 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 和详细信息
- 与会者跟踪:衡量活动之间的病毒传播
- 网络效应:识别转换率最高的活动
// 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 共享。
#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++ 可调用方法。