アドテク(広告テクノロジー)では、ブラウザでサイト見ているユーザー(オーディエンス)を特定する技術が求められます。
自社ECサイトで会員登録をしたユーザーを特定するのは簡単ですが、会員登録をしていないユーザー(初めて自社サイトに訪れたユーザー)を特定するには何らかの手段が必要になります。
つまり初めて自社サイトを訪れた人がどんな思考の人か、どんなサイトのどんなページを見ていたか・・。
その情報を特定するためにCookieに特定のIDを付与する技術がアドテクでは使われています。
3rd Party Cookieとは
今回の想定シナリオは以下のようになります
- オーディエンスがサイト1(train.com)で大阪へいくための電車料金を調べる
- サイト1には<img src="tracking.com/1.gif">が埋め込まれており、オーディエンスがサイトを見た瞬間にトラッキングサーバーへ通信が走る。(オーディエンスのブラウザ->トラッキングサーバー)
- トラッキングサーバーはオーディエンスのブラウザにCookieを出力しトラッキングIDを付与する
- オーディエンスは電車のチケットは当日駅で買うことにし、ホテルのサイト(hotel.com)でホテルを予約することにする
- hotel.comにも<img src="tracking.com/1.gif">が埋め込まれており、オーディエンスがサイトを見た瞬間にトラッキングサーバーへ通信が走る。(オーディエンスのブラウザ->トラッキングサーバー)
- トラッキングサーバーはオーディエンスのブラウザにtracking.comのクッキーが埋め込まれているのを確認し、再度IDを付与することはせずCookieのexpire(期限)だけを更新する。
- オーディエンスのCookieIDからtrain.comで大阪の情報を調べていたことがログからわかるので、ホテルのページの広告枠に大阪のホテルの案内を出したり、ファーストビューを大阪ホテルのキャンペーンページに変更したりなど広告を最適化する。
トラッキング用のクッキーの種類は大きくわけて2つあります。
種類 | 説明 |
---|---|
1st Party Cookie | 対象サイトのドメインのクッキーを使ってトラッキングする。絵でいう所のtrain.comのドメインでCookieを出力する |
3rd Party Cookie | 対象サイトとは別のトラッキングザーバーのドメインを使ってトラッキングする。絵でいう所のtracking.com |
1st Party Cookieで代表的なのはGoogleAnalytics(GA)です。
参考:http://nexal.jp/blogs/2061.html
3rdPartyにはSafariをトラッキングできないという致命的な欠陥(※)がありそれを回避するには1stParyCookieが有効です。(他にもローカルストレージをモニョモニョする・・などもありますが)
(※)Safariのデフォルトの設定が「3rd Party Cookieを拒否する」となっているため事実上3rdのCookieを受け付けない。
ピクセルトラッキングとは
1x1の透明画像(だいたいはgif)をレスポンスとして返す裏でCookieを仕込み、Cookieにユーザーを特定するIDを付与する技術の事。
透明なのでブラウザからは見えない、というかほとんどはhtmlでhidden設定されてるのでブラウザには表示されない。
ピクセルトラッキングのHTMLの記述についてはDoubleClick(google)のサイトが超詳しい
https://support.google.com/dfp_premium/answer/1347585?hl=ja
画像でなくてもいいが、htmlのsrc=などでHTLMのオンロードで自動的に読み込めるものに限る。
またJSはサードパーティ製のサイトのJSを読み込めないブログサービスなどもあるので扱いづらい。
よって基本は画像になる。
PlayFramework/Scalaでピクセルトラッキングサーバーを作る
Playインストール
Activatorをダウンロードし
activator new
でプロジェクトを新規作成する。(Scalaプロジェクト)
コントローラー実装
package controllers
import play.api._
import play.api.mvc._
import play.api.libs.Codecs
import java.security.MessageDigest
// Java8 lib
import java.util.Base64
object Tracking extends Controller {
val COOKIE_KEY = "Z_SYSTEM_3RD_PARTY_COOKIE_ID_SCALA"
val COOKIE_MAX_AFTER_AGE = Some(31622400 + 31622400)
//ref https://css-tricks.com/snippets/html/base64-encode-of-1x1px-transparent-gif/
val onePixelGifBase64 = "R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
val onePixelGifBytes = Base64.getDecoder().decode(onePixelGifBase64)
def pixelTracking = Action {request =>
val cookies = request.cookies
val cookieValue = cookies.get(COOKIE_KEY).map { cookie =>
Logger.debug(s"Cookie Exist! ${cookie.value}")
cookie.value
}.getOrElse {
val newValue = uniqueIdGenerator()
Logger.debug("Cookie Generate! $newValue")
newValue
}
Ok(onePixelGifBytes).withCookies(Cookie(COOKIE_KEY, cookieValue, COOKIE_MAX_AFTER_AGE)).as("image/gif")
}
val uniqueIdGenerator = () => {
val milliTime = System.currentTimeMillis()
val nanoTime = System.nanoTime()
val baseString = s"$milliTime $nanoTime"
Logger.debug(baseString)
val md = MessageDigest.getInstance("SHA-256")
md.update(baseString.getBytes())
val id = Codecs.toHexString(md.digest())
Logger.debug(id)
id
}
}
val uniqueIdGenerator 関数 (CookieID生成関数)
トラッキング用のIDはどようなアクセス状況下、どのようなサーバーマシン構成でもオーディエンスに対してユニークなIDを割り当てることが求められる。
今回はミリ秒とナノ秒(※)をスペースでつなげてSHA256した16進法文字列をIDとした。
これであれば同じミリ秒でアクセスしたユーザーがいない限りはユニークなIDとなる。
よりアクセス数があるサーバーであればユーザーのIPやサーバーのIPやMACアドレス、プロセスID、Javaプロセスのフリーメモリ数などを足してハッシュ化するといいだろう。
ロジックを使いまわして別トラッキングサーバーを作る場合は、トラッキングサーバーの種別ID("hogehoge-TrankingServer1")などを連結すればよいだろう。
(※)現在の一般のCPUでは正確なナノ秒は測定できないがSystem.nanoTime()はミリ秒よりは正確な値を返す。
def pixelTracking メソッド
このメソッドが実際のリクエストを受け付ける処理となる。
処理は単純で
- リクエストにCookieの値("Z_SYSTEM_3RD_PARTY_COOKIE_ID_SCALA")があるかを検索
- Cookieの値があったらCookieのExpire(有効期限)を更新して1x1ピクセルgifを返却
- Cookieの値がなかったらuniqueIdGenerator関数を実行しCookieIDを生成
- 生成したCookiIDをレスポンスに付与し、同時に1x1ピクセルgifを返却
ルーティングの設定
GET /1.gif controllers.Tracking.pixelTracking
http://サーバーのドメイン/1.gif にアクセスすると処理が実行されるようになる。
トラッキングサーバー起動
activatorを起動し、runでポート9000で起動する
activator
[info] Loading project definition from play_scala_study/play_scala_1/project
[info] Set current project to play_scala_1 (in build file:/play_scala_study/play_scala_1/)
[play_scala_1] $ run
--- (Running the application, auto-reloading is enabled) ---
[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
http://localhost:9000/1.gif にアクセスし、画面にgifが表示され、Cookieが書き込まれていることを確認する。(ブラウザの開発者ツールで確認する)
二回目のアクセスでクッキーIDが変更されていないことを確認する。
実際に運用する場合はport80で起動するようポートを指定して起動する。
activator
start 80
自社サービスのサイトのHTMLの実装
トラッキングサーバーは起動したので、別のドメインのサイトのページに以下のような記述を埋め込めばトラッキングは完了です。
<p>安い電車予約どっとこむ</p>
<img src="http://tracking.com/1.gif" style="display:none">
<p>安いホテル予約どっとこむ</p>
<img src="http://tracking.com/1.gif" style="display:none">