Flutter AppsFlyer OneLink 연동 및 테스트 과정

부리부리대마왕·2025년 4월 30일
0
post-thumbnail

개요

사내 서비스에서 조만간 앱 가입 이벤트를 열기로 했다. 이벤트가 열리기 전에, 유저가 어떤 경로로 앱을 설치했는지 트래킹 해두는 기능이 있다면 이벤트 결과 지표에 도움이 될 수 있을 것 같았다.

그래서 Deferred Deep Link + 마케팅 트래킹을 지원하는 링크 서비스들을 좀 찾아봤고, 그 중에 AppsFlyerOneLink서비스를 사용하기로 결정했다. 내 기준에 사용성이 괜찮았고, 무엇보다 Flutter SDK관련 지원이 잘 되어있는 것 같았다. 그래서 AppsFlyer를 사용해서 설치 유입 경로 트래킹 기능을 구축해봤고, 그 과정을 작성해보려고 한다.



OneLink란?

  • OneLink는 표준화된 기술 용어가 아니라, AppsFlyer만의 브랜드 네이밍이다.
  • 기본 개념은 Firebase Dynamic Links와 유사하며, 단일 링크로 다양한 상황(앱 설치 여부, 플랫폼, 딥링크 이동)을 처리한다.
  • 기술적으로는 Deep Link + Deferred Deep Link + OS 분기 + 마케팅 트래킹 기능을 하나로 패키징한 링크 서비스다.
  • 앱 내부에서는 Unified Deep Linking (UDL) 시스템을 통해 딥링크 데이터를 수신하고 제어한다.
  • OneLink의 기본 도메인은 xxx.onelink.me 형태를 갖는다.
    • 자체 커스텀 도메인을 사용하려면 별도 DNS 설정 및 HTTPS 인증서 설정이 필요함
    • 커스텀 도메인은 엔터프라이즈 플랜 또는 추가 요금제로 제공

앱이 설치되지 않은 상태에서 딥링크를 클릭한 사용자에게, 앱 설치 후에도 원래 딥링크의 목적지로 이동시키는 기술. 특정 링크를 통해 앱을 설치한 사용자들은 설치 후에도 유입된 링크의 목적에 따라 액션을 취해줄 수 있다.


Unified Deep Linking

다양한 딥링크 유입(Universal, App Link, URL Scheme, Deferred)을 SDK내부에서 하나의 콜백 규약으로 통합해서 앱에 전달하는 시스템
즉, 모든 링크들을 하나의 gateway에서 관리하는 규약(프로토콜) 및 방식을 칭한다.



🍳 One Link의 구조

Flow

사용자 OneLink 클릭
    ↓
디바이스에서 앱 설치 여부 확인
    ↓
(설치됨) → Universal/App Link → 앱 열림
(미설치) → 스토어 이동 → 설치 후 앱 열림
    ↓
앱 열림 → AppsFlyer SDK 트리거
    ↓
SDK가 딥링크 데이터 조회
    ↓
앱에 딥링크 데이터 전달 (onDeepLinking 콜백)
    ↓
앱에서 deep_link_value 파싱 → 이동 처리

OneLink는 링크 히스토리를 어떻게 기록하고 사용하는지?

  • OneLink 클릭 시 디바이스 정보(IDFA/GAID, IP, User Agent 등)를 AppsFlyer 서버에 저장한다.
  • 디바이스에는 별도의 저장을 하지 않는다. (100% 서버 사이드 저장)
  • 앱 설치 후 첫 실행 시, SDK가 서버에 디바이스 정보를 전송하여 과거 클릭 기록과 매칭을 시도한다.
  • 매칭에 성공하면, 클릭 시 저장된 OneLink 데이터(deep_link_value 등)를 앱에 전달하여 딥링크 처리를 진행한다.

"OneLink는 디바이스가 아니라 AppsFlyer 서버에 클릭 히스토리를 저장하고, SDK가 앱 실행 시 서버에 조회해서 데이터를 가져오는 구조이다."


링크 파라미터를 어떻게 관리하는지?

대표적으로 4개의 링크 파라미터를 통해 관리한다.

1. PID (Media Source)

  • 유입된 마케팅 채널을 식별하기 위한 ID
  • 고유한 ID가 아님 - 여러 개의 링크가 같은 pid 를 가질 수 있다.
  • 대시보드에서 설치 유입 분석 시 필터 기준으로 사용된다.
  • ex) dev_kakao_inviteprod_event_landing 등

2. Campaign

  • 같은 채널(pid) 안에 세부 캠페인을 구분하기 위해 사용
  • AB 테스트, 이벤트, 시기 구분 등에 유용
  • ex) landing_mayevent_0422abtest_group_b
  • 앱 내 딥링크 유입 여부 판단 및 라우팅 제어용 값
  • 어떤 링크인지 식별하거나, 앱 내부 경로로 매핑할 수 있는 키워드
  • 실 데이터를 넣는 용도는 아님 -> 그건 af_subX 사용
  • ex) from_onelinksignup_landing 등

4. af_sub

  • 실데이터(예: userId, eventID, couponCode 등)를 전달하기 위한 커스텀 파라미터 필드
  • 앱 내에서 파싱하여 특정 액션을 처리
  • ex) af_sub1=user_123af_sub2=campain_spring

링크 파라미터 사용 예시

https://graphic.onelink.me/abc123?
  pid=prod_web_direct
  &c=main_banner
  &deep_link_value=ViewerPage
  &af_sub1=1234(episodeId)
  • pid (채널명): 웹에서 모바일로 직접 이동시키기 때문에 채널명을 <환경>_web_direct 로 명명
  • campaign: 그래픽 웹 내 어느 영역에서 클릭했는지 구분하기 위해 사용
  • deep_link_value: viewer 페이지로 이동시키기 위해 설정
  • af_sub1: episodeId 를 받아 파라미터로 활용하기 위해 설정



