참고: 서버 간 통합은 요청을 통해서만 가능합니다. 싱귤러 고객 서비스 관리자 또는 싱귤러 지원팀에문의하세요.
앱에 임베드해야 하는 Singular SDK의 대안으로, Singular는 자체 서버에서 실행되는 전체 통합을 구축하는 데 사용할 수 있는 REST API도 제공합니다.
이 가이드에서는 Singular를 사용하여 기본적인 S2S 연동을 구축하고 다양한 선택적 기능을 구현하는 방법을 설명합니다.
S2S API 엔드포인트, 해당 매개변수 및 샘플 호출의 전체 목록은 S2S 엔드포인트 참조를 참조하세요.
기본 통합
싱귤러와의 가장 기본적인 통합은 새 세션이 있을 때, 즉 앱이 열렸을 때이를 싱귤러에 알리는 것입니다.
사용자 세션에 대해 Singular에 알리려면 세션 알림 엔드포인트를 호출하세요.
세션 알림을 통해 싱귤러는 여러 가지 작업을 수행할 수 있습니다:
- 특정 기기에서 앱의 첫 번째 세션인 경우, 싱귤러는 새로운 인스톨을 인식하고 인스톨 어트리뷰션 프로세스를 트리거합니다.
- 해당 세션이 리인게이지먼트 세션에 해당하는 경우, 싱귤러는 리인게이지먼트 어트리뷰션 프로세스를 트리거합니다( 리인게이지먼트 FAQ에서 자세히 알아보기).
- 그렇지 않은 경우, 싱귤러는 사용자 활동 및 리텐션을 추적하는 데 사용되는 세션으로 표시합니다.
세션 알림 엔드포인트에는 몇 가지 필수 파라미터가 있습니다. 세션을 보고하는 데 필요한 모든 데이터를 얻는 데 도움이 필요하면 참조를 참조하세요: iOS 설치 영수증및 참조 검색하기를참조하세요: 기기 식별자 및 세션 데이터 검색하기를 참조하세요.
팁: 세션을 보고하기 위해 데이터를 수집할 때, 비동기 함수가 다양한 에지 케이스를 반환하고 처리할 때까지 기다려야 합니다. 이는 데이터 누락 및 부분 어트리뷰션의 원인이 될 수 있는 일반적인 문제입니다.
앱 세트 ID 수집 및 전송(안드로이드 12 이상에서 필수)
앱 세트 ID 또는 ASID는 안드로이드 12 이상 기기에서 사용되는 새로운 개인정보 보호 친화적인 ID입니다. 앱 세트 ID는 동일한 개발자가 구글 플레이 스토어에 퍼블리싱한 기기의 모든 앱에서 공유됩니다.
GAID를 전송하는 방법과 유사하게 세션 호출 및 모든 이벤트 호출에 앱 세트 ID를 매개변수로 추가하세요(
).
앱 세트 ID를 수집하려면 앱에서 다음 코드를 사용합니다:
Context context = getApplicationContext();
AppSetIdClient client = AppSet.getClient(context);
Task<AppSetIdInfo> task = client.getAppSetIdInfo();
task.addOnSuccessListener(new OnSuccessListener<AppSetIdInfo>() {
@Override
public void onSuccess(AppSetIdInfo info) {
// Android Appset ID의 현재 범위를 결정합니다.
int scope = info.getScope();
// UUID 버전 4 형식을 사용하는 Android Appset ID 값을 읽습니다.
String id = info.getId();
}
});
중요: 구글 플레이 인스톨 리퍼러 보내기(안드로이드)
인스톨 리퍼러에는 사용자를 구글 플레이 스토어로 보낸 사람에 대한 정보가 포함되어 있습니다. 싱귤러에서 인스톨 리퍼러를 사용할 수 있으면 인스톨 어트리뷰션에 가장 정확한 방법을 제공합니다. 이 값을 검색하여 첫 번째 세션 알림 호출 시 Singular에 전달하세요. 이 값은 사용자 수준 내보내기에서 Facebook 데이터를 수신하고, 데이터 대상과 공유하고, 포스트백을 전송하는 등 몇 가지 중요한 Singular 기능에 필요합니다.
Google Play는 사용자가 스토어에 도착할 때 리퍼러 정보를 수집합니다. 사용자가 나중에 리퍼러가 추천한 앱을 설치하면 Google Play는 해당 정보를 앱에 제공합니다. 자세한 내용은 Google 개발자 문서를 참조하세요.
싱귤러와 인스톨 리퍼러를 공유하려면:
- 앱이 처음 열릴 때 Play 인스톨 리퍼러 API를 사용하여 인스톨 리퍼러를 검색합니다.
-
매개변수 install_ref를 포함한 세션 알림 엔드포인트를사용하여 세션을 싱귤러에 보고합니다. 이 파라미터는 JSON으로 인코딩되며 다음과 같은 속성을 가집니다:
속성 설명 referrer Play Install Referrer API에서 검색된 리퍼러 값입니다. JSON 개체이므로 문자열로 인코딩해야 합니다. referrer_source 지정하다 "service". clickTimestampSeconds Play Install Referrer API에서 수신한 클릭 타임스탬프(예: '1550420123')입니다. installBeginTimestampSeconds Play Install Referrer API에서 수신된 설치가 시작된 시간입니다. current_device_time 현재 장치의 시간(밀리초)입니다(예: '1550420454906').
다음은 설치 리퍼러 이벤트를 보고하는 샘플 코드입니다:
import requests
import json
SDK_KEY = '[개발자 도구 > SDK 통합 > SDK 키의 sdk_key].'
LAUNCH_URL = 'https://s2s.singular.net/api/v1/launch'
referrer_values = {
"referrer": "tracking_id%3D123456789&utm_source%3Dmdotm%26utm_medium%3Dbanner%26utm_campaign%3Dcampaign",
"referrer_source" : "service",
"clickTimestampSeconds" : 1550420123,
"installBeginTimestampSeconds" : 1550420123,
"current_device_time" : 1550420454906
}
referrer_values = json.dumps(referrer_values, separators=(',',':'))
params = {
'a': SDK_KEY,
'p': 'Android',
'i': 'com.singular.app',
'ip': '10.1.2.3',
've': '9.2',
'ma': 'samsung',
'mo': 'SM-G935F',
'lc': 'en_US',
'aifa': '8ecd7512-2864-440c-93f3-a3cabe62525b',
'andi': 'fc8d449516de0dfb',
'utime': 1483228800,
'dnt': 0,
'install':'true',
'n': 'MyCoolApp',
'c': 'wifi',
'cn': 'Comcast',
'bd': 'Build/13D15',
'fcm':'bk3RNwTe3H0CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1',
'app_v':'1.2.3',
'openuri':'myapp%3A%2F%2Fhome%2Fpage%3Fqueryparam1%3Dvalue1',
'ddl_enabled':'false',
'install_source': 'com.android.vending',
'install_time': 1510040127,
'update_time': 1510090877,
'custom_user_id': '123456789abcd',
'install_ref' : referrer_values
}
result = requests.get(LAUNCH_URL, params=params)
print result.json()
https://s2s.singular.net/api/v1/launch?aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&andi=fc8d449516de0dfb&p=Android&a=SDK_KEY&i=com.singular.app&ip=10.1.2.3&ve=9.2&dnt=0&n=MyCoolApp&dnt=0&c=wifi&cn=Comcast&lc=en_US&bd=Build%2FMMB29K&ma=samsung&mo=SM-G935F&custom_user_id=123456789abcd&install_ref=%7B%22installBeginTimestampSeconds%22%3A%221568939453%22%2C%22referrer%22%3A%22utm_source%3Dgoogle-play%26utm_medium%3Dorganic%22%2C%22clickTimestampSeconds%22%3A%220%22%2C%22referrer_source%22%3A%22service%22%2C%22current_device_time%22%3A%221568944524%22%7D%0A
선택 사항입니다: 사용자 ID 보내기
새 세션에 대해 Singular에 알릴 때 사용자 ID를 추가할 수 있습니다. 사용자 아이디는 사용자 이름, 이메일 주소, 무작위로 생성된 문자열 또는 앱에서 사용자 아이디로 사용하는 모든 식별자가 될 수 있습니다. Singular는 사용자 수준 데이터 내보내기와 내부 BI 포스트백(구성한 경우)에서 사용자 ID를 사용합니다.
사용자 ID를 보내려면 세션 알림 엔드포인트를 호출할 때 "custom_user_id" 매개 변수를 추가하세요.
예를 들면 다음과 같습니다:
import requests
import json
SDK_KEY = '[개발자 도구 > SDK 통합 > SDK 키의 sdk_key].'
LAUNCH_URL = 'https://s2s.singular.net/api/v1/launch'
params = {
'a': SDK_KEY,
'p': 'Android',
'i': 'com.singular.app',
'ip': '10.1.2.3',
've': '9.2',
'ma': 'samsung',
'mo': 'SM-G935F',
'lc': 'en_US',
'aifa': '8ecd7512-2864-440c-93f3-a3cabe62525b',
'andi': 'fc8d449516de0dfb',
'utime': 1483228800,
'dnt': 0,
'install':'true',
'n': 'MyCoolApp',
'c': 'wifi',
'cn': 'Comcast',
'bd': 'Build/13D15',
'fcm':'bk3RNwTe3H0CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1',
'app_v':'1.2.3',
'openuri':'myapp%3A%2F%2Fhome%2Fpage%3Fqueryparam1%3Dvalue1',
'ddl_enabled':'false',
'install_source': 'com.android.vending',
'install_time': 1510040127,
'update_time': 1510090877,
'custom_user_id': 'player_id_1234'
}
result = requests.get(LAUNCH_URL, params=params)
print result.json()
https://s2s.singular.net/api/v1/launch?aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&andi=fc8d449516de0dfb&p=Android&a=SDK_KEY&i=com.singular.app&ip=10.1.2.3&ve=9.2&n=MyCoolApp&dnt=0&c=wifi&cn=Comcast&lc=en_US&bd=Build%2FMMB29K&ma=samsung&mo=SM-G935F&custom_user_id=player_id_1234
curl --request GET \
--url 'https://s2s.singular.net/api/v1/launch?aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&andi=fc8d449516de0dfb&p=Android&a=SDK_KEY&i=com.singular.app&ip=10.1.2.3&ve=9.2&n=MyCoolApp&dnt=0&c=wifi&cn=Comcast&lc=en_US&bd=Build%2FMMB29K&ma=samsung&mo=SM-G935F&custom_user_id=player_id_1234'
추가 어트리뷰션 처리
애플 검색 광고 캠페인 어트리뷰션(iOS)
애플 검색 광고는 셀프 어트리뷰션 네트워크(SAN)로 간주됩니다. iOS 14.3부터 애플 검색 광고 통합은 두 가지 iOS 프레임워크를 통해 지원됩니다:
- iOS 14.2 이하의 경우, Apple 검색 광고는 iAd 프레임워크를 통해 지원됩니다.
- iOS 14.3 이상의 경우, Apple 검색 광고는 애드서비스 프레임워크를 통해 지원됩니다.
향후 iAd 프레임워크가 더 이상 사용되지 않을 때까지 iAd와 애드서비스 프레임워크를 모두 구현할 것을 권장합니다. 애드서비스는 아직 새로운 Apple 서비스이므로, 싱귤러는 두 서비스를 모두 활용하지만 어트리뷰션 및 보고를 위해 iAd 신호보다 애드서비스를 우선적으로 사용할 것입니다.
자세한 내용은 Apple 검색 광고 통합 문서를 참조하세요.
iAd를 통해 Apple 검색 광고 구현하기(iOS 14.2 이하)
1.어트리뷰션 데이터 검색하기:
어트리뷰션 데이터를 검색하려면, Apple Search Ads iAd API를 사용합니다. requestAttributionDetails(_:)를 호출하면 어트리뷰션 데이터가 포함된 JSON 객체가 반환됩니다.
예시
#import <iAd/iAd.h>
Class ADClientClass = NSClassFromString(@"ADClient");
if (ADClientClass) {
id sharedClient = [ADClientClass performSelector:@selector(sharedClient)];
if ([sharedClient respondsToSelector:@selector(requestAttributionDetailsWithBlock:)]) {
[sharedClient requestAttributionDetailsWithBlock:^(NSDictionary *attributionDetails, NSError *error) {
if (attributionDetails && attributionDetails.count > 0) {
// 앱의 iAd 속성 세부정보를 서버로 보냅니다.
}
}];
}
}
- 어트리뷰션 데이터를 검색하기 전에 몇 초의 지연 시간을 설정합니다.
- 응답이 False이거나 오류 코드(0, 2, 3)인 경우 재시도 로직을 구현합니다. 2초 후에 Apple 어트리뷰션 API를 다시 호출합니다.
2.어트리뷰션 데이터를 싱귤러로 보내기:
어트리뷰션 데이터를 싱귤러와 공유하려면, 이벤트 알림 엔드포인트를사용하여 예약된 이벤트 이름 __iAd_Attribution__으로 이벤트를 보고합니다. 아래 예시와 같이 이전 단계에서 검색한 JSON 객체를 e 파라미터의 값으로 전달합니다.
import requests
import json
SDK_KEY = '[개발자 도구 > SDK 통합 > SDK 키의 sdk_key].'
EVENT_URL = 'https://s2s.singular.net/api/v1/evt'
# !!! REPLACE WITH COLLECTED VALUE FROM APP !!!
apple_attribution_data = {
u'Version3.1': {
u'iad-adgroup-id': u'1234567',
u'iad-adgroup-name': u'Ad Group Name',
u'iad-attribution': u'true',
u'iad-campaign-id': u'1234567',
u'iad-campaign-name': u'Search Campaign',
u'iad-click-date': u'2016-05-21T12:19:31Z',
u'iad-conversion-date': u'2016-05-21T12:19:41Z',
u'iad-keyword': u'ballon',
u'iad-lineitem-id': u'1234567',
u'iad-lineitem-name': u'Line Item Name',
u'iad-org-name': u'Cool Company',
u'iad-purchase-date': u'2016-05-21T12:19:41Z'
}
}
params = {
'n': '__iAd_Attribution__',
'e': json.dumps(apple_attribution_data),
'a': SDK_KEY,
'p': 'iOS',
'i': 'com.singular.app',
'ip': '10.1.2.3',
've': '9.2',
'mo': 'iPhone9%2C4',
'lc': 'en_US',
'idfa': '8ECD7512-2864-440C-93F3-A3CABE62525B',
'idfv': '38548D9F-3F73-4D4B-8545-9A920CC89191',
'utime': 1483228800
}
result = requests.get(EVENT_URL, params=params)
print result.json()
https://s2s.singular.net/api/v1/evt?n=__iAd_Attribution__&e=%7B%22Version3.1%22%3A%7B%22iad-purchase-date%22%3A%20%222016-10-25T22%3A24%3A35Z%22%2C%22iad-keyword%22%3A%20%22ballon%22%2C%22iad-adgroup-id%22%3A%20%221234567%22%2C%22iad-campaign-id%22%3A%20%221234567%22%2C%22iad-lineitem-id%22%3A%20%221234567%22%2C%22iad-org-id%22%3A%20%224070%22%2C%22iad-org-name%22%3A%20%22Cool%20Company%22%2C%22iad-campaign-name%22%3A%20%22Search%20Campaign%22%2C%22iad-conversion-date%22%3A%20%222016-05-21T12%3A19%3A41Z%22%2C%22iad-conversion-type%22%3A%20%22Redownload%22%2C%22iad-click-date%22%3A%20%222016-05-21T12%3A19%3A31Z%22%2C%22iad-attribution%22%3A%20%22true%22%2C%22iad-adgroup-name%22%3A%20%22Ad%20Group%20Name%22%2C%22iad-lineitem-name%22%3A%20%22Line%20Item%20Name%22%7D%7D&a=SDK_KEY&p=iOS&i=com.singular.app&ip=10.1.2.3&ve=9.2&ma=Apple&mo=iPhone8%2C1&lc=en_US&idfa=8ECD7512-2864-440C-93F3-A3CABE62525B&idfv=38548D9F-3F73-4D4B-8545-9A920CC89191&utime=1568948680
참고:
- iOS 13+의 경우, 설치 또는 재설치 후 첫 번째 세션 직후에 __iAd_Attribution__이벤트를 전송해야 합니다. 그렇지 않으면, Apple 검색 광고 데이터는 어트리뷰션에 고려되지 않습니다.
- iOS 14 이상에서는 특정 조건에서만애플 검색 광고 어트리뷰션 응답을 사용할 수 있으며, 앱 트래킹 투명성 상태가 ATTrackingManager.AuthorizationStatus.denied인 경우 사용할 수 없습니다.
애드서비스를 통해 애플 검색 광고 구현하기(iOS 14.3 이상)
1.어트리뷰션 토큰을 검색합니다:
앱 설치 또는 재설치 후 앱이 처음 초기화되는 즉시 attributionToken()을 사용하여 어트리뷰션 토큰을 검색합니다.
예시
#import <AdServices/AdServices.h>
NSError *error = nil;
Class AAAttributionClass = NSClassFromString(@"AAAttribution");
if (AAAttributionClass) {
NSString *attributionToken = [AAAttributionClass attributionTokenWithError:&error];
if (!error && attributionToken) {
// 앱에서 서버로 AdServices AttributionToken을 보냅니다.
}
}
참고:
- 어트리뷰션 토큰은 디바이스에서 생성됩니다.
- 생성 후 토큰은 디바이스에서 5분 동안 캐시되며, 5분 후 attributionToken()을 호출하면 새 토큰이 생성됩니다.
- 생성된 토큰은 24시간 동안 유효합니다.
2. 어트리뷰션 토큰을 싱귤러로 보냅니다:
URL로 토큰을 인코딩하고 세션 알림 엔드포인트를 통해 &attribution_token= 매개변수에 추가된 토큰을 싱귤러로 전송합니다. 이 토큰은 매번 설치 및 재설치 후 첫 번째 세션에서 전송되어야 싱귤러가 Apple 검색 광고 다운로드 및 재다운로드를 추적할 수 있습니다.
메타 인스톨 리퍼러 어트리뷰션 (안드로이드)
'메타 리퍼러'는 광고주가 안드로이드 앱 설치에 대한 세분화된 사용자 수준의 어트리뷰션 데이터에 액세스할 수 있도록 Facebook이 도입한 안드로이드 전용 측정 솔루션입니다( Facebook의 데이터 정책 참조 ). 이 솔루션은 앱 설치 측정을 위해 '구글 플레이 인스톨 리퍼러'('구글 인스톨 리퍼러 통과하기' 참조)와 '메타 인스톨 리퍼러' 기술을 모두 구현하는 것으로 구성됩니다. 메타 리퍼러에 대한 자세한 내용은 해당 주제에 대한 FAQ에서 확인하세요().
메타 인스톨 리퍼러 정보를 싱귤러와 공유하려면:
- 앱이 처음 열릴 때, 메타의 설명서에 따라 메타 인스톨 리퍼러를 검색합니다.
-
매개변수 meta_ref를 포함한 세션 알림 엔드포인트를사용하여 세션을 Singular에 보고합니다. 이 매개변수는 JSON으로 인코딩되며 다음과 같은 속성을 가집니다:
속성 설명 is_ct 메타 설치 리퍼러로부터 받은 "is_ct"입니다. (예: 0 또는 1) install_referrer 메타 설치 리퍼러로부터 받은 "install_referrer" actual_timestamp 메타 설치 리퍼러로부터 수신된 "actual_timestamp"(예: 1693978124).
이벤트 추적
싱귤러는 인앱 이벤트에 대한 데이터를 수집하여 마케팅 캠페인의 성과를 분석하는 데 도움을 줄 수 있습니다. 이벤트에는 로그인 및 등록부터 게임 앱의 레벨 업에 이르기까지 모든 사용자 상호 작용이 포함될 수 있습니다.
Singular와 SDK/S2S 연동을 구현하기 전에, 조직에서 추적하고자 하는 이벤트 목록이 있어야 합니다( 인앱 이벤트 정의하기 참조).
앱에서 이벤트가 발생하면 싱귤러에 알리려면 이벤트 알림 엔드포인트를 호출하세요. 호출에 포함하는 이벤트 이름은 Singular 보고서, 내보내기 및 포스트백에서 이벤트가 식별되는 방식입니다.
참고:
- 싱귤러는 싱귤러의 표준 이벤트 및 속성 명명 규칙을 사용하여 이벤트를 전달할 것을 권장합니다. 표준 이벤트를 사용하면 통합에서 파트너 표준 이벤트와의 매핑 및 호환성을 간소화할 수 있습니다.
- 사용하려는 타사 파트너 및 분석 솔루션과의 호환성을 위해 이벤트 이름과 기타 속성을 영어로 전달할 것을 적극 권장합니다.
- 이벤트 이름은 32개의 ASCII 문자로 제한됩니다. ASCII가 아닌 문자의 경우 UTF-8로 변환하면 32바이트로 제한됩니다.
- 이벤트 속성 및 값은 500 ASCII 문자로 제한됩니다.
수익 추적
싱귤러는 앱을 통해 얻은 수익에 대한 데이터를 수집하여 캠페인의 성과와 ROI를 분석하는 데 도움을 줄 수 있습니다.싱귤러는 보고서, 로그 내보내기 및 포스트백에서 데이터를 사용할수 있도록 합니다.
수익 이벤트를 추적하려면 모든 이벤트에 사용하는 것과 동일한 이벤트 알림 엔드포인트를사용하되, 다음 정보를 추가하세요:
- is_revenue_event=true: 이벤트를 수익 이벤트로 표시합니다. 이벤트 이름이 __iap__이거나 금액이 0보다 큰 경우 이 매개 변수를 건너뛸 수 있습니다.
- 구매 영수증: Android 또는 iOS의 인앱 구매(IAP) 프로세스에서 반환되는 객체입니다. 싱귤러에 전달하여 거래에 대한 전체 세부 정보를 제공하고 싱귤러 보고서를 데이터로 보강할 것을 적극 권장합니다.
- 구매 서명(안드로이드만 해당): 거래의 유효성을 검사하고 인앱 사기를 방지하기 위해 이 데이터를 싱귤러에 전달할 것을 적극 권장합니다.
- 수익 금액 (예: "amt=1.99").
- 통화 (ISO 4217 통화 코드 사용, 예: "cur=USD").
구매 영수증 검색
수익 이벤트가 발생한 후 구매 영수증을 가져와서 Singular로 보낼 수 있는 방법은 다음과 같습니다:
- Android에서: Google Play는 구매 영수증('인앱 구매 데이터')과 구매 서명('인앱 데이터 서명')을 검색할 수 있는 API를 제공합니다. getBuyIntent()메서드를 사용합니다.
- iOS에서: 아래 예시와 같이 Apple의 인앱 구매 API를 사용합니다(자세한 내용은 Apple 인앱 구매 API 참조).
// SKPaymentTransactionObserver
+ (void)paymentQueue:(id)queue updatedTransactions:(NSArray *)skTransactions {
NSString *transactionReceipt = nil;
if ([skTransaction respondsToSelector:@selector(transactionReceipt)]) {
NSData *transactionReceiptRaw = [skTransaction performSelector:@selector(transactionReceipt)];
if (transactionReceiptRaw) {
transactionReceipt = [ApUtils base64Encode:transactionReceiptRaw];
}
}
}
사용자 지정 수익 이벤트 샘플
import requests
import json
SDK_KEY = '[개발자 도구 > SDK 통합 > SDK 키의 sdk_key].'
EVENT_URL = 'https://s2s.singular.net/api/v1/evt'
params = {
'a': SDK_KEY,
'p': 'Android',
'i': 'com.singular.app',
'ip': '10.1.2.3',
've': '9.2',
'ma': 'samsung',
'mo': 'SM-G935F',
'lc': 'en_US',
'bd': 'Build/13D15',
'aifa': '8ecd7512-2864-440c-93f3-a3cabe62525b',
'utime': 1483228800,
'n': 'RevenueEventName',
'amt': '2.50',
'cur': 'USD',
'is_revenue_event': 'true',
'purchase_receipt': {'orderId"':'GPA.1234',
'packageName':'com.example',
'productId':'com.example.product',
'purchaseTime':1417113074914,
'purchaseState':0,
'purchaseToken':'hakfcimbk... pM'},
'receipt_signature': 'TyVJfHg8OAoW7W4wuJt...5agEDMnNXvhfrw==',
'purchase_product_id': 'com.example.product',
'purchase_transaction_id': 'GPA.1234-1234-1234-12345'
}
result = requests.get(EVENT_URL, params=params)
print result.json()
https://s2s.singular.net/api/v1/evt?n=RevenueEventName&a=SDK_KEY&p=Android&i=com.singular.app&ip=10.1.2.3&ve=9.2&ma=samsung&mo=SM-G935F&lc=en_US&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&andi=fc8d449516de0dfb&utime=1483228800&amt=2.50&cur=EUR&bd=Build%2F13D15&is_revenue_event=true&purchase_receipt=%7B%27orderId%27%3A%27GPA.1234%27%2C%27packageName%27%3A%27com.example%27%2C%27productId%27%3A%27com.example.product%27%2C%27purchaseTime%27%3A1417113074914%2C%27purchaseState%27%3A0%2C%27purchaseToken%27%3A%27hakfcimbk...%20pM%27%7D&receipt_signature=TyVJfHg8OAoW7W4wuJt5agEDMnNXvhfrw==&purchase_product_id=com.example.product&purchase_transaction_id=GPA.1234-1234-1234-12345https://s2s.singular.net/api/v1/evt?n=RevenueEventName&a=SDK_KEY&p=Android&i=com.singular.app&ip=10.1.2.3&ve=9.2&ma=samsung&mo=SM-G935F&lc=en_US&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&andi=fc8d449516de0dfb&utime=1483228800&amt=2.50&cur=EUR&bd=Build%2F13D15
curl --request GET \ --url 'https://s2s.singular.net/api/v1/evt?n=RevenueEventName&a=SDK_KEY&p=Android&i=com.singular.app&ip=10.1.2.3&ve=9.2&ma=samsung&mo=SM-G935F&lc=en_US&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&andi=fc8d449516de0dfb&utime=1483228800&amt=2.50&cur=EUR&bd=Build%2F13D15&is_revenue_event=true&purchase_receipt=%7B%27orderId%27%3A%27GPA.1234%27%2C%27packageName%27%3A%27com.example%27%2C%27productId%27%3A%27com.example.product%27%2C%27purchaseTime%27%3A1417113074914%2C%27purchaseState%27%3A0%2C%27purchaseToken%27%3A%27hakfcimbk...%20pM%27%7D&receipt_signature=TyVJfHg8OAoW7W4wuJt5agEDMnNXvhfrw==&purchase_product_id=com.example.product&purchase_transaction_id=GPA.1234-1234-1234-12345'
딥링크 지원
딥링크는 앱 내부의 특정 콘텐츠로 연결되는 링크입니다. 사용자가 앱이 설치된 기기에서 딥링크를 클릭하면 앱이 열리고 특정 제품이나 경험이 표시됩니다.
단일 추적 링크에는 딥링킹뿐만 아니라 디퍼드 딥링킹도포함될 수 있습니다(자세한 내용은 딥링킹FAQ 및 단일 링크 FAQ참조).
딥링킹 전제 조건
iOS의 경우:
- 싱귤러의 링크 관리 페이지에서 링크에 대한 하위 도메인을 하나 이상 구성합니다. 자세한 내용은 단일 링크 FAQ를 참조하세요.
- SDK 설명서에 따라 유니버설 링크를 활성화합니다.
- 앱 코드에 링크 핸들러를 구현합니다(SDK 설명서의 핸들러 참조).
안드로이드의 경우:
- SDK 설명서에 따라 Android 딥링크를 구성합니다.
- 앱 코드에 링크 핸들러를 구현합니다(SDK 설명서의 핸들러 참조).
딥링크 지원
딥링크를 통해 앱이 열릴 때마다 openuri 매개변수를 사용하여 싱귤러에 세션을 보고할 때 URL을 추가하세요. 이는 싱글 링크를 사용할 때 필요합니다.
디퍼드 딥링크 활성화
앱이 인스톨 이후 처음으로 열리면 세션을 싱귤러에 보고할 때 다음 파라미터를 추가하여 디퍼드 딥링킹 플로우를 활성화합니다:
- install=true
- ddl_enabled=true
싱귤러는 디퍼드 딥링크를 포함한 트래킹 링크를 통해 앱이 설치되었는지 확인합니다. 만약 그렇다면 다음 값을 반환합니다:
- deferred_deeplink - 딥링크 주소. 사용자에게 올바른 제품이나 경험을 표시하기 위해 이 값을 파싱해야 합니다.
- deferred_passthrough - 딥링크에 추가된 모든 패스스루 매개변수.
디퍼드 딥링크를 지원하는 세션 알림 호출 샘플
import requests
import json
SDK_KEY = '[개발자 도구 > SDK 통합 > SDK 키의 sdk_key].'
LAUNCH_URL = 'https://s2s.singular.net/api/v1/launch'
params = {
'a': SDK_KEY,
'p': 'iOS',
'i': '162738612',
'ip': '10.1.2.3',
've': '9.2',
'mo': 'iPhone9%2C4',
'lc': 'en_US',
'idfa': '8ECD7512-2864-440C-93F3-A3CABE62525B',
'idfv': '38548D9F-3F73-4D4B-8545-9A920CC89191',
'utime': 1483228800,
'dnt': 0,
'n': 'MyCoolApp',
'c': 'wifi',
'cn': 'Comcast',
'bd': 'Build/13D15',
'openuri':'https://myapp.sng.link/A59c0/nha7?_dl=myapp%3A%2F%2Fdeeplink&_ddl=myapp%3A%2F%2Fdeferred-deeplink&_p=passthroughvalue',
'install':'true',
'ddl_enabled':'true'
}
result = requests.get(LAUNCH_URL, params=params)
print result.json()
샘플 응답
{
"deferred_deeplink":"myapp://deferred-deeplink",
"status":"ok",
"deferred_passthrough":"passthroughvalue"
}
싱글 쇼트 링크 처리
싱귤러 쇼트 링크에서 앱을 열면 실행 요청에 다음 파라미터를 전송하여 오픈우리로 전송된 URL이 싱귤러 롱 링크로 리졸브되어야 함을 싱귤러 엔드포인트에 알려야 합니다.
- singular_link_resolve_required=true
싱귤래러는 롱링크를 반환하고 앱 개발자는 링크 핸들러에서 딥링크와 패스스루 매개변수를 파싱할 수 있습니다.
짧은 링크 확인을 사용한 세션 알림 호출 샘플
import requests
import json
SDK_KEY = '[개발자 도구 > SDK 통합 > SDK 키의 sdk_key].'
LAUNCH_URL = 'https://s2s.singular.net/api/v1/launch'
params = {
'a': SDK_KEY,
'p': 'iOS',
'i': '162738612',
'ip': '10.1.2.3',
've': '9.2',
'mo': 'iPhone9%2C4',
'lc': 'en_US',
'idfa': '8ECD7512-2864-440C-93F3-A3CABE62525B',
'idfv': '38548D9F-3F73-4D4B-8545-9A920CC89191',
'utime': 1483228800,
'dnt': 0,
'n': 'MyCoolApp',
'c': 'wifi',
'cn': 'Comcast',
'bd': 'Build/13D15',
'openuri':'https://myapp.sng.link/A59c0/nha7/q5a2',
'singular_link_resolve_required':'true',
}
result = requests.get(LAUNCH_URL, params=params)
print result.json()
샘플 응답
{
"status":"ok",
"resolved_singular_link":"https://myapp.sng.link/A59c0/nha7?_dl=myapp%3A%2F%2Fdeeplink&_ddl=myapp%3A%2F%2Fdeferred-deeplink&_p=passthroughvalue"
}
동적 패스스루 매개변수 지원
단일 추적 링크에는 동적 패스스루 매개변수가 포함될 수 있습니다(자세히 알아보기). 조직에서 링크에 대한 동적 패스스루 매개변수를 설정한 경우 딥링크 URL에는 _p 매개변수 뒤에 URL로 인코딩된 JSON 값 또는 사용자에게 적절한 콘텐츠나 경험을 표시하는 데 사용할 수 있는 비정형 문자열이 포함됩니다( ).
고급 옵션
싱귤러 S2S 통합은 다음과 같은 고급 기능을 지원합니다. 이러한 기능은 위에서 설명한 것과 동일한 API 엔드포인트를 사용하여 구현되지만 특수한 매개변수 및 요구사항이 적용됩니다.
제거 추적
Singular는 기기의 무음 푸시 알림을 사용하여 제거를 추적할 수 있습니다.이 기능을 사용하려면 모든 세션 알림과 함께 디바이스의 푸시 토큰을 Singular 서버로 전송해야합니다.
안드로이드에서 앱 삭제 추적
Android에서 앱 제거 추적을 활성화하려면 먼저 FirebaseInstanceId.getInstance().getToken()을 호출하여 앱에서 FCM 토큰을 검색합니다. 토큰이 아직 생성되지 않은 경우 이 메서드는 null을 반환합니다. 자세한 내용은 구글 파이어베이스 문서를 참조하세요.
그런 다음 다음 예제에서와 같이 세션을 Singular에 보고할 때 fcm 매개 변수에 장치 토큰을 전달합니다:
import requests
import json
SDK_KEY = '[개발자 도구 > SDK 통합 > SDK 키의 sdk_key].'
LAUNCH_URL = 'https://s2s.singular.net/api/v1/launch'
params = {
'a': SDK_KEY,
'p': 'Android',
'i': 'com.singular.app',
'ip': '10.1.2.3',
've': '9.2',
'ma': 'samsung',
'mo': 'SM-G935F',
'lc': 'en_US',
'aifa': '8ecd7512-2864-440c-93f3-a3cabe62525b',
'andi': 'fc8d449516de0dfb',
'utime': 1483228800,
'dnt': 0,
'n': 'MyCoolApp',
'c': 'wifi',
'cn': 'Comcast',
'bd': 'Build/13D15',
'fcm': 'bk3RNwTe3H0CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1'
}
result = requests.get(LAUNCH_URL, params=params)
print result.json()
https://s2s.singular.net/api/v1/launch?a=SDK_KEY&p=Android&i=com.singular.app&ip=10.1.2.3&ve=9.2&ma=samsung&mo=SM-G935F&lc=en_US&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&andi=fc8d449516de0dfb&utime=1483228800&dnt=0&n=MyCoolApp&c=wifi&cn=Comcast&bd=Build%2F13D15&fcm=bk3RNwTe3H0CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1
curl --request GET \
--url 'https://s2s.singular.net/api/v1/launch?a=SDK_KEY&p=Android&i=com.singular.app&ip=10.1.2.3&ve=9.2&ma=samsung&mo=SM-G935F&lc=en_US&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&andi=fc8d449516de0dfb&utime=1483228800&dnt=0&n=MyCoolApp&c=wifi&cn=Comcast&bd=Build%2F13D15&fcm=bk3RNwTe3H0CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1'
iOS에서 제거 추적
싱귤러는 Apple의 푸시 알림을 사용하여 iOS에서 앱 제거를 추적할 수 있습니다. 앱이 아직 푸시 알림을 지원하지 않는 경우, Apple 가이드를 참조하세요. 앱이 푸시 알림을 지원하게 되면 세션을 싱귤러에 보고할 때 APNS에서 반환한 디바이스 토큰을 전달하세요.
참고:
- 디바이스 토큰을 검색하는 푸시 알림 구현이 이미 있다고 가정합니다.
- APNS 토큰은 일반적으로 네이티브 형식의 바이너리 데이터입니다. APNS에서 받은 대로 싱귤러에 전달하세요. 앱에서 다른 용도로 토큰 데이터 유형을 변경하는 경우에는 반드시 16진법으로 인코딩된 문자열로 전달해야 합니다(예: encodedb0adf7c9730763f88e1a048e28c68a9f806ed032fb522debff5bfba010a9b052).
import requests
import json
SDK_KEY = '[개발자 도구 > SDK 통합 > SDK 키의 sdk_key].'
LAUNCH_URL = 'https://s2s.singular.net/api/v1/launch'
params = {
'a': SDK_KEY,
'p': 'iOS',
'i': '162738612',
'ip': '10.1.2.3',
've': '9.2',
'mo': 'iPhone9%2C4',
'lc': 'en_US',
'idfa': '8ECD7512-2864-440C-93F3-A3CABE62525B',
'idfv': '38548D9F-3F73-4D4B-8545-9A920CC89191',
'utime': 1483228800,
'dnt': 0,
'n': 'MyCoolApp',
'c': 'wifi',
'cn': 'Comcast',
'bd': 'Build/13D15',
'apns_token': 'b0adf7c9730763f88e1a048e28c68a9f806ed032fb522debff5bfba010a9b052'
}
result = requests.get(LAUNCH_URL, params=params)
print result.json()
https://s2s.singular.net/api/v1/launch?a=SDK_KEY&p=iOS&i=162738612&ip=10.1.2.3&ve=9.2&mo=iPhone9%2C4&lc=en_US&idfa=8ECD7512-2864-440C-93F3-A3CABE62525B&idfv=38548D9F-3F73-4D4B-8545-9A920CC89191&utime=1483228800&dnt=0&n=MyCoolApp&c=wifi&cn=Comcast&bd=Build%2F13D15&apns_token=b0adf7c9730763f88e1a048e28c68a9f806ed032fb522debff5bfba010a9b052
curl --request GET \
--url 'https://s2s.singular.net/api/v1/launch?a=SDK_KEY&p=iOS&i=162738612&ip=10.1.2.3&ve=9.2&mo=iPhone9%2C4&lc=en_US&idfa=8ECD7512-2864-440C-93F3-A3CABE62525B&idfv=38548D9F-3F73-4D4B-8545-9A920CC89191&utime=1483228800&dnt=0&n=MyCoolApp&c=wifi&cn=Comcast&bd=Build%2F13D15&apns_token=b0adf7c9730763f88e1a048e28c68a9f806ed032fb522debff5bfba010a9b052'
데이터 개인정보 보호법 준수
Singular는 개인정보 보호 기능을 제공하여 GDPR 및 CCPA와 같은 소비자 개인정보 보호법을 준수하는 모든 파트너와 협력할 수 있도록 지원합니다. 이러한 파트너는 최종 사용자가 개인 정보 공유에 동의한 경우 알림을 받기를 원합니다.
사용자에게 정보 공유에 대한 동의를 요청하는 방법을 구현한 경우, 데이터_공유_옵션 매개변수를 사용하여 사용자의 선택 사항을 Singular에 알립니다:
- 사용자가 정보 공유에 동의(옵트인)했음을 나타내기 위해 "limit_data_sharing":false를 전달합니다.
- 사용자가 거부한 경우 "limit_data_sharing":true를 전달합니다.
싱귤러는 관련 규정을 준수하기 위해 이 정보를 필요로 하는 파트너에게 전달할 뿐만 아니라'사용자 개인정보 포스트백'에서 limit_data_sharing을 사용합니다. 자세한 내용은"사용자 개인정보 및 데이터 공유 제한"을 참조하세요.
참고:
- 이 방법의 사용은 선택 사항이지만, 사용자가 옵트인했음을 구체적으로 고지한 경우에만 파트너가 싱귤러와 공유하는 어트리뷰션 정보가 있을 수 있습니다.
- GET 요청에 JSON 객체를 전달할 경우 반드시 URL 인코딩해야 합니다.
필드 | 유형 | 설명 | 사용법 |
limit_data_sharing | boolean |
최종 사용자의 기본 설정을 나타내려면 모든 시작 또는 evt 요청에 이 선택적 값을 전달하세요. |
data_sharing_options= |
참조: iOS 설치 영수증 검색
세션 알림 엔드포인트 참조에서 볼 수 있듯이 iOS 앱의 세션을 보고할 때 install_receipt 매개변수에 설치 영수증을 전달해야 합니다.
이 값을 검색하려면 앱에 다음 코드를 추가하세요:
+ (NSString*)installReceipt {
// install receipts are iOS 7.0+
if (NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_7_0) {
return nil;
}
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
if (receiptURL) {
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
if (receipt) {
return [receipt base64EncodedStringWithOptions:0];
}
}
return nil;
}
참조: 디바이스 식별자 및 세션 데이터 검색하기
이 섹션에서는 REST API에서 필요한 특정 값을 검색하는 방법을 자세히 설명합니다. 이러한 값은 업계 표준이며, Apple과 Google에서도 이에 대한 문서를 보유하고 있습니다. 사용자의 편의를 위해 몇 가지 참조 구현을 제공했습니다.
Google 광고 ID 검색/광고 추적 제한(안드로이드 식별자)
앱에서 광고 ID를 가져오려면 구글 플레이 서비스 SDK가 필요합니다. 안드로이드 매니페스트.xml에서 애플리케이션 요소의 하위 요소로 다음 태그를 추가합니다:
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
앱 빌드가 안드로이드 12/API 레벨 31 이상을 타겟팅하는 경우, 구글 광고 ID에 액세스할 수 있는 권한을 추가하세요:
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
Google 광고 ID/광고 추적 제한 매개변수를 가져오기 위한 샘플 코드입니다:
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
import com.google.android.gms.common.GooglePlayServicesAvailabilityException;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import java.io.IOException;
// 메인 스레드에서 이 함수를 호출하지 마세요. 그렇지 않으면 IllegalStateException이 발생합니다.
public void getIdAndLAT() {
Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
} catch (IOException e) {
// Google Play 서비스 연결 중 복구할 수 없는 오류가 발생했습니다(예: 이전 버전의 서비스는 AdvertisingId 가져오기를 지원하지 않습니다).
} catch (GooglePlayServicesAvailabilityException e) {
// Google Play 서비스에 연결하는 중에 복구 가능한 오류가 발생했습니다.
} catch (GooglePlayServicesNotAvailableException e) {
// Google Play 서비스를 완전히 사용할 수는 없습니다.
}
final String GAID = adInfo.getId();
final boolean limitAdTracking = adInfo.isLimitAdTrackingEnabled();
}
Android용 로캘, 기기 및 빌드 검색하기
// Locale - lc= query parameter
String locale = Locale.getDefault();
// Model - mo= query parameter
String device = Build.MODEL;
// Build - bd= query parameter
String build = "Build/" + Build.ID;
앱 추적 투명성 권한 상태 검색하기(iOS)
iOS 14.5부터 기기의 IDFA를 검색하려면 앱 추적 투명성이 필요합니다. 앱 추적 투명성 프롬프트가 표시되는 경우, IDFA를 검색하기 전에 프롬프트와 핸들러를 구현해야 합니다.
다음은 ATT 프롬프트(선택 사항)를 구현하는 방법과 ATT 인증 스태츄(필수 사항)를 검색하는 방법의 예시입니다:
#import <AppTrackingTransparency/ATTrackingManager.h>
// ATT 프롬프트를 표시하기로 결정한 경우 선택 사항입니다. 프롬프트를 표시하고 값을 처리합니다. 여러 번 호출해도 한 번만 나타납니다.
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status){
// your authorization handler here
}];
// 필수 현재 ATT 승인 상태를 읽습니다.
ATTrackingManagerAuthorizationStatus status = [ATTrackingManager trackingAuthorizationStatus];
IDFA/광고 추적 제한(iOS 식별자) 검색하기
iOS 14.5부터 IDFA를 검색하려면 앱 추적 투명성이필요합니다. 앱 추적 투명성 프롬프트를 표시하기로 결정한 경우, IDFA를 검색하기 전에 프롬프트와 핸들러를 구현해야 합니다.
앱 추적 투명성을 표시하지 않으려는 경우에도 IDFA를 검색할 수 있습니다(값은 0이 됨). IDFA를 사용할 수 없거나 모두 0인 경우 싱귤러로 되돌아가므로 어떤 경우에도 IDFV를 검색하여 전송해야 합니다.
제한 광고 추적(isAdvertisingTrackingEnabled) 플래그는 iOS 13 이하에서 필수이며 사용자가 광고 추적을 옵트아웃했는지 여부를 나타내는 데 사용됩니다. iOS 14 이상에서는 이 플래그가 더 이상 사용되지 않으며 검색 시 정적 값이 됩니다. 싱글 및 파트너는 개인정보 흐름에 대한 데이터 처리를 위해 최신 ATT 인증 상태 값을사용합니다.
아래는 IDFA, IDFV 및 광고 추적 제한 상태 검색의 예입니다:
// 파일 상단에서 AdSupport 클래스를 가져옵니다.
@import AdSupport;
// 파일 상단에서 AdSupport 클래스를 가져옵니다.@import AdSupport;
IDFA/광고 추적 제한 매개변수를 가져오기 위한 샘플 코드입니다:
NSString* IDFA = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSString* IDFV = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
BOOL isAdvertisingTrackingEnabled = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled];
Class AdSupportClass = NSClassFromString(@"ASIdentifierManager");
id sharedManager = nil;
if (AdSupportClass && [AdSupportClass respondsToSelector:@selector(sharedManager)]) {
sharedManager = [AdSupportClass performSelector:@selector(sharedManager)];
}
if (sharedManager) {
NSString* IDFA = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSString* IDFV = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
BOOL dnt = ![[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled];
}
iOS용 로캘, 기기, 빌드 검색하기
// Locale - lc= query parameter
NSString *locale = [[NSLocale currentLocale] localeIdentifier];
// Model - mo= query paramter
#import <sys/sysctl.h>
NSString *device() {
size_t bufferSize = 64;
NSMutableData * buffer = [[NSMutableData alloc] initWithLength:bufferSize];
int status = sysctlbyname("hw.machine", buffer.mutableBytes, &bufferSize, NULL, 0);
if (status != 0) {
return nil;
}
return [[NSString alloc] initWithData:buffer encoding:NSUTF8StringEncoding];
}
// Build - bd= query parameter
NSString * build () {
size_t bufferSize = 64;
NSMutableData *buffer = [[NSMutableData alloc] initWithLength:bufferSize];
int status = sysctlbyname("kern.osversion",buffer.mutableBytes, &bufferSize, NULL, 0);
if (status != 0) {
return nil;
}
return [[NSString alloc] initWithData:buffer encoding:NSUTF8StringEncoding];
}
// Locale - lc= query parameter
NSString *locale = [[NSLocale currentLocale] localeIdentifier];
// Model - mo= query paramter
@import Darwin.sys.sysctl;
NSString *device(void) {
size_t bufferSize = 64;
NSMutableData * buffer = [[NSMutableData alloc] initWithLength:bufferSize];
int status = sysctlbyname("hw.machine", buffer.mutableBytes, &bufferSize, NULL, 0);
if (status != 0) {
return nil;
}
return [[NSString alloc] initWithData:buffer encoding:NSUTF8StringEncoding];
}
// Build - bd= query parameter
@import Darwin.sys.sysctl;
NSString * build ( void ) {
size_t bufferSize = 64;
NSMutableData *buffer = [[NSMutableData alloc] initWithLength:bufferSize];
int status = sysctlbyname("kern.osversion",buffer.mutableBytes, &bufferSize, NULL, 0);
if (status != 0) {
return nil;
}
return [[NSString alloc] initWithData:buffer encoding:NSUTF8StringEncoding];
}