GCPでオレオレGoogle Analytics(リアルタイム版)を開発する(その2)
前回の続き。次にCloud Functionsでブラウザから飛んできたビーコンを受ける口を作る。
1. Cloud Functionsを設定
とりあえずエンドポイント名とかは何でもいいと思うけど、注意点は未認証の呼び出しを許可する必要があるくらいだろうか。これだけでAPIコールのエンドポイントができる。なんていい時代なのか。
あとはNode.jsのコードをポチポチ書くくらい。色々弄りながら最終的にこんなコードになった。
/** * Responds to any HTTP request. * * @param {!express:Request} req HTTP request context. * @param {!express:Response} res HTTP response context. */ exports.trackBeacon = (req, res) => { console.log(Date.now()); var messageJson = { "ip" : req.ip ,"ua" : req.headers['user-agent'] ,"uid" : req.query.uid ,"url" : decodeURIComponent(req.query.url) ,"timestamp" : Date.now() }; var img = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==", 'base64'); res.writeHead(200, { 'Content-Type': 'image/png', 'Content-Length': img.length }); res.end(img); const {PubSub} = require('@google-cloud/pubsub'); const pubSubClient = new PubSub(); async function publishMessage() { const topicName = 'projects/[プロジェクト名]/topics/[トピック名]'; const dataBuffer = Buffer.from(JSON.stringify(messageJson)); const messageId = await pubSubClient.topic(topicName).publish(dataBuffer); console.log(`Message ${messageId} published.`); } publishMessage().catch(console.error); };
ブラウザから受け取って後続処理に流すのはIPアドレス・User Agent・Unique Identifier(uidパラメタ)・リクエスト発生元URL(urlパラメタ)・タイムスタンプ(エポックミリ秒)。また、画面には1x1の透過PNGを返す。その後にメッセージをPubSubに投げる。package.jsonはこんな感じ。Node.jsとか慣れてないので地味にここの書き方やらバージョン指定に苦戦。
{ "name": "sample-http", "version": "0.0.1", "dependencies": { "@google-cloud/pubsub": "1.7.3" } }
ここに書いたバージョン番号はこのサイトで発見。
www.npmjs.com
2. 合わせてHTMLを変更
上記のパラメタに合わせてHTML側もこんな感じに変更。クッキーの扱いとかがやっつけなのは勘弁してください。
<!doctype html> <html> <body> <h1>Hello World!</h1> <script> //UID生成 var N=48 var uid = getCookie('uid'); if(!uid){ uid=""; for(var i=0; i<N; i++){ uid += S[Math.floor(Math.random()*S.length)]; } document.cookie = "uid=" + uid + "; max-age=36000; secure; samesite=lax;"; } //計測ビーコン var imgUrl = '[Cloud Functionsのエンドポイント]'; var img = document.createElement('img'); img.src=imgUrl + '?uid=' + uid + "&url=" + encodeURIComponent(location.href); document.body.appendChild(img); function getCookie(key){ var cookies = document.cookie; var cookiesArray = cookies.split(';'); for(var c of cookiesArray){ var cArray = c.split('='); if( cArray[0] == key){ return decodeURIComponent(cArray[1]); } } } </script> </body> </html>