짧은 리퍼러 링크 생성하기
사용자 간 어트리뷰션을 가능하게 하는 공유 가능한 짧은 리퍼러 링크를 생성하고 오가닉 추천을 통해 앱 설치를 추적하세요.
버전 요구 사항: 이 기능을 사용하려면 SDK 버전 1.0.7 이상이 필요합니다. 짧은 링크는 생성 후 30일 동안 활성 상태로 유지됩니다.
개요
짧은 리퍼러 링크란?
짧은 링크는 매개변수로 가득 찬 긴 Singular 링크를 SMS, 소셜 미디어 또는 인앱 초대를 통해 공유하기 편리한 작고 안전한 URL로 변환합니다.
짧은 링크를 동적으로 생성하여 사용자가 친구와 공유하여 앱을 다운로드하고 사용하도록 초대할 수 있습니다. 각 짧은 링크는 추천한 사용자를 추적하여 바이럴 성장을 측정하고 특정 지지자에게 신규 설치를 할당할 수 있습니다.
구현 요구 사항
필수 구성 요소
짧은 리퍼러 링크를 만들기 전에 다음 요소를 수집하세요:
- Singular 링크: 사용자를 앱 다운로드로 안내하는 기본 추적 링크입니다. 설정 지침은 Singular 링크 FAQ를 참조하세요.
- 동적 파라미터: 링크에 컨텍스트를 추가하기 위한 선택적 사용자 지정 매개변수입니다. 추적 링크 파라미터에서사용 가능한 옵션 보기
- 리퍼러 정보: 링크를 공유하는 사용자의 이름과 ID로, 신규 인스톨을 리퍼러에게 어트리뷰션할 수 있도록 합니다.
SDK 메서드
리퍼러 쇼트링크 생성
사용자 지정 파라미터와 성공 및 오류 상태에 대한 콜백 핸들러가 포함된 짧은 리퍼러 링크를 생성합니다.
메서드 서명:
static void createReferrerShortLink(
String baseLink,
String referrerName,
String referrerId,
Map<String, String> passthroughParams,
void Function(String? shortLinkURL, String? error) completionHandler
)
파라미터:
- baseLink: 원본 Singular 추적 링크 URL
- referrerName: 추천 사용자의 표시 이름
- referrerId: 추천 사용자의 고유 식별자
- 패스스루 파라미터: 추가 동적 매개변수가 포함된 맵(없는 경우 빈 맵 전달)
-
완료 핸들러: 파라미터가 포함된 콜백 함수
(String? shortLinkURL, String? error)
전체 메서드 문서는 createReferrerShortLink 참조를 참조하세요.
기본 사용 예시
사용자 정의 매개변수를 사용하여 짧은 링크를 만들고 성공 콜백에서 공유 로직을 구현합니다.
import 'package:flutter/material.dart';
import 'package:singular_flutter_sdk/singular.dart';
import 'package:share_plus/share_plus.dart';
class ReferralScreen extends StatelessWidget {
void handleShareReferral() {
// Create custom parameters for the link
final parameters = {
'channel': 'sms',
'campaign_id': 'summer_promo_2025',
'referral_type': 'friend_invite'
};
// Generate the short referrer link
Singular.createReferrerShortLink(
'https://sample.sng.link/D52wc/cuvk?pcn=test', // Base Singular Link
'John Doe', // Referrer name
'user_12345', // Referrer ID
parameters, // Custom parameters
(shortLink, error) {
if (error != null) {
// Error occurred during link creation
print('Error creating short link: $error');
_showErrorDialog('Failed to create share link. Please try again.');
} else if (shortLink != null) {
// Success - short link was created
print('Generated short link: $shortLink');
// Share the link using share_plus package
shareLink(shortLink);
}
}
);
}
void shareLink(String shortLink) {
try {
Share.share(
'Join me on this awesome app! $shortLink',
subject: 'App Invitation'
);
print('Link shared successfully');
} catch (error) {
print('Error sharing link: $error');
_showErrorDialog('Failed to share link');
}
}
void _showErrorDialog(String message) {
// Your dialog implementation
print('Error: $message');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Referral')),
body: Center(
child: ElevatedButton(
onPressed: handleShareReferral,
child: Text('Share Referral Link'),
),
),
);
}
}
고급 구현
재시도 로직, 로딩 상태 및 클립보드 폴백을 사용하여 완전한 리퍼럴 시스템을 구현하세요.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:singular_flutter_sdk/singular.dart';
import 'package:share_plus/share_plus.dart';
class ReferralManager extends StatefulWidget {
final String userId;
final String userName;
final String baseLink;
const ReferralManager({
Key? key,
required this.userId,
required this.userName,
required this.baseLink,
}) : super(key: key);
@override
_ReferralManagerState createState() => _ReferralManagerState();
}
class _ReferralManagerState extends State<ReferralManager> {
bool _isGenerating = false;
String? _lastGeneratedLink;
Future<String> _generateShortLink({int retryCount = 0}) async {
final parameters = {
'channel': 'in_app',
'campaign_id': 'organic_referral',
'user_tier': 'premium',
'referral_timestamp': DateTime.now().millisecondsSinceEpoch.toString()
};
final completer = Completer<String>();
Singular.createReferrerShortLink(
widget.baseLink,
widget.userName,
widget.userId,
parameters,
(shortLink, error) async {
if (error != null) {
// Retry logic with exponential backoff
if (retryCount < 3) {
final delay = Duration(seconds: (1 << retryCount)); // 1s, 2s, 4s
print('Retrying in ${delay.inSeconds}s... (Attempt ${retryCount + 1}/3)');
await Future.delayed(delay);
try {
final result = await _generateShortLink(retryCount: retryCount + 1);
completer.complete(result);
} catch (e) {
completer.completeError(e);
}
} else {
completer.completeError(Exception(error));
}
} else if (shortLink != null) {
setState(() {
_lastGeneratedLink = shortLink;
});
completer.complete(shortLink);
} else {
completer.completeError(Exception('Unknown error occurred'));
}
}
);
return completer.future;
}
Future<void> _handleShare() async {
setState(() {
_isGenerating = true;
});
try {
final shortLink = await _generateShortLink();
print('Short link generated: $shortLink');
// Attempt to share
await Share.share(
'${widget.userName} invited you to join! $shortLink',
subject: 'App Invitation from ${widget.userName}'
);
// Track share event
Singular.event('referral_link_shared');
print('Link shared successfully');
} catch (error) {
print('Error in share flow: $error');
// Fallback: Copy to clipboard if available
if (_lastGeneratedLink != null) {
await Clipboard.setData(ClipboardData(text: _lastGeneratedLink!));
_showDialog(
'Link Copied',
'Failed to share, but the referral link has been copied to your clipboard!',
);
} else {
_showDialog(
'Error',
'Failed to generate referral link. Please check your connection and try again.',
);
}
} finally {
setState(() {
_isGenerating = false;
});
}
}
Future<void> _copyToClipboard() async {
if (_lastGeneratedLink != null) {
await Clipboard.setData(ClipboardData(text: _lastGeneratedLink!));
_showDialog('Copied!', 'Referral link copied to clipboard');
} else {
_showDialog('No Link', 'Please generate a link first');
}
}
void _showDialog(String title, String message) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(title),
content: Text(message),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('OK'),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_isGenerating)
CircularProgressIndicator()
else ...[
ElevatedButton(
onPressed: _handleShare,
child: Text('Share Referral Link'),
),
if (_lastGeneratedLink != null) ...[
SizedBox(height: 16),
OutlinedButton(
onPressed: _copyToClipboard,
child: Text('Copy Link'),
),
],
],
],
);
}
}
구현 모범 사례
오류 처리
콜백에서 강력한 오류 처리를 구현하여 네트워크 장애, 잘못된 매개변수 또는 서버 문제를 관리하세요.
- 재시도 로직: 일시적인 네트워크 오류에 대한 지수 백오프를 구현하세요.
- 사용자 피드백: 링크 생성 실패 시 명확한 오류 메시지 표시
- 폴백 옵션: 대체 공유 방법 제공(예: 짧은 링크 생성에 실패한 경우 전체 Singular 링크 공유)
-
유효성 검사:
createReferrerShortLink으로 호출하기 전에 매개변수를 확인하여 문제를 조기에 포착하세요.
추적 및 분석
리퍼러 정보를 활용하여 바이럴 루프를 구축하고 유기적 성장을 측정하세요.
모범 사례: 내부 사용자 식별 시스템과 일치하는 일관된 리퍼러 ID를 사용하세요. 이를 통해 다음을 수행할 수 있습니다:
- 특정 추천 사용자에게 신규 설치 속성 부여
- 성공적인 추천에 대해 사용자에게 보상 제공
- 바이럴 계수 및 K-요인 지표 추적
- 가장 가치 있는 브랜드 옹호자 식별
링크 만료
공유 전략에서 30일의 링크 수명 주기를 계획하세요.
중요: 짧은 링크는 30일 후에 만료됩니다. 장기 캠페인 또는 지속적인 공유 기능의 경우 주기적으로 새로운 짧은 링크를 생성하거나 전체 Singular 링크를 대체로 사용하세요.
일반적인 사용 사례
인앱 추천 프로그램
맞춤화된 추천 링크를 통해 사용자가 앱에서 직접 친구를 초대할 수 있도록 하세요.
- 보상 시스템: 추천을 추적하고 성공적인 친구 가입에 대해 사용자에게 보상을 제공하세요.
- 소셜 공유: SMS, WhatsApp, 이메일, 소셜 미디어용 share_plus 패키지와 연동하세요.
- 개인 초대: 개인 맞춤화를 위해 공유 메시지에 추천인 이름을 포함하세요.
사용자 생성 콘텐츠
사용자가 다른 사람들과 공유하고 싶은 콘텐츠를 생성할 때 공유 가능한 링크를 생성하세요.
- 콘텐츠 어트리뷰션: 어떤 콘텐츠가 가장 많은 앱 설치를 유도하는지 추적하세요.
- 크리에이터 인식: 게임화를 위해 신규 사용자를 콘텐츠 크리에이터에게 어트리뷰션하세요.
- 캠페인 태깅: 콘텐츠 유형 또는 카테고리에 따라 동적 파라미터 추가
이벤트 초대
이벤트 초대를 위한 고유 링크를 생성하여 어떤 참석자가 신규 사용자를 데려왔는지 추적할 수 있습니다.
- 이벤트 컨텍스트: 링크 매개변수에 이벤트 ID 및 세부 정보를 포함하세요.
- 참석자 추적: 이벤트에서 이벤트로의 바이럴 확산 측정
- 네트워크 효과: 전환율이 가장 높은 이벤트 식별