Comment embeds: Add event pixel tracking

This commit is contained in:
David Wick
2015-02-02 18:40:24 -08:00
parent ef1d38f4f7
commit a400524cb5
10 changed files with 179 additions and 8 deletions

View File

@@ -120,6 +120,8 @@ adframetracker_url = /pixel/of_defenestration.png
clicktracker_url = /click
# url to request to track interaction statistics
uitracker_url = /pixel/of_discovery.png
# embeds pixel tracking url
eventtracker_url = /pixel/of_delight.png
# google analytics token
googleanalytics =
# google analytics events sampling rate. Valid values are 1-100.

View File

@@ -82,7 +82,7 @@ def set_up_embed(embed_key, sr, thing, showedits):
c.embed_config = {
"logged": c.user_is_loggedin,
"stats_domain": g.stats_domain or "",
"eventtracker_url": g.eventtracker_url or "",
"created": iso_timestamp,
"showedits": showedits,
"thing": {

View File

@@ -413,6 +413,7 @@ module["reddit-embed-base"] = Module("reddit-embed-base.js",
"embed/custom-event.js",
"embed/utils.js",
"embed/post-message.js",
"embed/pixel-tracking.js",
)
@@ -478,6 +479,11 @@ module["reddit"] = LocalizedModule("reddit.js",
"lib/jquery.cookie.js",
"lib/jquery.url.js",
"lib/backbone-1.0.0.js",
"embed/custom-event.js",
"embed/utils.js",
"embed/post-message.js",
"embed/pixel-tracking.js",
"embed/comment-embed.js",
"timings.js",
"templates.js",
"scrollupdater.js",
@@ -498,10 +504,6 @@ module["reddit"] = LocalizedModule("reddit.js",
"embed.js",
"saved.js",
"messages.js",
"embed/custom-event.js",
"embed/utils.js",
"embed/post-message.js",
"embed/comment-embed.js",
PermissionsDataSource({
"moderator": ModeratorPermissionSet,
"moderator_invite": ModeratorPermissionSet,

View File

@@ -173,6 +173,7 @@ def js_config(extra_config=None):
"adtracker_url": g.adtracker_url,
"clicktracker_url": g.clicktracker_url,
"uitracker_url": g.uitracker_url,
"eventtracker_url": g.eventtracker_url,
"comment_embed_scripts": js.src("comment-embed", absolute=True, mangle_name=False),
"static_root": static(''),
"over_18": bool(c.over18),

View File

@@ -101,7 +101,7 @@
var serializedOptions = typeof options !== 'string' ?
serializeOptions(options) : options;
window.rembeddit.init({}, function() {
window.rembeddit.init({track: false}, function() {
var height = 0;
var reflow = setInterval(function() {
@@ -125,6 +125,10 @@
});
}
var tracker = new window.rembeddit.PixelTracker({
url: r.config.eventtracker_url,
});
$('body').on('click', '.embed-comment', function(e) {
var $el = $(e.target);
var data = $el.data();
@@ -174,6 +178,33 @@
$textarea.on('focus', function() {
$(this).select();
if (!created) {
var data = $el.data();
var options = getEmbedOptions(data);
var now = new Date();
var ts = now.getTime();
tracker.send({
'event_topic': 'embed',
'event_name': 'embed_create',
'event_ts': ts,
'event_ts_utc_offset': now.getTimezoneOffset() / -60,
'embed_type': options.parent ? 'comment_and_parent' : 'comment',
'user_agent': navigator.userAgent,
'user_id': r.config.user_id,
'logged_in_status': !!r.config.logged,
'sr_id': r.utils.fullnameToId(r.config.cur_site),
'sr_name': r.config.post_site,
'embed_id': r.utils.fullnameToId($el.thing_id()),
'embed_created_ts': ts,
'embed_control': options.live,
'embed_host_url': location.href,
'embed_version': window.rembeddit.VERSION,
});
created = true;
}
});
popup.on('closed.r.popup', function() {

View File

@@ -63,6 +63,8 @@
return;
}
App.addPostMessageOrigin(embed.getAttribute('data-embed-media'));
iframe.height = 0;
iframe.width = '100%';
iframe.scrolling = 'no';
@@ -85,7 +87,8 @@
callback(e);
App.postMessage(iframe.contentWindow, 'pong', {
type: 'comment',
type: embed.getAttribute('data-embed-parent') === 'true' ?
'comment_and_parent' : 'comment',
location: location,
options: options,
});

View File

@@ -1,8 +1,13 @@
;(function(App, window, undefined) {
App.VERSION = '0.1';
var RE_HOST = /^https?:\/\/([^\/|?]+).*/;
var config = window.REDDIT_EMBED_CONFIG;
var thing = config.thing;
App.addPostMessageOrigin(window.location.host);
if (document.referrer && document.referrer.match(RE_HOST)) {
App.addPostMessageOrigin(RegExp.$1);
}
function checkHeight() {
var height = document.body.clientHeight;
@@ -14,8 +19,87 @@
}
}
function createPayloadFactory(location) {
return function payloadFactory(type, action, payload) {
var now = new Date();
var data = {
'event_topic': 'embed',
'event_name': 'embed_' + action,
'event_ts': now.getTime(),
'event_ts_utc_offset': now.getTimezoneOffset() / -60,
'user_agent': navigator.userAgent,
'logged_in_status': !!config.logged,
'embed_ts_created': config.created,
'sr_id': thing.sr_id,
'sr_name': thing.sr_name,
'embed_id': thing.id,
'embed_version': App.VERSION,
'embed_type': type,
'embed_control': config.showedits,
'embed_host_url': location.href,
'comment_edited': thing.edited,
'comment_deleted': thing.deleted,
};
for (var name in payload) {
data[name] = payload[name];
}
return data;
};
}
setInterval(checkHeight, 100);
App.receiveMessage(window.parent, 'pong', function(e) {
var type = e.detail.type;
var options = e.detail.options;
var location = e.detail.location;
var createPayload = createPayloadFactory(location);
if (options.track === false) {
return;
}
var tracker = new App.PixelTracker({
url: config.eventtracker_url,
});
tracker.send(createPayload(type, 'view'));
function trackLink(e) {
var el = this;
var base = document.getElementsByTagName('base');
var target = el.target || (base && base[0] && base[0].target);
var newTab = target === '_blank';
var payload = {
'redirect_url': el.href,
'redirect_type': el.getAttribute('data-redirect-type'),
'redirect_dest': el.host,
'redirect_thing_id': el.getAttribute('data-redirect-thing'),
};
tracker.send(createPayload(type, 'click', payload), function() {
if (!newTab) {
window.top.location.href = el.href;
}
});
return newTab;
}
var trackLinks = document.getElementsByTagName('a');
for (var i = 0, l = trackLinks.length; i < l; i++) {
var link = trackLinks[i];
if (link.getAttribute('data-redirect-type')) {
trackLinks[i].addEventListener('click', trackLink, false);
}
}
});
App.postMessage(window.parent, 'ping', {
config: config,
});

View File

@@ -0,0 +1,27 @@
!function(App, window, undefined) {
var PixelTracker = App.PixelTracker = function(options) {
this._pixelTrackingUrl = options.url;
};
PixelTracker.prototype.send = function(payload, callback) {
callback = callback || function() {};
if (!this._pixelTrackingUrl || !payload) {
callback();
return;
}
payload.uuid = App.utils.uuid();
var image = new Image();
var buster = Math.round(Math.random() * 2147483647);
image.onload = callback;
image.src = this._pixelTrackingUrl +
'?r=' + buster +
'&data=' + encodeURIComponent(JSON.stringify(payload));
};
}((window.rembeddit = window.rembeddit || {}), this);

View File

@@ -37,4 +37,18 @@
return found;
};
// http://stackoverflow.com/a/8809472/704286
App.utils.uuid = function() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
};
})((window.rembeddit = window.rembeddit || {}), this);

View File

@@ -1,5 +1,12 @@
r.utils = {
fullnameToId: function(fullname) {
var parts = fullname.split('_');
var id36 = parts && parts[1];
return id36 && parseInt(id36, 36);
},
escapeSelector: function(str) {
return str.replace(/([ #;?%&,.+*~\':"!^$[\]()=>|\/@])/g,'\\$1');
},