Youtube 동영상 GTM Tracking Test

출처: http://eroi.com/ideas/definitive-guide-to-tracking-video-with-google-analytics-part-1-youtube/

Posted by 값진인생
,

<문제>

여러 마케팅 캠페인을 새로 시작하여, 특정일에 목표 전환율이 10% 이상 증가하는 캠페인이 있으면 알림을 받으려고 합니다. Google 애널리틱스에서 이 알림을 설정할 대 사용하는 도구는 무엇입니까?

A. 주석

B. 지능형 이벤트

C. 실시간

D. 2차 측정기준

E. 고급 세그먼트

<풀이>

<문제>

이전에 사이트에서 이미 발생한 적이 있는 트래픽의 비율을 확인하는 데 사용하는 보고서는 무엇입니까?

A. 행동 - 신규 방문 VS. 재방문 보고서

B. 행동 - 방문 빈도 및 최근 구매일 보고서

C. 관심분야 - 관심도 카테고리 보고서

D. 전체 트래픽 - 추천 보고서

E. 전자상거래 - 매출 실적 보고서

<풀이>

<문제>

Google 애널리틱스에서 광고 기능을 활성화하여 이용할 수 있는 보고서 또는 데이터 수집 기능은 무엇입니까?

A. 리마케팅

B. 관심분야 카테고리

C. 인구통계 보고서

D. B와 C만 정답

E. A, B, C 모두 정답

<풀이>

<문제>

리마케팅에 Google 애널리틱스를 사용할 때의 이점은 무엇입니까?

A. 맞춤 광고를 활용해 이전에 사이트를 방문했던 고객을 타겟팅할 수 있음

B. Google 애널리틱스의 기존 태그를 변경하지 않고도 리마케팅 목록을 만들 수 있음

C. 30일 동안 사이트를 2회 이상 방문한 사용자 등의 맞춤 세그먼트 및 타겟을 기반으로 리마케팅 목록을 만들 수 있음

D. A와 C만 정답

E. A, B, C 모두 정답

<풀이>

<문제>

시나리오: Google 상품 매장에서 최근 반응형 모바일 웹사이트를 만들어 새로운 광고 캠페인을 운영하기 시작했는데, Google 애널리틱스에서 전반적인 트래픽을 살펴보니 이탈률이 85%였습니다. 이탈률이 높은 원인을 확인하기 위해 트래픽을 분석할 때 유용한 측정기준은 다음 중 무엇입니까?

A. 기기 카테고리

B. 방문 페이지

C. 캠페인

D. A와 C만 정답

E. A, B, C 모두 정답

<풀이>


Posted by 값진인생
,

<Sample Html5 Video>

Source: http://html5demos.com/video

현재시작총 재생 시간

0

0

0

<참고 자료>

- HTML5 Video: https://www.w3.org/2010/05/video/mediaevents.html

- http://eroi.com/ideas/tracking-video-with-google-analytics-part-3-of-3-html5-edition/


<GA 이벤트 구성>

 Event Category 

 Event Action 

 Event Label

Event Value 

 Memo

 HTML5 Video

 Play

 Video Title

 1

 연속 재생할 때 발생하는 이벤트 제외

 HTML5 Video

 Pause

 Video Titile

 1

 연속 재생할 때 발생하는 이벤트 제외

 HTML5 Video

 Seek

 Video Titile

 1

 반복 발생하는 이벤트 제외

 HTML5 Video

 Mute

 Video Titile

 1

 
 HTML5 Video

 Unmute 

 Video Titile 1 
 HTML5 Video Error + Msg Video Titile 1 
 HTML5 Video

 PlayTime

 Video Titile

 순 재생시간

 
 HTML5 Video

 PlayTimeRate

 Video Titile

 순 재생시간 비율

 

실제로 동영상을 재생한 시간만 계산하기 위해 동영상의 play, pause 이벤트와 windows.beforeunload 이벤트 이용

