이 문서는 rake-javascript v3.x.x 의 사용법에 대해서 설명합니다. 구 버전의 사용은 다음을 참고하세요.

Basics

아래 내용을 꼭 읽기를 권장합니다.

  • rake-javascript(이하 RC-JS)는 Google Analytics(이하 GA)와 동일하게 비동기로 로딩되어 Page View 또는 Custom Format 로그를 전송합니다.
  • (중요) 사용자 환경 구분을 위해 _$RAKE_ENV 를 입력받습니다.
환경 _$RAKE_ENV
상용서버로 전송 LIVE
개발서버로 전송 DEV

WebView라면 Native와의 통신을 이용해 device_id 값을 가져오거나, 데이터를 Native로 넘겨 Android, iPhone 용 Rake를 이용해 전송할 수 있습니다. 다른 방법으로는 직접 device_id 값을 shuttle 에 입력할 수 있습니다. 다만 이 경우 포맷은 String 이어야 올바르게 암호화가 됩니다. 예를 들어 {"device_id_from_web": "48FFAA"} 는 암호화를 지원하지 않습니다. (escaping 된 값의 경우 가능하나, 권장하지 않습니다.)

Mobile Web이나 Web이라면 uuid 값을 device_id 값 대용으로 사용할 수 있습니다.(Web view에서도 생성 및 전송 가능). 단 uuid 값을 shuttle의 header에 포함시켜야 하고 포맷은 String이어야 합니다.

  • XHR을 지원하지 않는 브라우저를 위해서 XDR을 이용해 지원합니다. 다만 XDR Limitation 때문에 HTTPS(Rake Server)로 전송하려면, Client 페이지 또한 HTTPS 이어야 합니다.
  • 비동기로 로딩되는 스크립트의 사이즈는 브라우저 종류에 따라 다르며 이는 브라우저 호환성을 맞추기 위한 Polyfill 때문입니다.
브라우저 종류 스크립트 사이즈 스크립트 이름
Modern 27 KB rake.bundle.js
IE 9, 10 25 KB rake.bundle-ie.js
IE 8 47 KB rake.bundle-ie8.js

Usage

1. Sentinel Shuttle

  • RakeSentinel-Shuttle 과 같이 사용됩니다. Shuttle 은 로그 디자이너가 정의한 포맷에 맞게 로그를 남길 수 있도록 도와주는 POJO (= DTO, VO) 입니다. 따라서 Shuttle 없이는 Rake 를 사용할 수 없습니다.
  • Shuttle을 Sentinel에서 다운받아 <script> 태그를 이용해 추가합니다. 이 예제에서는 Shuttle 클래스의 이름을 MyAppShuttle 이라 가정하겠습니다.

2. Snippet

  • Snippet 코드를 통해서 비동기로 로딩되는 RC-JS의 동작을 제어할 수 있습니다.

2-1. Snippet 사용방법

  • 아래 Snippet 코드를 Copy하여 애플리케이션 스크립트 상단에 넣어주세요.