1. 새 링크 생성

AppsFlyer 대시보드 → Engage → OneLink Management → New Link 를 클릭해서 새로운 링크를 만들어준다. 카테고리를 선택한 뒤, 링크의 이벤트 이름(media source) 을 넣어준다.


2. General settings

링크의 기본적인 값들을 세팅하는 단계이다. 위에서 설정한 media source 값을 다시 설정할 수 있고, campaign값도 설정할 수 있다. (campaign 은 생략 가능) Retargeting, Link branding은 필요가 없어 따로 설정하진 않았다.


3. Custom experience settings

링크의 Preview가 필요한 경우 세팅. 별도로 필요가 없다면 스킵해도 된다.


4. Deep linking & redirection

실제 딥링크에 들어갈 변수값을 설정한다. 이 단계에선 deep_link_value 값과 deep_link_sub1 값을 설정하는데, 해당 변수들은 앱 내에서 분기 조건으로 사용되는 값이 된다.


앱 설치 여부에 따라 Redirect시킬 주소들을 넣는다.

앱이 설치 된 경우

iOS, Android에 설정한 OneLink의 주소로 Universal/App Link가 작동된다.


앱이 설치되지 않은 경우

AppsFlyer는 등록한 앱의 Package Name(Android)과 App ID(iOS)에 해당하는 스토어 주소로 Redirect 시켜준다.


5. Additional parameters

딥링크의 부가 파라미터 정보들을 담는 af_sub 값을 지정한다. Add parameter를 클릭하면 드롭다운 옵션이 나온다.



void _setupDeepLinkingListener() {
    _appsflyerSdk.onDeepLinking((DeepLinkResult result) {
      Logger.log('AppsFlyerService onDeepLinking', type: LogType.deeplink);

      if (_hasActiveListener) {
        _deepLinkController.add(result);
      } else {
        _bufferedDeepLinks.add(result);
      }
    });
  }

Deferred Deep Link의 경우, 앱이 실행된 후 즉시 리스너가 동작할 수 있다. 만약 딥링크 콜백이 실행 된 순간에 아직 시스템이 온전하게 초기화 되지 않았을 경우, 딥링크 액션이 실행되지 않을 수 있다. Deferred는 설치 후 딱 1회만 적용되기 때문에, 이런 누락 케이스가 발생 할 경우가 생기면 안된다.

따라서 정답은 아니지만, 딥링크가 누락 될 경우를 대비해 버퍼를 사용하여 들어오는 링크 정보들을 모두 저장한 후 시스템 초기화가 완전히 끝난 후 남아있는 딥링크 액션들을 처리해주는 방식을 사용하면 누락 위험을 줄여줄 수 있다.



🧪 테스트

Deferred Deep Link의 테스트가 어려운 이유는, 실제로 링크를 타고 스토어로 들어가 앱을 설치 후 실행시켜서 링크가 동작하는지 확인해봐야 하기 때문이다. 연동을 해보면서 개발 및 운영에서 간단하게 테스트 할 방법들을 찾았고, 아래에 방법들을 작성해봤다. (Test Documentation)


AppsFlyer 테스터 Device 등록

  1. AppStore DeviceId 설치 후 로그인을 통해 IDFA 를 확인한다.
  2. AppsFlyer Test Device 대시보드에서 Device 추가
  3. 등록된 디바이스는 모든 앱에서 테스트 디바이스로 인식되어 반복 설치 시에도 새로운 설치로 처리된다.

운영 환경 테스트

테스터 디바이스로 등록되면, 앱을 지웠다 다시 깔아도 새로운 설치로 처리되기 때문에 Deferred Deep Link의 동작을 확인할 수 있다. 딥링크 이벤트를 수신 시, Sentry 혹은 GA 같은 이벤트 트래킹 툴을 사용하여 확인할 수 있다.


개발 환경 테스트 (+디버깅)

원래 개발 환경에서는 테스트를 할 수 없지만(스토어에 올라가있지 않기 때문에) 야매로 동작을 확인할 수 있는 방법이 있다. (Test Device가 등록되어있다는 가정 하에 진행)

  1. 개발 앱 삭제
  2. 개발 환경으로 만든 One Link 클릭 (어차피 스토어 없어서 잘 안됨. 그냥 클릭만 하자)
  3. 개발 앱 다시 디버깅 혹은 재 설치
  4. 디버깅으로 AppsFlyer SDK의 onDeepLink 수신 확인

개발 환경에서 테스트가 가능한 이유

  1. One Link는 클릭 시 기기에 클릭 정보와 링크 등을 저장한다.
  2. 앱이 나중에 설치되면, SDK가 디바이스 정보를 조회해서 클릭 정보를 역추적한다.
  3. SDK는 IDFA(iOS), GAID(Android) 기준으로 같은 디바이스를 구분해서 "앱 설치 전 클릭"을 기억하고 있다가 Deferred로 연결한다.
  4. 개발 앱도 삭제 후 다시 설치하는 과정이 있었고, 테스터 디바이스로 등록 되어있는 기기를 사용하기 때문에 디버깅 환경으로도 들어오는 Deferred Deep Link에 대해 확인할 수 있게 된다.



🍺 결과

AppsFlyer OneLink수신 시 Sentry에 Event를 적재시켰고, Sentry에서 확인 한 결과 Deferred와 일반 딥링크가 구분되어 로그가 적재되었다. 추후에 가입 이벤트가 생길 시 파라미터랑 캠패인을 잘 조합해서 유입 경로 및 마케팅 지표를 추적할 수 있게 되었다!

0개의 댓글