<스크립트>


  (function(){
    // 반복재생(loop)할 경우 이벤트 발생 지점과 동영상 마지막 부분 비교용.
    // 차이가 mindiff(초) 보다 작으면 끝까지 재생한 것으로 처리.
    // mindiff가 너무 작으면 동영상 끝부분 검출이 안될 수 있음.
    var mindiff = 0.5;
    // mute와 같은 수준의 볼륨 정의.
    var minsound = 0.05;
    // 각 동영상에 대한 정보 저장 객체.
    var videos_status = {};    
    var videos = document.getElementsByTagName('video');
    
    function eventHandler(e){ 
      switch(e.type) {     
        // 동영상 정보 로드 후 정보 저장.
        case 'loadeddata':
          // 동영상 총 길이(초).
          videos_status[e.target.id].duration = e.target.duration;
          // 동영상 초기 상태(play, pause, seek).
          videos_status[e.target.id].playstatus = (e.target.paused == true) ? 'pause' : 'play';
          // 동영상 음소거 여부.
          videos_status[e.target.id].muted    = e.target.muted;          
          videos_status[e.target.id].unmuted  = !e.target.muted;
          break;
        case 'timeupdate':           
          // 동영상의 현재 재생 지점(초) 저장. 재생 중 페이지를 떠날 때 총 재생 시간 계산에 사용.
          videos_status[e.target.id].current = e.target.currentTime;
          // 반복재생(loop) 상태인지?
          if (e.target.loop == true) {
              // 동영상 끝에 도달 했는지?
              if (videos_status[e.target.id].loopones == true && Math.abs(e.target.duration - e.target.currentTime) < mindiff) {
                  // 테스트용.
                  console.log('loop ended');
                  document.getElementById('eventlog').innerHTML += '>loop ended ';
                  // 총 재생시간 업데이트. 재생 시작 시간 초기화. 동영상 끝 검출(loopones) 끔.
                  videos_status[e.target.id].totalplaytime += (e.target.duration - videos_status[e.target.id].startpos);
                  videos_status[e.target.id].startpos = 0;
                  videos_status[e.target.id].loopones = false;
              }
              // 동영상을 처음부터 다시 재생 하는지? 동영상 끝 검출(loopones) 켬.
              if (e.target.currentTime < mindiff) videos_status[e.target.id].loopones = true;
          }          
          break;
        case 'play':
          // seek 할 때 발생하는 play 이벤트 제외 필요. 동영상 재생 중 seek하면 pause -> seeked -> play 순으로 이벤트 발생.
          // 현재는 분석 할 때 순수 play 횟수는 play - seek로 계산.          

          // 동영상 재생 상태를 play로 변경.
          videos_status[e.target.id].playstatus = 'play';          
          // 재생 시작 시점을 현재 시점으로 설정.
          videos_status[e.target.id].startpos = e.target.currentTime;

          // 반복재생(loop) 상태에서 발생하는 play 이벤트 제외함. 
          // 이 때문에 동영상 마지막 부분 직전에서 재생을 클릭해도 GA 이벤트 발생하지 않음.
          if ((e.target.loop == false) || (Math.abs(e.target.duration - e.target.currentTime) > mindiff)) {
            dataLayer.push({
              'event': 'Html5VideoEvent',
              'eventCategory': 'HTML5 Video',
              'eventAction': 'Play',
              'eventLabel': videos_status[e.target.id].videotitle,
              'eventValue' : 1
            });
          }
          break;
        case 'pause':
          // seek 할 때 발생하는 pause 이벤트 제외 필요. 
          // 현재는 분석 할 때 순수 pause 횟수는 pause - seek로 계산.

          // 동영상 재생 상태를 pause로 변경.
          videos_status[e.target.id].playstatus = 'pause';          
          
          // 동영상 재생시점과 현재 시점 간 오류가 있는지?
          if (videos_status[e.target.id].startpos > e.target.currentTime) {
            console.log('error : startpos = ' + videos_status[e.target.id].startpos + ', currentTime = ' + e.target.currentTime);
          }
          // 총 재생시간 업데이트.
          videos_status[e.target.id].totalplaytime += (e.target.currentTime - videos_status[e.target.id].startpos);          
          if ((e.target.loop == true) && (Math.abs(e.target.duration - e.target.currentTime) < mindiff)) {
            // 반복재생(loop) 상태에서 발생하는 pause 이벤트 제외함. 
            // 이 때문에 동영상 마지막 부분 직전에서 멈춤을 클릭해도 GA 이벤트 발생하지 않음.                      
          } else {
            // 반복재생(loop) 상태가 아니거나, 현재 재생시점이 mindiff보다 큼 경우만 pause GA 이벤트 발생.
            // 테스트용.
            dataLayer.push({
              'event': 'Html5VideoEvent',
              'eventCategory': 'HTML5 Video',
              'eventAction': 'Pause',
              'eventLabel': videos_status[e.target.id].videotitle,
              'eventValue': 1
            });
          }
          break;
        case 'seeked':           
          // 연속해서 발생한 seek 이벤트 제외. 반복재생(loop) 상태에서 동영상 처음으로 돌아갈 때 발생하는 seeked 이벤트 제외함. 
          // 중지(pause) 상태에서 발생하는 seek도 한번만 발생됨.
          if ((videos_status[e.target.id].playstatus != 'seek') && (videos_status[e.target.id].loopones == true && Math.abs(e.target.duration - e.target.currentTime) > mindiff)) {
            dataLayer.push({
              'event': 'Html5VideoEvent',
              'eventCategory': 'HTML5 Video',
              'eventAction': 'Seek',
              'eventLabel': videos_status[e.target.id].videotitle,
              'eventValue' : 1
            });
            // 동영상 재생 상태를 seek로 변경.
            videos_status[e.target.id].playstatus = 'seek';
          }
          break;
        case 'volumechange':                    
          // 음소거 또는 최소 볼륨(minsound) 미만으로 변경할 때 한 번만 GA 이벤트 발생. (unmute에서 mute로 변경 시 1회 발생)
          if ((videos_status[e.target.id].muted == false) && (e.target.muted == true || e.target.volume < minsound)) {
            videos_status[e.target.id].muted = true;
            videos_status[e.target.id].unmuted = false;
            dataLayer.push({
              'event': 'Html5VideoEvent',
              'eventCategory': 'HTML5 Video',
              'eventAction': 'Mute',
              'eventLabel': videos_status[e.target.id].videotitle,
              'eventValue' : 1
            });
          }
          // 음소거 해제 또는 최소 볼륨(minsound) 이상으로 변경할 때 한 번만 GA 이벤트 발생. (mute에서 unmute로 변경 시 1회 발생)
          if ((videos_status[e.target.id].unmuted == false) && (e.target.muted == false) && (e.target.volume >= minsound)) {
            videos_status[e.target.id].muted = false;
            videos_status[e.target.id].unmuted = true;
            dataLayer.push({
              'event': 'Html5VideoEvent',
              'eventCategory': 'HTML5 Video',
              'eventAction': 'Unmute',
              'eventLabel': videos_status[e.target.id].videotitle,
              'eventValue' : 1
            });
          }
          break;
        case 'error':          
          dataLayer.push({
            'event': 'Html5VideoEvent',
            'eventCategory': 'HTML5 Video',
            'eventAction': 'Error - ' + e.target.error,
            'eventLabel': videos_status[e.target.id].videotitle,
            'eventValue' : 1
          });
          break;
        default:
          break;
      }
    }
    
    function onbeforeunloadHandler(e) {
      for (var v in videos_status) {
        // 페이지를 떠나려고 할 때 동영상이 재생 중이라면 총 재생시간 업데이트.
        if (videos_status[v].playstatus == 'play') {
           videos_status[v].totalplaytime += (videos_status[v].current - videos_status[v].startpos);
        }
        // 재생한 동영상의 총 재생시간 GA 이벤트 발생.
        if (videos_status[v].totalplaytime > 0) {
          // 총 재생시간
          console.log('onbeforeunloadHandler');
          document.getElementById('eventlog').innerHTML += '> onbeforeunloadHandler ';
          dataLayer.push({
            'event': 'Html5VideoEvent',
            'eventCategory': 'HTML5 Video',
            'eventAction': 'PlayTime',
            'eventLabel': videos_status[v].videotitle,
            'eventValue' : Math.round(videos_status[v].totalplaytime)
          });
          // 총 재생시간 비율. 100%가 동영상의 전체 부분을 봤다는 뜻은 아님. 10초 길이 동영상의 0~1초 부분을 10번 봐도 100%가 됨.
          dataLayer.push({
            'event': 'Html5VideoEvent',
            'eventCategory': 'HTML5 Video',
            'eventAction': 'PlayTimeRate',
            'eventLabel': videos_status[v].videotitle,
            'eventValue' : Math.round(100 * videos_status[v].totalplaytime / videos_status[v].duration)
          });
        }
      }
    }
    
    for (var i = 0; i < videos.length; i++) {
      var videoTagId;
      var videoTitle;
      
      // 동영상의 ID 설정.
      if (!videos[i].getAttribute('id')) {
        videoTagId = 'html5_video_' + Math.random().toString(36).slice(2);
        videos[i].setAttribute('id', videoTagId);
      }
      else {
        videoTagId = videos[i].getAttribute('id');
      }
      // 동영상의 제목 설정.
      if (!videos[i].getAttribute('data-title')) {
        videoTitle = videos[i].currentSrc;
      } else {
        videoTitle = videos[i].getAttribute('data-title');  
      }      
      // 동영상 정보 초기화.
      videos_status[videoTagId] = {};
      videos_status[videoTagId].startpos = 0;
      videos_status[videoTagId].current = 0;
      videos_status[videoTagId].playpos = 0;
      videos_status[videoTagId].totalplaytime = 0;
      videos_status[videoTagId].loopones = true;
      videos_status[videoTagId].videotitle = videoTitle;        
      
      // 동영상의 이벤트 핸들러 설정.
      videos[i].addEventListener("loadeddata", eventHandler, false); 
      videos[i].addEventListener("play", eventHandler, false); 
      videos[i].addEventListener("pause", eventHandler, false); 
      videos[i].addEventListener("seeked", eventHandler, false); 
      videos[i].addEventListener("timeupdate", eventHandler, false);
      videos[i].addEventListener("volumechange", eventHandler, false);
      videos[i].addEventListener("error", eventHandler, false);
    } 
    // 페이지의 이벤트 핸들러 설정.beforeunload
    window.addEventListener("beforeunload", onbeforeunloadHandler, false);
  })();