<!-- start RC-JS --><script type="text/javascript">
// RC-JS를 비동기로 로딩하는 Snippet 입니다.
(function () {function a(r,e,$){return e in r?Object.defineProperty(r,e,{"value":$,"enumerable":!0,"configurable":!0,"writable":!0}):r[e]=$,r}var j=function(e){return e.userAgent.toLowerCase()};var l=function(e){var r=e.userAgent;return"Netscape"===e.appName&&r.indexOf("trident")>-1||r.indexOf("msie")>-1||r.indexOf("edge")>-1};var k=function(e){return e.indexOf("msie")<0?0:parseInt(e.split("msie")[1],10)};var b="RAKE";var f="_$OPTIONS";var g="_$loaded";var i="_$cb";var c="_$RAKE_ENV";var h="_$SV";var d="_$RAKE_MODE";var m=function(e,t){var r=!(arguments.length>2&&arguments[2]!==undefined)||arguments[2],$={};for(var o in e)e.hasOwnProperty(o)&&($[o]=e[o]);for(var n in t)t.hasOwnProperty(n)&&(r?$[n]=t[n]:e[n]=t[n]);return r?$:e};var n="1.0",o="rake.bundle.js",p="rake.bundle-ie8.js",q="rake.bundle-ie.js",e=function(r,e){return{"init":function($){e[h]||(function(){var r,$=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};m(e,(a(r={},g,!1),a(r,f,$[f]||{}),a(r,d,$[d]||[]),a(r,c,$[c]||"LIVE"),a(r,h,n),a(r,i,function(){}),r),!1)}($),function(){if(!r.getElementById(b)){var $=r.createElement("script"),t=r.getElementsByTagName("script")[0];$.id=b,$.type="text/javascript",$.async=!0,$.src=function(r){var e="DEV"===r?"https://pg.rake.skplanet.com:8443/log/static/js/rake/new/current":"LIVE"===r?"https://rake.skplanet.com:8443/log/static/js/rake/new/current":"",$=window.navigator,t=$.appName,c=j($),n="".concat(e,"/").concat(o);if(l({"userAgent":c,"appName":t})){var i=k(c);8===i?n="".concat(e,"/").concat(p):i>8&&i<11&&(n="".concat(e,"/").concat(q))}return n}(e[c]),t.parentNode.insertBefore($,t)}}(),function(){if(!e[g])for(var r=["track","flush","create","remove","collect","autoTrack","setServerURL","setServerPort","excludeAutoProperties"],$=function($,t){var c=r[$];e[c]=function(){var r=Array.prototype.slice.call(arguments,0),$=[c];$=$.concat(r),e.push($)}},t=0,c=r.length;t<c;t++)$(t,c)}(),window[b]=e)}}}(document,window[b]||[]);window.snippet=e;})();

// Snippet 옵션 설정
snippet.init();
</script><!-- end RC-JS -->

2-2. Snippet 옵션

  • RC-JS 동작 제어용 옵션
설명 필수 타입
_$RAKE_ENV 사용자 환경 구분 (상용(기본):LIVE, 개발:DEV) X String
_$RAKE_MODE RC-JS + α의 기능 (현재는 DMP만 지원) X Array
_$OPTIONS RC-JS 동작에 필요한 값 X Object
  • _$OPTOINS 값
설명 필수 타입
isBeacon 브라우저의 Beacon 기능 사용 유무 X Boolean
isCookieSync DMP의 PIXEL(Cookie Sync) API 연동 유무 X Boolean
nid DMP의 PIXEL API 연동 시 사용하는 제휴사 식별자 X String
uid DMP의 PIXEL API 연동 시 사용하는 제휴사 사용자 식별자 X String
  • 예제
// Snippet 옵션 설정
snippet.init({
	_$RAKE_ENV: 'DEV',
	_$RAKE_MODE: ['DMP'],
	_$OPTIONS: {
		isBeacon: true,
		isCookieSync: true,
		nid: '제휴사 식별자',
		uid: '제휴사 사용자 식별자'
	}
});

2-3. Snippet 옵션을 통한 RC-JS 기능

1) DMP 기능
  • 자체적으로 DMP의 도메인 비실명 Cookie UID를 운영하고 PIXEL(Cookie Sync)를 사용하는 경우 _$OPTIONS 필드에 isCookieSync, nid, uid 를 설정합니다.
2) Beacon 기능
  • Beacon 은 페이지 전환 시 전송 요청이 취소(XDR 혹은 XHR)되는 브라우저의 특징을 보완하여 Beacon 으로 로그 전송을 보장합니다. (RC-JS 기본 전송모드: XDR 혹은 XHR)
  • _$OPTIONS 필드에 isBeacon 을 true로 설정하면, Beacon 모드로 전송합니다. 다만 true 값이지만 Beacon 을 지원하지 않는 브라우저(IE)에서는 XDR 혹은 XHR로 전송이 됩니다.
  • Beacon 전송 시 successCallback, failureCallback, timeoutAsMillis 비활성 됩니다.

3. Rake API

