今回は、アクセス解析の話ではないのですが、データとして GAを使ったので、ここに書きます。
前回、スクロール率をgoogle analyticsで計測した話を書きました。 レポート部分は、エクセルでの表示だったんですが、今回、自動化のひとつの方法として、タイトルの方法をやったので、報告します。
Google Apps Script(GAS)は、かなりの便利ツール
データを外部から引っ張ってきて、加工して、メール配信というのが、割合簡単にできます。
今回は、google analyticsのデータを引っ張って、加工して、HTMLメールで配信という形の紹介です。
GASの記述は、javascriptです。 google analyticsの集計の設定も javascriptですので、 javascriptは習得しがいのある技術かもしれません。
手順としては、URLFetchで google analytics Data Export Api からデータを取得して、それを google chart apiを使って、 HTMLメールで送る作業です。
Google Chart APIも、自動化ツールとして価値大。
URLを指定すれば、チャート画像を返してくれます。
ですので、変化する数字を自動的にグラフ化してレポーティングしたい場合に価値が高いです。
パラメータがたくさんあって、マニュアル(解説)が英語なのでとっつきにくいですが、データ、チャートタイプ、ラベル、軸、などの概念とapiでのパラメータが一致すれば、それなりに使えるのではと思ってます。
別別サイトにメモみたいなのを書きましたが、、、あまり参考にならないかも。
GMailの問題?
いろいろいじって、なんとか自動化にこぎつけたのですが、GmailのHTML表示の時に、imageタグの部分が上手く表示されなくて、いろいろ探したのですが、結局あきらめました。 たぶん、文字数の問題のような気がしてるのですが、、、どうなんでしょう。 Yahoo Japanの Web mailなら問題なかったです。
出力画像と スクリプトを貼りつけます。
スクロール計測とそのレポート配信を試してみたい方は連絡下さい(コメントでスクロール計測希望と書いてくだい)。 設定して、週次 or 日次で、特定のディメンジョンで切ったスクロール率のよる閲覧割合をメールレポーティングします。無料です。 以下の画像のような形でのHTMLメールが送られます。
画像レポートの後に、参考に、GASのスクリプトを貼りつけておきます。 貼り付けた以外にも追加の定義(関数、代入式)などがあるので、全部ではないです。
以下、レポート配信に使ったscriptの一部。
1: function CRReport(id,name,title,address){2: //id = "ga:21600568", name="shirai", title="wordpress", address="kimiyuki[at?]gmail.com";3: var startdate; var enddate; var dimensions = []; var metrics = []; var filters = ""; var segments = "";4: var entries; var sort;var data;5: var tmp;6: var siteurl;7: startdate = getMyDate(-15); enddate = getMyDate(-3);8: dimensions = ["ga:pagePath,ga:hostname"]; metrics=["ga:visits"]; sort=["-ga:visits"];9: entries = getDataFromApi(id, startdate, enddate,dimensions, metrics, filters, segments, sort);10: pagePaths = [];11: entries.slice(0,3).forEach(function(entry){12: var el = entry.getElements("http://schemas.google.com/analytics/2009", "dimension");13: el.forEach(function(e){14: if(e.getAttribute("name").getValue() == "ga:pagePath") pagePaths.push(e.getAttribute("value").getValue());15: if(!siteurl && e.getAttribute("name").getValue() == "ga:hostname") siteurl = e.getAttribute("value").getValue();16: });17: });18:19: data = {};20: var w1 = [null,null, null]; var w2 = [];21: pagePaths.forEach(function(path){22: Utilities.sleep(500);23: w1 = [null,null,null], w2=[];24: var dim_sg = "ga:medium";25: dimensions = ["ga:eventCategory", "ga:eventAction", "ga:pagePath",dim_sg]; metrics = ["ga:uniqueEvents"]; sort = null;26: filters="ga:eventCategory==CompRead0523B;ga:pagePath==" + path;27: segments=null;28: entries = getDataFromApi(id, startdate, enddate, dimensions, metrics, filters, segments, sort);29: entries.forEach(function(entry){30: var ds = entry.getElements("http://schemas.google.com/analytics/2009", "dimension");31: var es = entry.getElements("http://schemas.google.com/analytics/2009", "metric");32: var w = new Array();33: ds.forEach(function(e){34: if(e.getAttribute("name").getValue()=="ga:eventAction") w1[1] = parseInt(e.getAttribute("value").getValue().replace("z",""));35: if(e.getAttribute("name").getValue()== dim_sg){w1[0] = e.getAttribute("value").getValue();}36: });37: es.forEach(function(e){38: if(e.getAttribute("name").getValue() == "ga:uniqueEvents") w1[2] = parseInt(e.getAttribute("value").getValue());39: });40: w2.push([w1[0], w1[1],w1[2]]); //値にして設定するため41: w1 = [null,null, null];42: });43: w2 = w2.sort(function(a,b){return a[1] > b[1]});44: if(data[path] == null) data[path] = [];45: data[path] = w2.map(function(x){return x});46: //data[path] = w2.map(function(e){return [e[0], Math.floor((e[1]/total)*100)]});47: });48: // Logger.log(data);49: html = outputChart(data, startdate, enddate, siteurl);50: Logger.log(html);51: MailApp.sendEmail(address, "CompRead","html mail", {cc: "kimiyuki[aat]gmail.com", htmlBody: html});52: }53:54:55: function outputChart(data, startdate, enddate ,siteurl){56: var html = "<div>" + startdate + "から" + enddate + "のセッション数上位3ページの精読率調査です。数字はセッション数です。</div>";57: for(e in data){58: //Logger.log(e);59: //Logger.log(data[e] instanceof Array);60: //Logger.log(data[e].length);61: //Logger.log(data[e].toString());62:63: //making dimentionable data64: var dimmed_data = data[e].reduce(function(r, x){65: if(r[x[0]] == null){66: r[x[0]] = x[2];67: }else{68: r[x[0]] += x[2];69: }70: return r;71: }, {});72: //Logger.log(dimmed_data.toSource());73:74: var tmp = [];75: Logger.log("object="); Logger.log(dimmed_data.toSource() + "\n");76: for(c in dimmed_data){tmp.push([c, dimmed_data[c]])};77: dimmed_data = tmp.sort(function(a,b){ return a[1] < b[1]});78: Logger.log("dimmed_data=");79: Logger.log(dimmed_data.toString()+"\n");80: var label = data[e].map(function(x){return x[1]}).unique();81: var data1 = data[e].filter(function(x){return x[0] == dimmed_data[0][0]}).map(function(x){ return x[2]});82: var data2 = data[e].filter(function(x){return x[0] == dimmed_data[1][0]}).map(function(x){ return x[2]});83: var data3 = dimmed_data.length < 3 ? "" : data[e].filter(function(x){return x[0] == dimmed_data[2][0]}).map(function(x){return x[2]});84: //Logger.log(label);85: //Logger.log(data1);86: //Logger.log(data2);87: //html += "<tr><td>" + e + "</br>" + data[e].map(function(x){return x[0] + '=>' + x[1]}).join(',') + "</td></tr>";88: html += "<div><div>";89: html += makeChart(label, data1, data2,data3, dimmed_data[0][0], dimmed_data[1][0], (dimmed_data.length > 2 ? dimmed_data[2][0] : ""));90: html += "</br>";91: html += "<a href='http://" + siteurl + e + "'>" + e + "</a></div>";92: html += "<div> </div>" //全角空白を入れた。間隔を作るため93: }94: html += "</div>";95: return html;96: }97:98: function makeChart(label, data1, data2, data3, dataLabel1, dataLabel2, dataLabel3){99: var max = data1.concat(data2).reduce(function(r, e){return r > e ? r : e;}, 10);100: var chds = "chds=" + "0," + max;101: var chxr = "chxr=1,0," + max;102: var chco = "chco=4d89f9,c6d9fd" + (data3 != "" ? ",63C6DE" : "");103: var chdl = "chdl=" + dataLabel1 + "|" + dataLabel2 + (dataLabel3 != "" ? "|"+dataLabel3 : "");104: var chm = "chm=N,000000,0,,12,0,e|N,00FFFF,1,,12,0,e" + (data3 != "" ? "|N,0000FF,2,,12,0,e" : "");105: var url =106: "<img style='display:block;' src='http://chart.apis.google.com/chart?cht=bhg&chs=250x" + (dataLabel3 != "" ? "990" : "660") + "&chd=t:" +107: data1.join(",") + "|" + data2.join(",") + (data3 != "" ? "|"+data3.join(",") : "") +108: "&" + chds + "&" + chxr + "&" + chm + "&" + chdl + "&" + chco +109: "&chxt=y,x&chxl=0:|" + label.reverse().join("|") + "&chxs=0,ff0000,12,0,lt|1,0000ff,10,1,lt'/>";110: //Logger.log(url);111: return url //.replace("&", "&");112:113: }