마케팅 어트리뷰션(Hive 사용자 추적 툴)은 Adjust, Singular, AppsFlyer를 동시에 적용하기 쉽도록 묶어 놓은 패키지이다. 프로젝트 별로 적용 여부를 따진 후, 각 모듈 별로 키를 발급해 적용한다.
- Adjust: https://www.adjust.com
- Singular: https://app.singular.net
- AppsFlyer: https://hq1.appsflyer.com/
Key 설정을 위해 마케팅 어트리뷰션 툴 가이드를 참고하세요.
기본으로 지원하는 기능은 아래와 같다.
- 게임 내 이벤트 추적
- 과금 추적
Tracking Module Initialize
- 모듈의 키 값과 이벤트 키 값을 설정
- 최초 모듈 초기화 시 발급받은 키 값을 입력하거나 Unity의 경우 키 값을 입력할 인스펙터를 제공함
필수 발급 키 값
- Adjust는 기본 Update와 Purchase, TutorialComplete용 키 값 발급 필요
- Singular는 별도의 키 값을 발급할 필요 없이 코드에 추가해서 사용
TutorialComplete를 제외한 다른 값(Purchase, Install, Open, Update)은 모듈에서 호출하기 때문에 게임 내에서는 호출하지 않아야 한다. 단, Adjust의 경우 Update에 대한 키 값을 발급받아 클라이언트에서 따로 키 값을 추가해주어야 한다.
트래킹 모듈의 키 값 설정 시 Adjust는 발급받은 이벤트 토큰(Token) 값을 입력해야 한다. Singular는 Singular 콘솔 페이지에서 별도 발급 및 추가 없이 코드에서 원하는 키 값을 추가하여 사용하면 해당 키 값이 집계된다.
C2SModuleTracker_SendEvent
이벤트를 전송한다.
argument type | type | desc | platform | 비고 |
---|---|---|---|---|
event | string | 이벤트 이름은 Initialize에서 Matching에 설정한 키로 사용 |
all | 1.5.0 |
revenue | Dictionary (unity) | 설정할 경우 수익 측정 이벤트를 발생 | all | 1.5.0 |
key-value for revenue
argument type | type | desc | platform | 비고 |
---|---|---|---|---|
title | string | (필수) 상품 이름 | all | 1.5.0 |
description | string | (필수) 상품 설명 | all | 1.5.0 |
currency | string | (필수) 통화 코드 (https://en.wikipedia.org/wiki/ISO_4217) 규격에 맞게 입력 (대문자로 사용) |
all | 1.5.0 |
price | string | (필수) 상품 가격 (float 형태) | all | 1.5.0 |
itemCount | int | (필수) 상품 개수 | all | 1.5.0 |
transactionId | string | 중복구매방지 refId 안드로이드 : order Id iOS : (영수증 검증 이후의) transactionId |
all | 1.11.3+ |
Returns
YES일 경우 성공, NO일 경우 실패
C2SModuleTracker_SetEnable
Tracker의 이벤트 전송에 대한 활성화 여부를 설정한다.
argument type | type | desc | platform | 비고 |
---|---|---|---|---|
Adjust | bool | Adjust모듈의 이벤트 전송 활성화 여부 | all | 1.5.0 |
Singular | bool | Singular모듈의 이벤트 전송 활성화 여부 | all | 1.5.0 |
AppsFlyer | bool | AppsFlyer모듈의 이벤트 전송 활성화 여부 | all | 1.19.8+ |
Returns
YES일 경우 성공, NO일 경우 실패
샘플 코드
public static bool C2SModule.Tracker.SendEvent(C2SModule.Parameter arg, out C2SModule.Error error,
C2SModule.CompletionHandler completionHandler);
– 사용자 추적툴 이벤트 발생
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[일반 이벤트 사용시] C2SModule.Error error; C2SModule.Parameter arg; arg["event"] = "TutorialComplete"; if( !C2SModule.Tracker.SendEvent( arg, out error ) ) { // Error 시 처리 } [수익 측정 이벤트 사용시] C2SModule.Error error; Dictionary<string,object> revenueArg = new Dictionary<string,object>(); revenueArg["title"] = "item1"; revenueArg["description"] = "item1 desc"; revenueArg["currency"] = "USD"; revenueArg["price"] = "0.99"; revenueArg["itemCount"] = 1; C2SModule.Parameter arg; arg["event"] = "Purchase"; //< 사전 정의된 이벤트 이름. arg["revenue"] = revenueArg; if( !C2SModule.Tracker.SendEvent( arg, out error ) ) { // Error 시 처리 } |
public static bool C2SModule.Tracker.SetEnable(C2SModule.Parameter arg, out C2SModule.Error error,
C2SModule.CompletionHandler completionHandler);
– 사용자 추적툴 사용여부 설정
1 2 3 4 5 6 7 8 |
C2SModule.Error error; C2SModule.Parameter arg; arg["Adjust"] = true; arg["Singular"] = true; arg["AppsFlyer"] = true; if( !C2SModule.Tracker.SetEnable( arg, out error ) ) { // Error 시 처리 } |
– 사용자 추적툴 이벤트 발생
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
[일반 이벤트 보내는 예시] TSharedPtr< FJsonObject> arg = MakeShareable(new FJsonObject); arg->SetStringField(TEXT("event"), TEXT("TutorialComplete")); FString OutputString; TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(arg.ToSharedRef(), Writer); FHiveSDKModule::Get().HiveSDKUETracker_SendEvent(OutputString); [수익 측정 이벤트 예시] TSharedPtr< FJsonObject> arg = MakeShareable(new FJsonObject); arg->SetStringField(TEXT("event"), TEXT("Purchase")); TSharedPtr< FJsonObject> argRevenueInfo = MakeShareable(new FJsonObject); argRevenueInfo->SetStringField(TEXT("title"), TEXT("potion")); argRevenueInfo->SetStringField(TEXT("description"), TEXT("potion")); argRevenueInfo->SetNumberField(TEXT("itemCount"), 1); argRevenueInfo->SetStringField(TEXT("currency"), TEXT("KRW")); argRevenueInfo->SetStringField(TEXT("price"), TEXT("1000")); arg->SetObjectField(TEXT("revenue"),argRevenueInfo); FString OutputString; TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(arg.ToSharedRef(), Writer); FHiveSDKModule::Get().HiveSDKUETracker_SendEvent(OutputString); |
– 사용자 추적툴 사용여부 설정
1 2 3 4 5 6 7 8 9 |
TSharedPtr< FJsonObject> arg = MakeShareable(new FJsonObject); arg->SetBoolField(TEXT("Adjust"), true); // true : 사용, false : 사용 안 함 arg->SetBoolField(TEXT("Singular"), true); FString OutputString; TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(arg.ToSharedRef(), Writer); FHiveSDKModule::Get().HiveSDKUETracker_SetEnable(OutputString); |
+(BOOL)SetEnable:(id)arg error:(NSError**)error completionHandler:(void(^)(NSDictionary *, NSError*))
completionHandler;
– 사용자 추적툴 이벤트 발생
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
[일반 이벤트 보내는 예시] -(void)tutorialComplete { NSError* error = nil; NSDictionary* arg = @{@"event":@"TutorialComplete"}; [C2STracker SendEvent:arg error:&error completionHandler:^(NSDictionary *, NSError *) { //이벤트 완료. }]; } [수익 측정 이벤트 예시] -(void)revenueEvent { NSError* error = nil; NSDictionary* arg = @{@"event":@"Purchase", @"revenue":@{ @"title"", //아이템이름 @"description":@"item1", //아이템설명 @"currency":@"USD", //커런시코드 @"price":@"0.99", //아이템가격 @"itemCount":@1, //아이템 수량 } }; [C2STracker SendEvent:arg error:&error completionHandler:^(NSDictionary *, NSError *) { //이벤트 완료. }]; } |
+(BOOL)SetEnable:(id)arg error:(NSError**)error completionHandler:(void(^)(NSDictionary *, NSError*))
completionHandler;
– 사용자 추적툴 사용여부 설정
1 2 3 4 5 6 7 8 |
NSError* error = nil; NSDictionary* arg = @{@"Singular":@true, @"Adjust":@true, @"AppsFlyer":@true}; //true false로 사용여부 설정. [C2SModuleTracker SetEnable:arg error:&error completionHandler:^(NSDictionary *, NSError *) { //이벤트 완료. }]; } |
C2SModule_Cocos2dx::C2SModuleCompletionHandler* completionHandler = NULL);
– 사용자 추적툴 이벤트 발생
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[일반 이벤트 보내는 예시] Json::Value arg; arg["event"] = "TutorialComplete"; // initialize때 등록한 이벤트 문자열 Json::StyledWriter writer; std::string strJSON = writer.write(arg); C2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleTracker_SendEvent( strJSON.c_str(), &error ) == false ) { CCLog( "====>>>> Tracking SendEvent error (%s)", error.get()->GetMessage() ); } [수익 측정 이벤트 예시] Json::Value arg; arg["event"] = "Purchase"; Json::Value argRevenueInfo; argRevenueInfo["title"] = "healing potion"; argRevenueInfo["description"] = "healing potion desc"; argRevenueInfo["itemCount"] = 1; argRevenueInfo["currency"] = "KRW"; argRevenueInfo["price"] = "1000"; arg["revenue"] = argRevenueInfo; Json::StyledWriter writer; std::string strJSON = writer.write(arg); C2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleTracker_SendEvent( strJSON.c_str(), &error ) == false ) { CCLog( "====>>>> Tracking SendEvent error (%s)", error.get()->GetMessage() ); } |
pkError, C2SModule_Cocos2dx::C2SModuleCompletionHandler* completionHandler = NULL);
– 사용자 추적툴 사용여부 설정
1 2 3 4 5 6 7 8 9 10 |
Json::Value arg; arg["Adjust"] = false; // true : 사용, false : 사용 안 함 arg["Singular"] = true; arg["AppsFlyer"] = true; Json::StyledWriter writer; std::string strJSON = writer.write(arg); C2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleTracker_SetEnable( strJSON.c_str(), &error ) == false ) { CCLog( "====>>>> Tracking SetEnable error (%s)", error.get()->GetMessage() ); } |
C2SModuleTracker_ShowConsentMode
EU 및 EEA 지역에서 2024년 3월 6일부터 맞춤 광고 제공을 위한 개인 정보를 수집할 경우 유저로부터 명시적 동의를 받도록 하는 DMA 규정이 의무화 됨에 따라, 개인정보 수집 동의 여부를 체크할 수 있는 동의 배너를 노출합니다.
API 사용을 위한 사전 설정
Android
App 수준의 build.gradle에서 “Analytics Consent-Mode” 라이브러리를 선언합니다.
1 2 3 |
implementation "com.com2us.android.hive:hive-analytics-consent-mode:${HIVE_SDK_VERSION}" // BoM을 사용하지 않을 경우 HiveSDK 버전 입력 |
iOS
Podfile에서 “Analytics Consent-Mode” 프레임워크를 선언합니다.
1 2 3 |
pod 'HiveAnalyticsConsentMode', '${HIVE_SDK_VERSION}' # HiveSDK 버전 입력 |
Request
ARGUMENT NAME | TYPE | DESC | PLATFORM | 비고 |
---|---|---|---|---|
checkCmp | bool | (optional) TCF 규격에 맞게 저장된 파일이 있다면 해당 파일을 읽어 동의 정보 설정 여부이며 기본값은 true (서드 파티 동의 관리 플랫폼(CMP)과 연동 참고) |
all | 24.1.1+ |
type | string |
|
all | 24.1.1+ |
Response
ARGUMENT NAME | TYPE | DESC | PLATFORM | 비고 |
---|---|---|---|---|
type | string | 호출 타입 (require / always ) |
all | 24.1.1+ |
consentStatus | Array | 동의 배너에 포함되는 Provider 상태 정보 | all | 24.1.1+ |
consentStatus 배열 타입
ARGUMENT NAME | TYPE | DESC | PLATFORM | 비고 |
---|---|---|---|---|
providerName | string | Provider 이름
|
all | 24.1.1+ |
consentForDataUsage | string |
|
all | 24.1.1+ |
consentForPersonalization | string |
|
all | 24.1.1+ |
consentDate | long | 동의를 진행한 시각. 단위는 millisecond. | all | 24.1.1+ |
expiredDate | long | 동의가 만료되는 시각. 단위는 millisecond. | all | 24.1.1+ |
샘플 코드
public static bool C2SModule.Tracker.ShowConsentMode(C2SModule.Parameter arg, out C2SModule.Error error, C2SModule.CompletionHandler completionHandler);
– 동의 배너를 노출
1 2 3 4 5 6 7 8 9 10 11 |
C2SModule.Error error; C2SModule.Parameter arg; arg["type"] = "require"; arg["checkCmp"] = true; if( !C2SModule.Tracker.ShowConsentMode( arg, out error ) ) { // Error 시 처리 } |
+(BOOL)ShowConsentMode:(id)arg error:(NSError**)error completionHandler:(void(^)(NSDictionary *, NSError*))
completionHandler;
– 동의 배너를 노출
1 2 3 4 5 6 7 |
NSError* error = nil; NSDictionary* arg = @{@"type":@"require", @"checkCmp":@true}; [C2STracker ShowConsentMode:arg error:&error completionHandler:^(NSDictionary *, NSError *) { //이벤트 완료. }]; |
C2SModule_Cocos2dx::C2SModuleCompletionHandler* completionHandler = NULL);
– 동의 배너를 노출
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Json::Value arg; arg["type"] = "require"; arg["checkCmp"] = true; Json::StyledWriter writer; std::string strJSON = writer.write(arg); C2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleTracker_ShowConsentMode( strJSON.c_str(), &error ) == false ) { CCLog( "====>>>> Tracking ShowConsentMode error (%s)", error.get()->GetMessage() ); } |
서드 파티 동의 관리 플랫폼(CMP)과 연동
동의 배너 팝업을 노출할 때 생성하는 TCF 규격에 맞는 파일을 활용하면 서드 파티 동의 관리 플랫폼(CMP)과 중복으로 동의 배너 UI를 노출하지 않도록 설정할 수 있습니다. C2SModuleTracker_ShowConsentMode checkCmp 파라미터가 true
인 경우, TCF 규격에 맞게 저장된 파일이 있다면 해당 파일을 읽어 파일에 있는 업체는 동의 설정한 것으로 간주합니다. 예를 들어, Hive Adiz를 사용할 경우 Google AdMob 콘솔에 접속하여 GDPR 메시지를 작성한 후, Hive Adiz를 초기화해볼 수 있습니다. CMP에서 동의 배너를 중복하여 노출하지 않으려면 아래와 같은 순서로 파트너 설정을 진행합니다. 설정에 앞서 동의를 받아야 하는 업체를 파트너로 설정합니다. 설정에 대한 자세한 사항은 HIVE ADIZ > GDPR 메시지 작성를 참고하세요.
- 좌측 메뉴에서 개인 정보 보호 및 메시지를 클릭
- 동의 관리 솔루션 > 유럽 규정 메뉴에서 ‘GDPR’ 설정을 클릭. 이후 메시지를 입력하고, 파트너사를 설정할 수 있는 페이지로 이동
- 광고 파트너 검토 > 맞춤 광고 파트너 항목에서 수정 버튼을 클릭(이후, 광고 파트너 목록을 확인하고 필요한 파트너를 선택하도록 수정할 수 있음)
- 동의를 받아야 하는 업체명을 확인하여 체크. (파트너 목록에서는 검색 기능을 제공하지 않으므로 Ctrl+F로 검색하시면 편리함.)
– AppsFlyer 동의 필요 → Appsflyer 체크
– Adjust 동의 필요 → Adjust GmbH 체크
– Singular 동의 필요 → Singular Labs Inc. 체크
※Google은 자동으로 선택되어 있음
- 저장 후, 선택한 파트너사가 목록에 노출되는 것을 확인할 수 있음