3-1 create()

  • Rake 인스턴스를 생성한다.
  • DMP 기능
    • DMP 기능을 사용하기 위해서 snippet.init()_$RAKE_MODE: ['DMP'] 를 추가합니다.
    • DMP 모듈을 사용 시 PIXEL API를 호출하여 dmp_uid 를 발급 받고, 이후 GETUID API를 통해서 DMP 에서 발급된 dmp_uid 를 localStorage에 저장합니다.
    • localStorage에 저장된 dmp_uid 를 Payload의 header에 저장하여 보내기 위해서 Rake Instance 생성 시 isDMP 을 넣어야 합니다. (다중 Instance 지원 때문)
  • UUID 기능
    • UUID 기능을 사용하기 위해서 RAKE Instance 생성 시 Parameters에 uuid:true를 입력합니다.
    • UUID 기능 사용 시, localStorage에 RAKE:uuid를 key값으로 identifier를 생성,저장하고 전송합니다.
    • localStorage에 저장된 RAKE:uuid를 Payload의 header에 저장하여 보내기 위해서 Rake Instnace 생성 시 uuid를 true로 설정해야 합니다.
  • Parameters
설명 필수 타입
instanceAlias Instance 별칭 (다중 Instance 사용 시 필수이며, 설정 시 다른 API(예: track 등)에서도 설정해야함) X String
token Sentinel에서 발급받은 Token 값 O String
isDMP DMP 기능 활성 유무 (기본: false) X Boolean
uuid UUID 기능 활성 유무 (기본: false) X Boolean
filters URL이 모두 매칭될 경우에만 전송 X Array
converters URL Query 혹은 Cookie 값을 Payload로 설정해서 전송 X Array
  • filters
설명 필수 타입
type 현재는 URL_INCLUDES_ALL(URL 모두 매칭)만 지원 O String
patterns URL에 매칭할 키워드 (없거나 빈 배열일 경우 모두 전송) X Array
  • converters
설명 필수 타입
type URL_QUERY_TO_PAYLOAD, COOKIE_TO_PAYLOAD O String
from URL Query 혹은 Cookie에서 사용할 Key 값 O String
to Payload에 설정할 Key 값 O String

% Payload 설정 시 body에 설정하고 싶으면, _$body.TO값 설정 (예: body의 속성으로 user_session 을 설정하고 싶으면 _$body.user_session)

  • 예제
// Rake Instance 생성
RAKE.create({
  instanceAlias: 'Instance 별칭',
  token: 'Sentinel에서 발급받은 Token 값',
  isDMP: true,
  uuid: true,
  filters: [
    { type: 'URL_INCLUDES_ALL', patterns: ['localhost', 'index.html'] }
  ],
  converters: [
    // URL에서 QueryString 중 userSession 값을 추출하여 body의 user_session 필드에 삽입
    { type: 'URL_QUERY_TO_PAYLOAD', from: 'userSession', to: '_$body.user_session' },

    // URL에서 QueryString 중 userId 값을 추출하여 header의 user_id 필드에 삽입
    { type: 'URL_QUERY_TO_PAYLOAD', from: 'userId', to: 'user_id' },

    // 브라우저 Cookie에서 cookieSession 값을 추출하여 header의 cookie_session 필드에 삽입
    { type: 'COOKIE_TO_PAYLOAD', from: 'cookieSession', to: 'cookie_session' }
  ]
});

3-2 autoTrack()

  • create() + track() 기능
  • Parameters
설명 필수 타입
instanceAlias Instance 별칭 (다중 Instance 사용 시 설정) X String
token Sentinel에서 발급받은 Token 값 O String
shuttle Shuttle 생성자 명 (Payload 생성용) O String
isDMP DMP 기능 활성 유무 (기본: false) X Boolean
uuid UUID 기능 활성 유무 (기본: false) X Boolean
filters URL이 모두 매칭될 경우에만 전송 (상세 코드는 3-1 create() 참조) X Array
converters URL Query 혹은 Cookie 값을 Payload로 설정해서 전송 (상세 코드는 3-1 create() 참조) X Array
timeoutAsMillis 전송 Timeout 밀리초 (기본: 15000) X Number
successCallback 전송 성공 시 Callback X Function
failureCallback 전송 실패 시 Callback X Function
  • 예제