Posted by 값진인생
,
검색이나 책에서 보고 정리했습니다. 출처가 없는 점 양해 바랍니다.
계속 업데이트 할 생각합니다.
  • AARRR(Acquisition, Activation, Retention, Referral, Revenue). 일명 해적지표. Dave McClure가 만듦
  • ARPPU(Average Revenue Per Paying User). 결제자당 평균 매출(혹은 결제자 객단가). 월 단위로 주로 계산하게 되며, 해당 기간의 매출 총합을 결제자수로 나누면 됨. 주의할 점은, 소수의 고액결제자들로 인해 크게 영향을 받을 수 있는 지표라는 점. 실제 데이터를 구할 때 아웃라이어에 대한 체크가 필요함
  • ARPU(Average Revenue Per User). 사용자당 평균 매출(혹은 가입자당 평균 매출, 객단가). 해당 기간의 매출 총합을 사용자수로 나누어 계산
  • ASP(Application Service Provider). 애플리케이션 서비스 제공자. 
  • ASP(Average Selling Price). 결제 건당 매출. 매출을 판매개수로 나누어 계산. 개별아이템의 단가가 얼마나 높은지 파악할 수 있는 지표
  • AU(Active User). 활동유저. 일반적으로는 ‘접속’ 기준. DAU를 의미하는 경우가 많음
  • CAC(Customer Acquisition Cost). 유저 모객단가. 한 사람의 신규 고객을 데려오는 데 드는 비용. 광고 등 마케팅비용을 신규유저수로 나누어 계산
  • Click Fraud. 부정클릭. 악의의 목적을 갖고 사용자 또는 경쟁사가 클릭하여 광고비용을 소진 시키는 것
  • DAU(Daily Active User). 일별 활동 사용자. 하루를 기준으로 활동(=접속)하는 사람 수. 많은 서비스들이 공통적으로 key metric으로 생각하는 중요한 지표
  • DT(Duration Time). 체류시간. 한 방문자가 설정된 기간 동안 특정 웹 페이지에 머무른 시간
  • EVA(Economic Value Added). 경제적부가가치. 
  • Invalid Click. 무효클릭. 클릭되었으나 과금되지 않는 중복제거된 클릭
  • LTV(Lifetime Value) / CLV(Customer Lifetime Value). 고객 생애가치. 한 명의 고객이 서비스에 진입해서 이탈하기까지의 전체 기간동안 창출하는 가치 . CLV = ((M-c) / (1-r)) - AC
  • MAU(Monthly Active User). 월별 활동 사용자. 해당 월에 최소 1회 이상 접속한 사람의 숫자
  • MCU(Maximum Current User). 최대 동시접속자 수. 
  • OMTM(One Metric That Matters). 현재 단계에서 무엇보다 중점을 두어야 하는 지표
  • PU(Paying User). 결제자. 보통 일단위 혹은 월단위로 끊어서 보는 경우가 많음
  • Retention Rate. 회원 잔존율. D-day에 들어온 유저가 D+x일에 얼마나 남아있는지를 보여주는 비율. 보통 D+7 잔존율, D+30 잔존율, D+60 잔존율 등을 살펴봄
  • Revenue. 판매액(혹은 매출액). 
  • ROA(Return on Assets). 총자산영업이익률. 
  • ROAS(Return(Revenue) On AD-Spend). 타겟 광고 투자수익. 투자한 광고비 대비 광고주가 얻은 매출. ROAS = 광고에 의한 매출 / 광고비
  • ROE(Return on Equity). 주주자본이익률. 
  • ROI(Return On Investment). 투자 수익. 보통 광고매출의 순이익 / 광고비로 계산
  • ROIC(Return on Invested Capital). 투하자본이익률. 
  • SaaS(Software as a Service) / on-demand software. 소프트웨어 및 관련 데이터는 중앙에 호스팅되고 사용자는 웹 브라우저 등의 클라이언트를 통해 접속하는 형태의 소프트웨어 전달 모델이다.
  • UUID(Unique User IDentifier). 개인별 고유 식별자. 다양한 사업목적을 갖는 웹사이트에서 반드시 ‘회원’의 속성이 존재한다고 볼 수 없기에 ‘회원ID’와 같이 웹사이트에 방문하는 개개인을 구별할 수 있는 식별자를 통칭
  • WAU(Weekly Active User). 주별 활동 사용자. 해당 주에 최소 1회 이상 접속한 사람의 숫자


