rcmdnk's blog
Last update

English ver.: Notice a copy event on your blog in Google Analytics
無料でできる! 世界一やさしいGoogle Analytics アクセス解析入門

JavaScriptだけでブログがコピーされた時にその内容をメールで送る でやった事をちょっといじって コピー結果をGoogleアナリティクスも送れる様にしてみました。

JavaScriptの用意

source/javascript/utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
jQuery(function($){
  $(document).on('copy', function(e) {
    var selected = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            selected = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            selected = document.selection.createRange().htmlText;
        }
    }
    if (!selected) return;
    ga('send', 'event', 'copy', location.href + ':' + document.title, selected);
  });
});

追記: 2015/08/10

location.hrefを使うと見出しからセクションに飛んだ時とかに ハッシュ部分(#...)が残ってしまって違うページとカウントされてしまうので、

1
2
3
-ga('send', 'event', 'copy', location.href + ':' + document.title, selected);
+var url = 'http://' + location.host + location.pathname;
+ga('send', 'event', 'copy', url + ':' + document.title, selected);

と変更しました。

追記ここまで

前回 のAjaxで送ってた部分をGoogleアナリティクスのオブジェクトに置き換えただけです。 (selectedが空白かどうかのチェックだけ直前に入れるようにしてみました。)

Googleアナリティクス(ユニバーサルアナリティクス、analytics.jsの方)のオブジェクト名を変更してないままgaだと仮定しています。

追記: 2015/01/27

古いアナリティクスのコード(ga.js)の方を使ってる場合には

ga('send', 'event', 'copy', location.href + ':' + document.title, selected);

の部分を

_gaq.push(['_trackEvent', 'copy', location.href + ':' + document.title, selected]);

としてください(ここではアナリティクスのオブジェクトがデフォルトの_gaqだとしています)。 以下も同様です。

追記ここまで

これをアナリティクスのコードを読み込んだ後に読み込んだり <script>内に直接書くなりしてください。

bulb 下のアナリティクスコードの読み込みはJavaScriptをasyncで読み込むについて でやった物になってますが、普通のコードでも勿論構いません。

また、jQueryの関数を使っているのでjQueryも先に読み込んでおく必要があります。

head.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<head>
...
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
...
<script src="//www.google-analytics.com/analytics.js" async defer></script>
<script>
ga = function() {
  ga.q.push(arguments);
};
ga.q = [['create', '<YOUR_GOOGLE_ANALYTICS_TRACKING_ID>', 'auto'], ['send', 'pageview']];
ga.l = 1 * new Date();
</script>
<script src="/javascripts/utils.js"></script>
...
</head>

通常のアナリティクスのコード+<script>内直接な感じだと内直接な感じだと内直接な感じだと内直接な感じだと こんな感じ。

head.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<head>
...
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
...
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '<YOUR_GOOGLE_ANALYTICS_TRACKING_ID>', 'auto');
ga('send', 'pageview');
</script>
...
<script>
jQuery(function($){
  $(document).on('copy', function(e) {
    var selected = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            selected = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            selected = document.selection.createRange().htmlText;
        }
    }
    if (!selected) return;
    ga('send', 'event', 'copy', location.href + ':' + document.title, selected);
  });
});
</script>
...
</head>

追記: 2015/01/06

今回はjQueryを使ってるのが最初のところだけなので、 jQueryを他で使ってない場合は次の様にすればjQueryを読み込まずに行けます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<head>
...
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '<YOUR_GOOGLE_ANALYTICS_TRACKING_ID>', 'auto');
ga('send', 'pageview');
</script>
...
<script>
window.onload = function() {
  document.oncopy = function () {
    var selected = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            selected = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            selected = document.selection.createRange().htmlText;
        }
    }
    if (!selected) return;
    ga('send', 'event', 'copy', location.href + ':' + document.title, selected);
  }
}
</script>
...
</head>

追記ここまで

上の、

1
ga('send', 'event', 'copy', location.href + ':' + document.title, selected);

