서버 간 연동 가이드
서버 간 사용 사례
앱에 임베드해야 하는 Singular SDK의 대안으로, Singular는 Singular SDK 없이도 자체 서버에서 실행되는 완전한 연동을 구축하는 데 사용할 수 있는 REST API를 제공합니다. 이 가이드에서는 완전한 서버 간 연동을 구축하는 개념을 설명하고 모든 고급 기능을 중점적으로 설명합니다.
하이브리드 사용 사례
100% 서버 간 연동의 대안으로, Singular SDK를 사용하여 세션 관리와 모든 고급 기능 및 데이터 수집 요구 사항을 처리하는 하이브리드 접근 방식을 활용할 수 있습니다. 또한 서버 간 이벤트 API를 활용하여 백엔드 서버에서 이벤트를 전송할 수도 있습니다.
하이브리드 사용 사례 세부 정보
인앱 모바일 이벤트 또는 웹사이트 이벤트 데이터를 서버에서 Singular로 전송할 때는 Singular 모바일 SDK 또는 웹 SDK의 해당 식별자를 반드시 포함해야 합니다. 이를 통해 이벤트 활동이 올바른 디바이스에 정확하게 어트리뷰션되도록 할 수 있습니다.
데이터 흐름
이 디바이스 데이터를 검색하는 방법에는 크게 두 가지가 있습니다:
- 클라이언트 관리 데이터 흐름: 이 옵션은 클라이언트에서 필요한 모든 데이터 포인트를 캡처하여 자체 API를 통해 서버로 전달하는 것입니다. 이 방법을 사용하면 클라이언트 측(예: 모바일 앱 또는 웹사이트)에서 직접 디바이스 식별자, 이벤트 데이터 및 기타 필요한 속성을 수집하여 서버로 전달하면 서버 간 이벤트 API를 사용하여 이를 처리하여 Singular로 전송할 수 있습니다.
- 포스트백: 이 옵션은 Singular 내부 BI 포스트백을 구성하는 것으로, 이를 통해 Singular가 지정된 엔드포인트에 JSON 페이로드와 함께 포스트백을 전송할 수 있습니다. 이 포스트백은 설치, 재참여 및/또는 인앱 이벤트가 발생한 후 실시간으로 전달됩니다. 페이로드에는 인앱 서버 측 이벤트를 성공적으로 전송하는 데 필요한 모든 필수 데이터 포인트가 포함됩니다. 내부 BI 포스트백 설정에 대한 자세한 지침을 보려면[여기를 클릭하세요.]
두 옵션 모두 디바이스 그래프를 유지하기 위해 일부 서버 측 로직이 필요할 수 있습니다. Singular SDK가 디바이스 식별자의 변경을 감지하면 정확한 추적 및 어트리뷰션을 위해 서버를 적절히 업데이트하는 것이 중요합니다.
앱에서 디바이스 식별자와 파라미터를 캡처하여 Singular API 엔드포인트에서 사용할 수 있도록 서버로 전송하는 첫 번째 옵션을 구현하려면 다음 문서를 검토하여 지침을 확인하세요:
- 이벤트 엔드포인트 필수 파라미터를 검토합니다.
- 특정 디바이스 식별자 및 디바이스 데이터 포인트의 검색에 도움이 되는 iOS 및 Android 코드 샘플에 대한 서버 간 디바이스 데이터 검색 가이드를 검토하세요.
아래의 일반 가이드라인을 검토하여 서버 간 구성의 일반 가이드라인을 따르세요. 하이브리드 사용 사례에서는 Singular SDK가 이를 관리하므로 세션 엔드포인트를 생략할 수 있습니다.
주요 포인트
- 유연성: 데이터 수집 및 전송을 완벽하게 제어할 수 있습니다.
- 기능 동등성: 적절한 데이터가 제공되면 모든 SDK 기능을 지원합니다.
- 연동 경로: 클라이언트 → 서버 → Singular API
- 실시간 처리: 한 번에 하나의 요청만 처리하며 일괄 처리하지 않습니다.
- 순차적 데이터 흐름: 이벤트는 시간 순서대로 처리해야 합니다.
- 데이터 중복 제거: Singular: 수신된 데이터는 중복 제거되지 않습니다. 요청을 재생해야 하는 경우 성공적인 요청을 하나(1)만 보내고 로그를 저장하는 것이 좋습니다.
- 데이터 유효성 검사: 디바이스 수준 데이터는 영구적이며 한번 수집된 데이터는 삭제할 수 없습니다. Singular에 데이터를 전송하기 전에 철저한 데이터 유효성 검사를 실시하여 정확성을 보장하세요.
요구 사항
SDK는 자동으로 디바이스 및 앱 데이터를 수집하지만, S2S 접근 방식에서는 사용자가 직접 데이터를 수집해야 합니다:
- 앱에서 필요한 데이터 포인트를 수집합니다.
- 이 데이터를 서버로 전달하고 디바이스 그래프에 저장합니다.
- 세션 API 엔드포인트를 통해 Singular에 세션 요청을 보냅니다.
- Singular의 응답을 앱에 다시 전달합니다.
- EVENT API 엔드포인트를 통해 이벤트 요청을 Singular로 전달합니다.
REST API 엔드포인트
세션 엔드포인트
GET https://s2s.singular.net/api/v1/launch
세션 엔드포인트 API 참조
이벤트 엔드포인트
GET https://s2s.singular.net/api/v1/evt
이벤트 엔드포인트 API 참조
시작하기
앱 세션 및 이벤트 추적을 위해 Singular의 REST API와 성공적으로 연동하려면 4가지 주요 단계로 구성된 포괄적인 데이터 파이프라인을 구현해야 합니다.
- 앱 내에서 강력한 데이터 수집 전략을 수립하여 서버 측 데이터베이스에 관련 사용자 상호 작용과 Singular 필수 데이터 포인트를 캡처하고 저장합니다.
- 캡처한 이벤트를 서버에서 Singular의 REST API 엔드포인트로 즉시 전달하는 실시간 데이터 스트리밍 메커니즘을 생성합니다.
- Singular의 API 응답을 처리하기 위해 적절한 응답 처리를 구현하여 성공적인 데이터 전송과 적절한 오류 관리를 보장합니다.
- 모든 데이터 흐름에 걸쳐 철저한 테스트를 수행하여 연동의 정확성과 신뢰성을 검증합니다.
이러한 체계적인 접근 방식을 통해 데이터 무결성을 유지하면서 원활한 데이터 전송을 보장하고 애플리케이션과 Singular의 분석 플랫폼 간의 실시간 동기화를 유지합니다.
데이터 수집
Singular는 각 엔드포인트에 특정 데이터 포인트가 필요하며, 이는 Singular 플랫폼의 기능을 제공하는 데 필요합니다. 모든 필수 매개변수는 필수이며 생략할 경우 데이터 또는 기능 불일치가 발생할 수 있습니다.
팁: Singular API를 사용하기 위해 클라이언트 측 데이터를 수집하여 서버로 다시 전송할 때는 비동기 함수가 반환될 때까지 기다렸다가 다양한 에지 케이스를 처리해야 합니다. 이는 데이터 누락 및 부분 어트리뷰션의 원인이 될 수 있는 일반적인 문제입니다.
- 세션 엔드포인트 필수 파라미터를 검토하세요.
- 이벤트 엔드포인트 필수 파라미터를 검토합니다.
- 특정 기기 식별자 및 기기 데이터 포인트 검색에 도움이 되는 iOS 및 안드로이드 코드 샘플에 대한 서버 간 기기 데이터 검색 가이드를 검토하세요.
- iOS 코드 샘플용 서버 간 SKAdNetwork 4 구현 가이드에서 특정 SkAdNetwork 4 디바이스 데이터 포인트 검색에 대한 도움말을 확인할 수 있습니다.
- 아래에서 원하는 고급 옵션 섹션을 검토하고 식별합니다.
필요한 데이터 포인트를 캡처하여 서버에 제공하면 세션 및 이벤트 요청을 Singular로 스트리밍할 준비가 된 것입니다.
실시간 데이터 스트리밍
실시간 데이터 스트리밍은 정확한 어트리뷰션 및 캠페인 성과 측정을 유지하는 데 매우 중요합니다. 서버 측 추적을 구현할 때, 데이터 전송의 타이밍과 순서는 Singular가 제공하는 분석 및 최적화 기능의 품질에 직접적인 영향을 미칩니다.
중요한 타이밍 고려 사항
- 어트리뷰션 정확도: 세션 보고가 지연되면 사용자 행동을 마케팅 캠페인과 정확하게 연결하기 위해 정확한 시간대 데이터가 필요하므로 어트리뷰션 정확도에 심각한 영향을 미칠 수 있습니다.
- SKAdNetwork 시사점: iOS SKAdNetwork 전환 값의 시간에 민감한 특성으로 인해 실시간 데이터 스트리밍이 특히 중요합니다. 전환 값 업데이트를 위한 엄격한 디바이스 내 타이머 창이 있기 때문에, 이벤트 보고가 지연되면 전환 값 업데이트 기회를 놓쳐 캠페인 성과 데이터가 불완전하거나 부정확해질 수 있습니다.
데이터 스트림을 구축할 때 염두에 두어야 할 몇 가지 모범 사례입니다:
- 앱 세션 시작을 위한 서버 측 이벤트 리스너를 구현합니다.
- 모든 필수 데이터 포인트와 함께 세션 데이터를 Singular의 REST API로 즉시 전달합니다.
- 인앱 이벤트에 대한 서버 측 이벤트 리스너를 구현합니다.
- 모든 필수 데이터 포인트와 함께 이벤트 데이터를 Singular의 REST API로 즉시 전달합니다.
- 안정적인 데이터 전송을 위해 웹훅 아키텍처를 사용합니다.
- 실패한 요청에 대한 재시도 메커니즘을 구현합니다.
- 품질 보증을 위해 데이터 흐름을 모니터링하세요.
실시간 스트림이 구성되었으면 응답 처리로 넘어가세요.
응답 처리
응답 처리는 서버 측 API 상호 작용과 클라이언트 측 기능을 연결하는 또 다른 중요한 구성 요소입니다. 이 양방향 커뮤니케이션을 통해 Singular의 API에서 중요한 응답 데이터가 모바일 애플리케이션에 도달하여 디퍼드 딥링킹 및 전환 값 업데이트와 같은 주요 기능을 구현할 수 있습니다.
주요 응답 유형
- 디퍼드 딥링크: 새 세션이 시작되면 적절한 사용자 라우팅 및 경험 개인화를 위해 앱에 즉시 전달해야 하는 보류 중인 딥링크 데이터가 API 응답에 포함될 수 있습니다.
- 전환 값: iOS 캠페인의 경우, 전환 엔드포인트는 정확한 캠페인 측정을 유지하기 위해 앱에 즉시 전달되어야 하는 업데이트된 SKAdNetwork 전환 값을 제공합니다.
응답 처리 흐름을 구축할 때 염두에 두어야 할 몇 가지 모범 사례:
- 클라이언트 서버에서 응답 처리를 구현합니다.
- Singular API 응답을 구문 분석하고 유효성을 검사합니다.
- 관련 응답 데이터를 클라이언트 앱으로 전달합니다. iOS SKAdNetwork 전환 값 업데이트에 필수적입니다.
- 클라이언트 측 응답 처리를 구현합니다.
- 적절한 상태 코드로 오류를 우아하게 처리합니다.
- 재시도 메커니즘에 대한 실패한 응답 로그.
이제 응답 처리가 완료되었으므로 데이터 파이프라인을 테스트하고 모든 데이터 흐름이 예상대로 작동하고 올바른 데이터를 제공하는지 검증할 차례입니다.
데이터 흐름 테스트
테스트 단계는 성공적인 배포를 위해 매우 중요합니다. Singular와의 가장 기본적인 연동은 사용자 세션이 발생했을 때 이를 Singular에 알려 Singular가 여러 내부 프로세스를 트리거할 수 있도록 하는 것입니다:
- 특정 디바이스에서 앱의 첫 번째 세션인 경우, Singular는 새로운 설치를 인식하고 인스톨 어트리뷰션 프로세스를 트리거합니다.
- 해당 세션이 리인게이지먼트 세션에 해당하는 경우, Singular는 리인게이지먼트 어트리뷰션 프로세스를 트리거합니다( 리인게이지먼트 FAQ에서 자세히 알아보기).
- 그렇지 않으면, Singular는 이를 세션으로 표시하여 사용자 활동 및 리텐션 지표를 추적하는 데 사용합니다.
세션 요청과 Singular 서버에 대한 후속 이벤트 요청의 타이밍은 매우 중요합니다:
-
이벤트가 발생하기 전에 Singular 세션이 수신되어야 합니다.
예를 들어, 사용자가 앱 사용을 시작할 때 앱 열기에서 세션을 트리거하면, 세션에 이어 인앱 이벤트가 전송될 수 있습니다. 사용자가 앱을 백그라운드에서 장시간(1분 이상) 사용하면 세션이 시간 초과됩니다. 앱이 다시 포그라운드로 돌아오면 다른 세션이 전송됩니다. 앱 수명 주기 이벤트와 타이머를 사용하여 세션 관리를 관리하고 Singular에 대한 세션 요청을 규제하는 것이 좋습니다. - 앱에서 발생하는 이벤트는 해당 세션 이후에 실시간으로 전송되어야 합니다.
- 세션 데이터 흐름을 테스트하고 첫 번째 세션과 후속 세션에 각각의 데이터 포인트와 올바른 값이 있는지 확인합니다.
- 세션이 Singular에 보고된 후에만 이벤트가 수신되는지 확인합니다. 세션 이전에 이벤트가 수신되면 디바이스에 대한 오가닉 어트리뷰션이 조작되어 보고에서 원치 않는 결과를 초래할 수 있습니다.
- 세션 응답이 처리되어 클라이언트 앱으로 다시 전달되는지 확인합니다. 이는 Singular 캠페인으로 디퍼드 딥링크를 지원할 때 매우 중요합니다.
성공:
- 필수 데이터 포인트의 데이터 수집 및 저장을 확인했습니다!
- Singular로의 실시간 데이터 스트리밍을 검증했습니다!
- Singular에 대한 요청의 응답 처리 및 로깅을 검증했습니다!
- 모든 테스트 데이터 흐름을 검증했습니다!
고급 옵션
Singular의 서버 대 서버(S2S) 연동의 고급 옵션을 활용하려면 추가 매개변수로 세션 알림 엔드포인트를 개선해야 합니다.
이 과정에는 다음이 포함됩니다:
- 원하는 고급 기능을 식별합니다.
- 해당 특수 매개변수를 찾습니다.
- 이러한 매개변수를 기존 엔드포인트 구성에 연동합니다.
아래에서 사용 가능한 고급 옵션을 검토하세요:
추가 어트리뷰션 처리
Apple 검색 광고 캠페인 어트리뷰션(iOS)
Apple 검색 광고는 자체 어트리뷰션 네트워크(SAN)로 간주됩니다. iOS 14.3부터 두 가지 iOS 프레임워크를 통해 Apple Search Ads 연동이 지원됩니다:
- iOS 14.2 이하의 경우, Apple 검색 광고는 iAd 프레임워크를 통해 지원됩니다 .
- IOS 14.3 이상의 경우, Apple 검색 광고는 애드서비스 프레임워크를 통해 지원됩니다.
향후 iAd 프레임워크가 더 이상 사용되지 않을 때까지는 iAd 프레임워크와 애드서비스 프레임워크를 모두 구현하는 것이 좋습니다. 애드서비스는 아직 새로운 Apple 서비스이므로, Singular는 두 서비스를 모두 활용하되 어트리뷰션 및 리포팅을 위해 iAd 신호보다 애드서비스를 우선시할 것입니다.
자세한 내용은 Apple 검색 광고 연동 문서를 참조하세요.
iAd를 통해 Apple 검색 광고 구현하기(iOS 14.2 이하)
1. 어트리뷰션 데이터 검색하기:
어트리뷰션 데이터를 검색하려면, Apple Search Ads iAd API를 사용합니다. 요청AttributionDetails(_:) 를 호출하면 어트리뷰션 데이터가 포함된 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) {
// REPORT attributionDetails FROM YOUR APP TO YOUR SERVER
}
}];
}
}
- 어트리뷰션 데이터를 검색하기 전에 몇 초의 지연 시간을 설정합니다.
- 응답이 False이거나 오류 코드(0, 2, 3)인 경우 재시도 로직을 구현합니다. 2초 후에 Apple 어트리뷰션 API를 다시 호출합니다.
2. 어트리뷰션 데이터를 Singular로 보내기:
어트리뷰션 데이터를 Singular와 공유하려면, 이벤트 알림 엔드포인트를 사용하여 예약된 이벤트 이름 __iAd_Attribution__으로 이벤트를 보고합니다. 아래 예시와 같이 이전 단계에서 검색한 JSON 객체를 e 파라미터의 값으로 전달합니다.
import requests
import json
SDK_KEY = '[sdk_key from Developer tools > SDK Integration > SDK keys]'
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 이상에서는 특정 조건에서만 Apple Search Ads 어트리뷰션 응답을 사용할 수 있으며, 앱 트래킹 투명성 상태가 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) {
// Handle attributionToken
}
}
참고:
- 어트리뷰션 토큰은 디바이스에서 생성됩니다.
- 생성 후 토큰은 디바이스에서 5분 동안 캐시됩니다. 5분 후 attributionToken()이 호출되면 새 토큰이 생성됩니다.
- 생성된 토큰은 24시간 동안 유효합니다.
2. 어트리뷰션 토큰을 Singular로 전송합니다:
URL로 토큰을 인코딩하고 세션 알림 엔드포인트를 통해 &attribution_token= 파라미터에 토큰을 추가하여 Singular로 전송합니다. 이 토큰은 매번 설치 및 재설치 후 첫 번째 세션에서 전송되어야 하며, 이를 통해 Singular가 Apple Search Ads 다운로드 및 재다운로드를 추적할 수 있습니다.
중요: 구글 플레이 인스톨 리퍼러 전송(안드로이드)
인스톨 리퍼러에는 사용자를 구글 플레이 스토어로 보낸 사람에 대한 정보가 포함되어 있습니다. Singular에서 인스톨 리퍼러를 사용할 수 있는 경우 인스톨 어트리뷰션에 가장 정확한 방법을 제공합니다. 이 값을 검색하여 첫 번째 세션 알림 호출 시 Singular에 전달하세요. 사용자 수준 내보내기에서 Facebook 데이터를 수신하고, 데이터 대상과 공유하고, 포스트백을 전송하는 등 일부 중요한 Singular 기능에 필요합니다.
Google Play는 사용자가 스토어에 도착할 때 리퍼러 정보를 수집합니다. 나중에 사용자가 리디렉션된 앱을 설치하면 Google Play는 해당 정보를 앱에서 사용할 수 있도록 합니다. 자세한 내용은 Google 개발자 문서를 참조하세요.
Singular와 설치 리퍼러를 공유하려면 다음과 같이 하세요:
- 앱을 처음 열 때 Play 인스톨 리퍼러 API를 사용하여 인스톨 리퍼러를 검색합니다.
-
매개변수 install_ref를 포함한 세션 알림 엔드포인트를 사용하여 Singular에 세션을 보고합니다. 이 파라미터는 JSON으로 인코딩되며 다음과 같은 속성을 가집니다:
속성 설명 referrer
Play 인스톨 리퍼러 API에서 검색된 리퍼러 값입니다. 이 값은 JSON 객체이므로 문자열로 인코딩해야 합니다. referrer_source
"서비스"를 지정합니다. clickTimestampSeconds
Play 인스톨 리퍼러 API에서 받은 클릭 타임스탬프(예: "1550420123")입니다. installBeginTimestampSeconds
플레이 설치 리퍼러 API에서 수신한 설치가 시작된 시간입니다. current_device_time
현재 기기에서의 시간(밀리초 단위)(예: "1550420454906").
다음은 인스톨 리퍼러 이벤트를 보고하는 샘플 코드입니다:
import requests
import json
SDK_KEY = '[sdk_key from Developer tools > SDK Integration > SDK keys]'
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
메타 인스톨 리퍼러 어트리뷰션(안드로이드)
'메타 리퍼러'는 광고주가 안드로이드 앱 설치에 대한 세분화된 사용자 수준의 어트리뷰션 데이터에 액세스할 수 있도록 Facebook에서 도입한 안드로이드 전용 측정 솔루션입니다( Facebook의 데이터 정책 참조 ). 앱 설치 측정을 위해 '구글 플레이 인스톨 리퍼러'('구글 인스톨 리퍼러 통과하기' 참조)와 '메타 인스톨 리퍼러' 기술을 모두 구현하는 것으로 구성됩니다. 메타 리퍼러에 대한 자세한 내용은 해당 주제에 대한 FAQ에서 확인하세요.
메타 인스톨 리퍼러 정보를 Singular와 공유하려면 다음과 같이 하세요:
- 앱이 처음 열릴 때 메타의 설명서에 따라 메타 인스톨 리퍼러를 검색합니다.
-
메타_ref 매개변수를 포함한 세션 알림 엔드포인트를 사용하여 Singular에 세션을 보고합니다. 이 매개변수는 JSON으로 인코딩되며 다음과 같은 속성을 가집니다:
속성 설명 is_ct
메타 인스톨 리퍼러로부터 받은 "is_ct"입니다. (예: 0 또는 1) install_referrer
메타 인스톨 리퍼러에서 받은 "install_referrer"입니다. actual_timestamp
메타 설치 리퍼러에서 받은 "실제_타임스탬프"(예: 1693978124).
Singular 링크 지원
딥링크는 사용자를 앱 내의 특정 콘텐츠로 안내하는 클릭 가능한 링크입니다. 사용자가 앱이 설치된 기기에서 딥링크를 클릭하면 앱이 열리고 특정 제품이나 경험이 표시됩니다.
Singular 추적 링크에는 딥링킹뿐만 아니라 디퍼드 딥링킹도 포함될 수 있습니다(자세한 내용은 딥링킹 FAQ 및 Singular 링크 FAQ 참조).
딥링킹 활성화
딥링킹 전제 조건
클라이언트 앱이 Singular 링크를 iOS 유니버설 링크 또는 안드로이드 앱 링크로 인식하도록 구성해야 합니다. iOS 및 Android 딥링킹을 활성화하려면 Singular 링크 전제 조건 가이드를 참조하세요.
딥링크 구현하기
딥링크를 통해 앱이 열리면 openURL을 캡처하여 openuri 매개변수에 URL 값을 추가하여 Singular로 전송된 세션 알림 요청에 추가합니다. 이는 Singular 링크를 사용할 때 필요합니다.
클라이언트 앱 코드를 업데이트하여 Singular 링크 URL의 딥링크 파라미터를 파싱하고 처리해야 합니다. Singular 링크로 인한 딥링크가 성공한 경우, 오픈URL에 다음 파라미터가 존재할 수 있습니다:
_dl, _ios_dl, _android_dl, _p
- _ios_dl 와 _android_dl 는 각 플랫폼마다 다른 딥링크 값을 사용하여 iOS와 Android 모두에서 딥링크로 생성된 링크에 존재할 수 있습니다.
- iOS와 Android의 딥링크 값이 동일한 경우 _dl 만 표시됩니다.
- 패스스루 파라미터에 추가 데이터가 전달되면 _p 가 표시됩니다.
딥링크 핸들러 코드 샘플
앱에는 오픈URL을 파싱하고 적절하게 처리할 수 있는 핸들러 코드가 있어야 합니다. 아래 예제에서 Singular 링크 매개변수를 파싱하는 방법을 확인할 수 있습니다.
class DeepLinkHandler {
func handleURL(_ url: URL) {
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
return
}
var params: [String: String] = [:]
// Parse query parameters
if let queryItems = components.queryItems {
for item in queryItems {
switch item.name {
case "_dl":
params["deeplink"] = item.value
case "_ios_dl":
params["ios_deeplink"] = item.value
case "_p":
params["passthrough"] = item.value
default:
break
}
}
}
// Handle the parsed parameters
processDeepLinkParameters(params)
}
private func processDeepLinkParameters(_ params: [String: String]) {
// Process the parameters as needed
print("Processed parameters: \(params)")
}
}
// In SceneDelegate or AppDelegate
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else { return }
let handler = DeepLinkHandler()
handler.handleURL(url)
}
class DeepLinkHandler {
fun handleDeepLink(intent: Intent) {
val data: Uri? = intent.data
data?.let { uri ->
val params = mutableMapOf<String, String>()
// Parse query parameters
uri.queryParameterNames?.forEach { name ->
when (name) {
"_dl" -> params["deeplink"] = uri.getQueryParameter(name) ?: ""
"_android_dl" -> params["android_deeplink"] = uri.getQueryParameter(name) ?: ""
"_p" -> params["passthrough"] = uri.getQueryParameter(name) ?: ""
}
}
processDeepLinkParameters(params)
}
}
private fun processDeepLinkParameters(params: Map<String, String>) {
// Process the parameters as needed
println("Processed parameters: $params")
}
}
// In your Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Handle deep link if activity was launched from a deep link
intent?.let { DeepLinkHandler().handleDeepLink(it) }
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// Handle deep link if app was already running
intent?.let { DeepLinkHandler().handleDeepLink(it) }
}
}
디퍼드 딥링크 지원
앱을 설치한 후 처음으로 앱을 열면 세션을 Singular에 보고할 때 다음 매개변수를 추가하여 디퍼드 딥링킹 플로우를 활성화하세요 :
- install=true
- ddl_enabled=true
Singular는 디퍼드 딥링크가 포함된 추적 링크를 통해 앱이 설치되었는지 확인합니다. 설치되었다면 세션 요청은 서버에 대한 응답으로 다음 값을 반환합니다:
- deferred_deeplink - 딥링크 주소. 사용자에게 올바른 제품이나 경험을 표시하기 위해 이 값을 파싱해야 합니다.
- deferred_passthrough - 딥링크에 추가된 모든 패스스루 매개변수.
클라이언트 앱은 Singular 세션 API의 응답에 제공된 디퍼드 딥링크 및 패스스루 매개변수를 처리하고 데이터를 적절하게 처리하는 코드를 포함해야 합니다. 디퍼드 딥링크 값이 포함된 SESSION 알림의 응답 JSON은 다음과 같습니다:
{
"deferred_deeplink":"myapp://deferred-deeplink",
"status":"ok",
"deferred_passthrough":"passthroughvalue"
}
동적 패스스루 매개변수 사용
Singular 추적 링크에는 동적 패스스루 매개변수가 포함될 수 있습니다(자세히 알아보기). 조직에서 링크에 동적 패스스루 매개변수를 설정한 경우 딥링크 URL에는 _p 매개변수 뒤에 URL 인코딩된 JSON 문자열 값 또는 사용자에게 적절한 콘텐츠 또는 경험을 표시하는 데 사용할 수 있는 비정형 문자열이 포함됩니다.
짧은 링크 해결
단축된 Singular 링크에서 앱을 여는 경우, 실행 요청에 다음 파라미터를 포함시켜 Singular 세션 엔드포인트에 openuri 파라미터로 전송된 openURL이 Singular 긴 링크로 확인되어야 함을 알려야 합니다.
- singular_link_resolve_required=true
Singular는 단축되지 않은 긴 링크를 반환하고 앱 개발자는 앞서 언급한 대로 링크 핸들러에서 딥링크 및 패스스루 매개변수를 파싱할 수 있습니다.
샘플 응답
{
"status":"ok",
"resolved_singular_link":"https://myapp.sng.link/A59c0/nha7?_dl=myapp%3A%2F%2Fdeeplink&_ddl=myapp%3A%2F%2Fdeferred-deeplink&_p=passthroughvalue"
}
교차 디바이스 지원
Singular의 크로스 디바이스 솔루션을 구현하거나 사용자를 디바이스 수준 세션에 연결할 때 중요한 것은 custom_user_id 매개변수를 효과적으로 활용하는 것이 중요합니다. 이 매개변수에는 내부 사용자 ID가 포함되어야 하지만, 개인 식별 정보(PII)가 포함되지 않도록 하여 데이터 개인정보 보호 정책을 준수하는 것이 필수적입니다.
모범 사례로는 사용자 이름, 이메일 주소 또는 앱의 고유 사용자 식별자 역할을 하는 무작위로 생성된 문자열에서 파생된 해시값을 사용하는 것이 좋습니다. 이 접근 방식을 구현하면 Singular가 포괄적인 크로스 디바이스 보고를 위해 custom_user_id 를 포괄적인 교차 기기 보고, 사용자 수준 데이터 내보내기 및 내부 BI 포스트백(구성된 경우)에 활용하여 사용자 개인정보는 유지하면서 분석 데이터의 세분성과 가치를 향상시킬 수 있습니다.
구매 보고
Singular는 앱을 통해 얻은 구매에 대한 데이터를 수집하여 캠페인의 성과와 ROI를 분석하는 데 도움을 줄 수 있습니다. Singular는 보고서, 내보내기 로그 및 포스트백에서 데이터를 사용할 수 있도록 합니다.
구매 이벤트를 추적하려면 모든 이벤트에 사용하는 것과 동일한 이벤트 알림 엔드포인트를 사용하되, 구매 매개변수를 포함하세요.
- is_revenue_event 이렇게 하면 이벤트가 구매 이벤트로 표시됩니다. 이벤트 이름이 __iap__ 이거나 금액이 0보다 큰 경우 이 매개 변수를 건너뛸 수 있습니다.
- purchase_receipt Android 또는 iOS의 인앱 구매(IAP) 프로세스에서 반환되는 객체입니다. 거래에 대한 전체 세부 정보를 Singular에 제공하고 데이터로 Singular 보고서를 보강하려면 이 파라미터를 Singular에 전달하는 것을 적극 권장합니다.
- receipt_signature (안드로이드에만 해당) 거래를 검증하고 인앱 사기를 방지하기 위해 이 데이터를 Singular에 전달할 것을 적극 권장합니다.
- amt 매출 금액은 더블로 표시된 금액입니다(예: "amt=1.99").
- cur ISO 4217 통화 코드입니다(예: "cur=USD").
앱 클라이언트 코드에서 구독 상태 관리 구현을 가이드로 사용하여 Google의 Play 청구 라이브러리 및/또는 Apple의 스토어키트에서 구매 개체를 가져옵니다. 또한 기기에서 직접 구독 정보를 쿼리하고 구독 상태를 관리할 수도 있습니다. 이러한 세부 정보를 다시 서버로 전달하여 Singular에 이벤트 요청에 포함할 수 있습니다.
샘플 커스텀 구매 이벤트
import requests
params = {
"a": "sdk_key_here",
"p": "Android",
"i": "com.singular.app",
"ip": "10.1.2.3",
"ve": "9.2",
"aifa": "8ecd7512-2864-440c-93f3-a3cabe62525b",
"asid": "edee92a2-7b2f-45f4-a509-840f170fc6d9",
"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": "hakfcimbkargpM",
},
"receipt_signature": "TyVJfHg8OAoW7W4wuJtasr5agEDMnNXvhfrw==",
"purchase_product_id": "com.example.product",
"purchase_transaction_id": "GPA.1234-1234-1234-12345",
}
response = requests.get("https://s2s.singular.net/api/v1/evt", params=params)
print(response.json())
GET /api/v1/evt
?a=sdk_key_here
&p=Android
&i=com.singular.app
&ip=10.1.2.3
&ve=9.2
&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b
&asid=edee92a2-7b2f-45f4-a509-840f170fc6d9
&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":"hakfcimbkargpM"}
&receipt_signature=TyVJfHg8OAoW7W4wuJtasr5agEDMnNXvhfrw==
&purchase_product_id=com.example.product
&purchase_transaction_id=GPA.1234-1234-1234-12345 HTTP/1.1
Host: s2s.singular.net
Accept: application/json
curl -G "https://s2s.singular.net/api/v1/evt" \
--data-urlencode "a=sdk_key_here" \
--data-urlencode "p=Android" \
--data-urlencode "i=com.singular.app" \
--data-urlencode "ip=10.1.2.3" \
--data-urlencode "ve=9.2" \
--data-urlencode "aifa=8ecd7512-2864-440c-93f3-a3cabe62525b" \
--data-urlencode "asid=edee92a2-7b2f-45f4-a509-840f170fc6d9" \
--data-urlencode "n=RevenueEventName" \
--data-urlencode "amt=2.50" \
--data-urlencode "cur=USD" \
--data-urlencode "is_revenue_event=true" \
--data-urlencode "purchase_receipt={\"orderId\":\"GPA.1234\",\"packageName\":\"com.example\",\"productId\":\"com.example.product\",\"purchaseTime\":1417113074914,\"purchaseState\":0,\"purchaseToken\":\"hakfcimbkargpM\"}" \
--data-urlencode "receipt_signature=TyVJfHg8OAoW7W4wuJtasr5agEDMnNXvhfrw==" \
--data-urlencode "purchase_product_id=com.example.product" \
--data-urlencode "purchase_transaction_id=GPA.1234-1234-1234-12345"
앱 삭제 추적
Singular는 디바이스의 무음 푸시 알림을 사용하여 앱 제거를 추적할 수 있습니다. 이를 활성화하려면 모든 세션 알림과 함께 디바이스의 푸시 토큰을 Singular 서버로 전송해야 합니다.
-
Singular 플랫폼과 앱에 대한 제거 추적 설정 가이드를 참조하세요:
- iOS의 경우 APNS 토큰을 apns_token 매개변수에 추가합니다. Android의 경우 FCM 토큰을 파라미터에 추가합니다. fcm 매개변수에 추가합니다.
iOS 설치 영수증 검색
iOS 앱에 대한 세션을 보고할 때 설치 영수증을 install_receipt 파라미터에 전달해야 합니다.
이 값을 검색하려면 앱에 다음 코드를 추가합니다:
// ReceiptManager.h
@interface ReceiptManager : NSObject
+ (nullable NSString *)getInstallReceipt;
@end
// ReceiptManager.m
#import <StoreKit/StoreKit.h>
@implementation ReceiptManager
+ (nullable NSString *)getInstallReceipt {
if (@available(iOS 18.0, *)) {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block NSString *result = nil;
[SKPaymentQueue.defaultQueue addTransactionObserver:[[SKPaymentTransactionObserver alloc] init]];
if (@available(iOS 18.0, *)) {
[AppTransaction.shared fetchWithCompletionHandler:^(AppTransaction *transaction, NSError *error) {
if (error) {
NSLog(@"Failed to get app transaction: %@", error.localizedDescription);
} else {
result = transaction.jwsRepresentation;
}
dispatch_semaphore_signal(semaphore);
}];
}
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return result;
} else {
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
if (!receiptURL) {
NSLog(@"Receipt URL not found");
return nil;
}
NSError *error = nil;
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL
options:NSDataReadingUncached
error:&error];
if (error) {
NSLog(@"Failed to read receipt: %@", error.localizedDescription);
return nil;
}
return [receiptData base64EncodedStringWithOptions:0];
}
}
@end
import Foundation
import StoreKit
class ReceiptManager {
static func getInstallReceipt() -> String? {
if #available(iOS 18.0, *) {
// Synchronous wrapper for async code
let semaphore = DispatchSemaphore(value: 0)
var result: String?
Task {
do {
let transaction = try await AppTransaction.shared
result = transaction.jwsRepresentation
semaphore.signal()
} catch {
debugPrint("Failed to get app transaction: \(error.localizedDescription)")
semaphore.signal()
}
}
semaphore.wait()
return result
} else {
// Legacy receipt fetching
guard let receiptURL = Bundle.main.appStoreReceiptURL else {
debugPrint("Receipt URL not found")
return nil
}
do {
let receiptData = try Data(contentsOf: receiptURL, options: .uncached)
return receiptData.base64EncodedString(options: [])
} catch {
debugPrint("Failed to read receipt: \(error.localizedDescription)")
return nil
}
}
}
}
데이터 개인정보 보호법 준수
Singular는 개인정보 보호 기능을 제공하여 GDPR 및 CCPA와 같은 소비자 개인정보 보호법을 준수하는 모든 파트너와 협력할 수 있도록 지원합니다. 이러한 파트너는 최종 사용자가 개인 정보 공유에 동의한 경우 알림을 받기를 원합니다.
사용자에게 정보 공유에 대한 동의를 요청하는 방법을 구현한 경우, 데이터_공유_옵션 매개변수를 사용하여 사용자의 선택 사항을 Singular에 알립니다:
- "limit_data_sharing":false 을 전달하여 사용자가 정보 공유에 동의(옵트인)했음을 표시합니다.
- 사용자가 거부한 경우 "limit_data_sharing":true 을 전달합니다.
Singular는"사용자 개인정보 포스트백"에서 limit_data_sharing 을 사용할 뿐만 아니라 관련 규정을 준수하기 위해 이 정보를 필요로 하는 파트너에게 전달합니다. 자세한 내용은"사용자 개인정보 및 데이터 공유 제한"을 참조하세요.
참고:
- data_sharing_options 매개변수는 선택 사항이지만, 사용자가 옵트인했음을 구체적으로 고지한 경우에만 파트너가 Singular와 공유할 어트리뷰션 정보가 있을 수 있습니다.