Posted by 값진인생
,

구글 애널리틱스 보고서를 내려받는 여러가지 도구가 있지만, 공부 삼아 만들어 봤습니다. 


우선 엑셀 VBA로 Google Analytics API를 이용하기 위해 Tim Hall의 라이러리를 이용했습니다.(https://github.com/VBA-tools/VBA-Web/wiki/Google-APIs)

역시 세상은 넓고 능력자는 도처에 있네요. 제가 한 건 API 파라메터 설정과 응답 결과를 엑셀에 뿌려주는 정도입니다. (한 가지 더 oauth 인증 절차를 수정하여 구글 계정 로그인 횟수를 줄였습니다.)


그리고 Google Docs를 이용한다면 Google Analytics Spreadsheet Add-on을 추천합니다. (https://developers.google.com/analytics/solutions/google-analytics-spreadsheet-add-on) 그 외도 무료/상용 툴이 다양하게 있습니다.


간단한 사용법입니다. 


첨부한 엑셀 파일을 실행하면 아래와 같이 가져올 보고서를 설정하는 시트가 있습니다.


필수 입력 항목은 Report Name, Sheet Name, View ID, Start Date, End Date입니다.

Last N Days가 0보다 크면 Start Date와 End Date에 입력한 값은 무시되고 현재 날짜를 기준으로 Start Date와 End Date가 설정됩니다.



Account ID, Property ID, View ID는 Dialog Box 메뉴에서 Accounts/Properties/Views 버튼을 누르면 대화상자가 나타나고 보고서를 가져올 계정/속성/보기의 ID를 선택할 수 있습니다. 




측정 기준과 측정 항목도 마찬가지로 Dialog Box 메뉴에서 Dimensions/Metrics 버튼을 누르면 가져올 항목을 선택할 수 있습니다. 



Custom Dimensions/Metrics는 Custom Dimensions/Metrics 버튼을 누르면 목록을 보고 선택할 수 있습니다.



비슷한 방법으로 세그먼트를 선택할 수 있습니다.




보고서에 대한 정의가 끝나면 Run reports 버튼을 눌러 데이터를 가져옵니다.


만약, 현재 보고서만 갱신할 경우에는 Refresh report 버튼을 클릭합니다.


뭐. 별다른 기능은 없지만, 구글 애널리틱스와 업무 환경을 통합하는 괜찮은 방법 같습니다. 보다 정형화된 보고서를 보관한다면 애널리틱스와 Access를 조합하는 것도 좋겠습니다.


상용 툴에 비하면 보잘 것 없지만, 단순 반복 작업을 줄이는 효과를 기대합니다.


아직 테스트가 충분하지 않아 예기치 않은 오류가 있을 수 있습니다. 재미 삼아 보세요. VBA를 다룰 줄 안다면 입 맛에 맞게 수정하여 이용하실 수 있습니다. 


Google Analytics Report.xlsm


Posted by 값진인생
,

<문제>

참 또는 거짓: 삭제한 보기는 복구할 수 없습니다.


A. 참. 삭제된 보기는 복구할 수 없습니다. 

B. 거짓. 삭제된 보기는 35일 내에 복구할 수 있습니다.


<풀이>


<문제>

다음 중 단일 Google 애널리틱스 계정 내에서 보기를 사용할 수 있는 경우는 언제입니까?


A. 특정 하위 도메인의 트래픽을 자세히 확인하려는 경우

B. 사이트의 특정 부분(특정 페이지 또는 여러 페이지)의 트래픽을 자세히 확인하려는 경우

C. 하위 데이터에 엑세스 할 수 있는 사용자의 권한을 제한하려는 경우

D. A와 C만 정답

E, A, B, C 모두 정답


<풀이>


<문제>

Google 애널리틱스에서 필터를 추가하면 무엇을 할 수 있습니까?


A. 특정 IP 주소에서 유입되는 방문자 제외 

B. 복잡한 페이지 URL을 읽을 수 있는 텍스트 문자열로 변경

C. 이전 데이터 수정 

D. A와 B만 정답

E. A, B, C 모두 정답


<풀이>


<문제>

참 또는 거짓: 보기 설정에서 표시되는 필터의 순서는 중요합니다.


A. 참: 필터는 표시된 순서대로 실행됩니다.

B. 거짓: 필터는 표시된 순서대로만 실행되지는 않습니다.


<풀이>


Posted by 값진인생
,