のところではアナリティクスのイベントトラッキング 1 を使っています。

  • 第一引数がコマンドで、sendで情報を送ります。
  • 第二引数はヒットタイプと呼ばれ、eventでこれがイベントトラッキングを送る事を指定します。
  • 第三引数はイベントカテゴリーで、好きな文字列を入れますがここではcopy
  • 第四引数はイベントアクションで、単にカテゴリーを更に絞り込むために使う言葉としてここでは使っていて、ページのURLとタイトルをここに入れています。
  • 第五引数はイベントラベルと呼ばれますが、ここにコピーされた文字列を入れています。
  • さらにイベントトラッキングでは第六引数にイベント値として0か正の整数を指定できますが、今回は余り使い道が無いので指定してません。

注意として、イベントラベル等は無限に長いものが入れられるわけではなく、 最大値を超えると勝手に切り捨てられて送られます。

最大値はそれぞれ

  • イベントカテゴリ: 150 bytes
  • イベントアクション: 500 bytes
  • イベントラベル: 500 bytes

となっています 2

例えばソーシャルアクションのターゲットなどという値もあり、 これはeventの代わりにsocialというヒットタイプを使うと使えるものですが 最大2048 bytesまで使えます。 socialに送る値は

  • ソーシャルネットワーク: 50 bytes
  • ソーシャルアクション: 50 bytes
  • ソーシャルアクションのターゲット: 2048 bytes

の様になっていて、上手くこれを使えば送れる最大文字数が4倍になりますが、 その他の値が小さいので上みたいにURLとタイトルを入れたりすると簡単に はみ出てしまう可能性もあります。

取り敢えず完璧に追いたいわけでもないので、 使い方的にもeventのが正しそうなのでeventで。

Googleアナリティクスで見てみる

イベントトラッキングは、左の行動カテゴリーの中のイベント というところで見れます。

eventsummary

取り敢えずサマリーを開いてみると

selectcategory

こんな感じでカテゴリー一覧が見れるのでここでcopyをクリック。

eventcategory

この画面で、上のイベントアクションをクリック。

eventaction

そうするとこんな感じでコピーされたページの一覧が出てきます。 この中の適当なページを選んでクリックすると、

eventlabel

こんな感じでコピーされた物一覧が見れます。

コピー部分取得時にHTMLで取得してるので、大きな領域をコピーされると

longlabel

こんな感じのタグ混じりのものが送られてきたりもします。

Mandrillを使った方法 の時はHTMLメールにしてそのまま送ったのでHTMLで取得してましたが、 この辺は適当にJavaScript側で好きに出来ます。

テキストだけにしたいなら

1
2
-selected = container.innerHTML;
+selected = container.innerText;

1
2
-selected = document.selection.createRange().htmlText;
+selected = document.selection.createRange().text;

の2箇所の変更を行えば良いと思います。

追記: 2015/01/27

また、ここではイベントアクションにページ情報を入れていますが、 それらに入れなくても copyを表示した時点で、 セカンダリ ディメンジョン行動ページタイトル 等を選んでページごとの表示をさせることも可能です。

secondarydimension

withsecondarydimension

今の所アクションの項目に他の物を入れる必要がないのであれですが、 必要であればイベントアクションに他の物を入れても良いかも。

追記ここまで

まとめ

コピーされたのを知る方法として、 なんとなくメールで送らなくちゃいけない、と思ってて手がつかなかったですが、 Googleアナリティクスだけでも簡単に見ることが出来ました。

ちょっと見てみたい、というだけならこれで十分な気がします。

ただ、Mandrillの方だと文字数制限なしで見れるのとHTMLをそのまま見れるので 便利なので、 取り敢えず引き続き 前回の スクリプトの中に上のgaコードを入れて 両方入れる形にしておきます。

思ったよりも沢山コピーされてるので実はメールは殆どタグで振り分けられたままになってますが、 Mandrillのダッシュボードも中々見やすいので 解析する点でも中々優れていると思います。 (メールの上限超えたらまあ仕方ないからその月はそこまで、ということで。)

追記: 2015/08/10

ここ最近ブログでよくコピーされる物

追記ここまで

Sponsored Links
Sponsored Links

« tmuxのPaneの扱いをGNU screenのWindowの取り扱いになるべく近づけてみる tmux/GNU ScreenでC-hにキーバインドする »

}