// Rake Instance 자동 생성 및 전송
RAKE.autoTrack({
  instanceAlias: 'Instance 별칭',
  token: 'Sentinel에서 발급받은 Token 값',
  shuttle: MyAppShuttle, // Shuttle 생성자 명
  isDMP: true,
  uuid: true,
  filters: [
    { type: 'URL_INCLUDES_ALL', patterns: ['localhost', 'index.html'] }
  ],
  converters: [
    // URL에서 QueryString 중 userSession 값을 추출하여 body의 user_session 필드에 삽입
    { type: 'URL_QUERY_TO_PAYLOAD', from: 'userSession', to: '_$body.user_session' },

    // URL에서 QueryString 중 userId 값을 추출하여 header의 user_id 필드에 삽입
    { type: 'URL_QUERY_TO_PAYLOAD', from: 'userId', to: 'user_id' },

    // 브라우저 Cookie에서 cookieSession 값을 추출하여 header의 cookie_session 필드에 삽입
    { type: 'COOKIE_TO_PAYLOAD', from: 'cookieSession', to: 'cookie_session' }
  ],
  timeoutAsMillis: 1000,
  successCallback: function() { console.log('SUCCESS CALLBACK') },
  failureCallback: function() { console.log('FAILURE CALLBACK') }
});

3-3 track()

  • Payload를 메모리(localStorage)에 적재하고 바로 전송합니다. (1건씩 처리용, collect() + flush() 기능)
  • Parameters
설명 필수 타입
instanceAlias Instance 별칭 (다중 Instance 사용 시 필수이며, 설정 시 다른 API(예: track 등)에서도 설정해야함) X String
payload Shuttle을 이용한 Payload 값 O Object
timeoutAsMillis 전송 Timeout 밀리초 (기본: 15000) X Number
successCallback 전송 성공 시 Callback X Function
failureCallback 전송 실패 시 Callback X Function
  • 예제
// 전송할 Payload 생성
const shuttle = new MyAppShuttle();
shuttle.setAction_id('view');
shuttle.setPage_id('49E-FF01');
const myPayload = shuttle.getImmutableJSONObject();

// Payload 전송
RAKE.track({
	instanceAlias: 'Instance 별칭', // create()에서 설정한 instanceAlias
	payload: myPayload,
	timeoutAsMillis: 1000,
	successCallback: function() { console.log('SUCCESS CALLBACK') },
	failureCallback: function() { console.log('FAILURE CALLBACK') }
});

3-4 collect()

  • Payload를 리스트 형태로 메모리(localStorage)에 적재합니다. (전송 실패 및 유실 방지용)
  • DMP 기능
    • create() 생성 시 isDMP: true 이면, localStorage에 저장된 dmp_uid 를 header의 dmpc 에 설정
  • UUID 기능
    • create() 생성 시 uuid: true 이면, localStorage에 저장된 RAKE:uuid 를 header의 uuid 에 설정
  • Parameters
설명 필수 타입
instanceAlias Instance 별칭 (다중 Instance 사용 시 필수이며, 설정 시 다른 API(예: track 등)에서도 설정해야함) X String
payload Shuttle을 이용한 Payload 값 O Object
  • 예제
// 전송할 Payload 생성 및 적재 01
const shuttle = new MyAppShuttle();
shuttle.setAction_id('view');
shuttle.setPage_id('49E-FF01');

RAKE.collect({
	instanceAlias: 'Instance 별칭', // create()에서 설정한 instanceAlias
	payload: shuttle.getImmutableJSONObject()
});

// 전송할 Payload 생성 및 적재 02
shuttle.setAction_id('click');
shuttle.setPage_id('49E-FF02');

RAKE.collect({
	instanceAlias: 'Instance 별칭', // create()에서 설정한 instanceAlias
	payload: shuttle.getImmutableJSONObject()
});

3-5 flush()

  • 리스트 형태로 메모리(localStorage)에 적재된 Payload를 서버에 전송합니다.
  • 전송 실패시 메모리에 재적재합니다. (메모리 적재 사이즈: 100개)
  • Parameters
설명 필수 타입
instanceAlias Instance 별칭 (다중 Instance 사용 시 필수이며, 설정 시 다른 API(예: track 등)에서도 설정해야함) X String
timeoutAsMillis 전송 Timeout 밀리초 (기본: 15000) X Number
successCallback 전송 성공 시 Callback X Function
failureCallback 전송 실패 시 Callback X Function
  • 예제
// 전송
RAKE.flush({
	instanceAlias: 'Instance 별칭', // create()에서 설정한 instanceAlias
	timeoutAsMillis: 1000,
	successCallback: function() { console.log('SUCCESS CALLBACK') },
	failureCallback: function() { console.log('FAILURE CALLBACK') }
});

예제 코드

<html lang="en">
  <body>
    <!-- start RC-JS --><script type="text/javascript">
    // RC-JS를 비동기로 로딩하는 Snippet 입니다.
    (function () {function a(r,e,$){return e in r?Object.defineProperty(r,e,{"value":$,"enumerable":!0,"configurable":!0,"writable":!0}):r[e]=$,r}var j=function(e){return e.userAgent.toLowerCase()};var l=function(e){var r=e.userAgent;return"Netscape"===e.appName&&r.indexOf("trident")>-1||r.indexOf("msie")>-1||r.indexOf("edge")>-1};var k=function(e){return e.indexOf("msie")<0?0:parseInt(e.split("msie")[1],10)};var b="RAKE";var f="_$OPTIONS";var g="_$loaded";var i="_$cb";var c="_$RAKE_ENV";var h="_$SV";var d="_$RAKE_MODE";var m=function(e,t){var r=!(arguments.length>2&&arguments[2]!==undefined)||arguments[2],$={};for(var o in e)e.hasOwnProperty(o)&&($[o]=e[o]);for(var n in t)t.hasOwnProperty(n)&&(r?$[n]=t[n]:e[n]=t[n]);return r?$:e};var n="1.0",o="rake.bundle.js",p="rake.bundle-ie8.js",q="rake.bundle-ie.js",e=function(r,e){return{"init":function($){e[h]||(function(){var r,$=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};m(e,(a(r={},g,!1),a(r,f,$[f]||{}),a(r,d,$[d]||[]),a(r,c,$[c]||"LIVE"),a(r,h,n),a(r,i,function(){}),r),!1)}($),function(){if(!r.getElementById(b)){var $=r.createElement("script"),t=r.getElementsByTagName("script")[0];$.id=b,$.type="text/javascript",$.async=!0,$.src=function(r){var e="DEV"===r?"https://pg.rake.skplanet.com:8443/log/static/js/rake/new/current":"LIVE"===r?"https://rake.skplanet.com:8443/log/static/js/rake/new/current":"",$=window.navigator,t=$.appName,c=j($),n="".concat(e,"/").concat(o);if(l({"userAgent":c,"appName":t})){var i=k(c);8===i?n="".concat(e,"/").concat(p):i>8&&i<11&&(n="".concat(e,"/").concat(q))}return n}(e[c]),t.parentNode.insertBefore($,t)}}(),function(){if(!e[g])for(var r=["track","flush","create","remove","collect","autoTrack","setServerURL","setServerPort","excludeAutoProperties"],$=function($,t){var c=r[$];e[c]=function(){var r=Array.prototype.slice.call(arguments,0),$=[c];$=$.concat(r),e.push($)}},t=0,c=r.length;t<c;t++)$(t,c)}(),window[b]=e)}}}(document,window[b]||[]);window.snippet=e;})();

    // Snippet 옵션 설정
    snippet.init({
        _$RAKE_ENV: 'DEV',
        _$RAKE_MODE: ['DMP'],
        _$OPTIONS: {
            isBeacon: true,
            isCookieSync: true,
            nid: '제휴사 식별자',
            uid: '제휴사 사용자 식별자'
        }
    });
  </script><!-- end RC-JS -->
    <!-- Shuttle 스크립트 로딩 -->
    <script src="./shuttle/MyAppShuttle.js"></script>
    <script type="text/javascript">
      const test = () => {
      // Rake Instance 생성
      RAKE.create({
        instanceAlias: 'Instance 별칭',
        token: 'Sentinel에서 발급받은 Token 값',
        isDMP: true,
        uuid: true,
        filters: [
          { type: 'URL_INCLUDES_ALL', patterns: ['localhost', 'index.html'] }
        ],
        converters: [
          // URL에서 QueryString 중 userSession 값을 추출하여 body의 user_session 필드에 삽입
          { type: 'URL_QUERY_TO_PAYLOAD', from: 'userSession', to: '_$body.user_session' },

          // URL에서 QueryString 중 userId 값을 추출하여 header의 user_id 필드에 삽입
          { type: 'URL_QUERY_TO_PAYLOAD', from: 'userId', to: 'user_id' },

          // 브라우저 Cookie에서 cookieSession 값을 추출하여 header의 cookie_session 필드에 삽입
          { type: 'COOKIE_TO_PAYLOAD', from: 'cookieSession', to: 'cookie_session' }
        ]
      });

      /*
       * track() 테스트
       */
      // 전송할 Payload 생성
      const shuttle = new MyAppShuttle();
      shuttle.setAction_id('view');
      shuttle.setPage_id('49E-FF01');
      const myPayload = shuttle.getImmutableJSONObject();

      // Payload 전송
      RAKE.track({
      instanceAlias: 'Instance 별칭', // create()에서 설정한 instanceAlias
      payload: myPayload,
      timeoutAsMillis: 1000,
      successCallback: function() { console.log('SUCCESS CALLBACK for Track') },
      failureCallback: function() { console.log('FAILURE CALLBACK for Track') }
    });


      /*
       * collect() + flush() 테스트
       */
      // 전송할 Payload 생성 및 적재 01
      // const shuttle = new MyAppShuttle(); // 앞에서 선언해서 주석 처리
      shuttle.setAction_id('view');
      shuttle.setPage_id('49E-FF01');

      RAKE.collect({
      instanceAlias: 'Instance 별칭', // create()에서 설정한 instanceAlias
      payload: shuttle.getImmutableJSONObject()
    });

      // 전송할 Payload 생성 및 적재 02
      shuttle.setAction_id('click');
      shuttle.setPage_id('49E-FF02');

      RAKE.collect({
      instanceAlias: 'Instance 별칭', // create()에서 설정한 instanceAlias
      payload: shuttle.getImmutableJSONObject()
    });

      // 전송
      RAKE.flush({
      instanceAlias: 'Instance 별칭', // create()에서 설정한 instanceAlias
      timeoutAsMillis: 1000,
      successCallback: function() { console.log('SUCCESS CALLBACK for Collect + Flush') },
      failureCallback: function() { console.log('FAILURE CALLBACK for Collect + Flush') }
    });
    };
      setTimeout(test, 1000);

      const test_autoTrack = () => {
      // Rake Instance 자동 생성 및 전송
      RAKE.autoTrack({
        instanceAlias: 'Instance 별칭',
        token: 'Sentinel에서 발급받은 Token 값',
        shuttle: MyAppShuttle, // Shuttle 생성자 명
        isDMP: true,
        uuid: true,
        filters: [
          { type: 'URL_INCLUDES_ALL', patterns: ['localhost', 'index.html'] }
        ],
        converters: [
          // URL에서 QueryString 중 userSession 값을 추출하여 body의 user_session 필드에 삽입
          { type: 'URL_QUERY_TO_PAYLOAD', from: 'userSession', to: '_$body.user_session' },

          // URL에서 QueryString 중 userId 값을 추출하여 header의 user_id 필드에 삽입
          { type: 'URL_QUERY_TO_PAYLOAD', from: 'userId', to: 'user_id' },

          // 브라우저 Cookie에서 cookieSession 값을 추출하여 header의 cookie_session 필드에 삽입
          { type: 'COOKIE_TO_PAYLOAD', from: 'cookieSession', to: 'cookie_session' }
        ],
        timeoutAsMillis: 1000,
        successCallback: function() { console.log('SUCCESS CALLBACK for AutoTrack') },
        failureCallback: function() { console.log('FAILURE CALLBACK for AutoTrack') }
      });
    };
      // setTimeout(test_autoTrack, 1000);
    </script>
    <h1>RakeApp-Example</h1>
  </body>
</html>