Page MenuHomePhabricator

anyPageVisit: record referrer class in page_visit events' action_source
Closed, ResolvedPublic5 Estimated Story Points

Description

In T433431 we introduced reusable anyPageVisit.js instrumentation that allows experiments to easily produce specification-conforming page_visit events for calculating:

metrics in GrowthBook, just by writing:

const anyPageVisit = require( './anyPageVisit.js' );
mw.testKitchen.getExperiment( 'my-experiment' ).then(
  ( experiment ) => experiment.use( anyPageVisit )
);

To calculate metrics like "ratio of internally-to-externally-referred-or-direct page visits" (to be defined in GB), we would need to record referrer class in action_source for those page_visit events. Not all experiments will want this, so it should be optional and anyPageVisit should be configurable to record that when requested.

Notes

Noodlin' on implementation for a parameterized anyPageVisit:

**
 * @param {boolean} recordSpecialPageName - whether page_title contextual attribute
 *  is included on visits to Special pages (disabled by default)
 * @param {boolean} recordRawReferrer - whether to record the referrer (raw) on page visits
 * @return {function(mw.testKitchen.EventSenderInterface): void} - the returned function
 */
function anyPageVisit( recordSpecialPageName = false, recordRawReferrer = false ) {
	const interactionData = {};
	const pageVisitAttributes = [
		'page_namespace_id' // Required for metrics concerned with *article* visits specifically
	];
	if ( recordSpecialPageName ) {
		if ( mw.config.get( 'wgCanonicalSpecialPageName' ) ) {
			pageVisitAttributes.push( 'page_title' );
		}
	}
	if ( recordRawReferrer ) {
		interactionData.action_source = document.referrer;
	}
	return ( eventSender ) => {
		eventSender.send( PAGE_VISIT_ACTION, interactionData, pageVisitAttributes );
	};
}

Then to use it:

mw.testKitchen.getExperiment( 'my-experiment' ).then(
  ( experiment ) => experiment.use( anyPageVisit( recordRawReferrer = true ) )
);

Couple of points:

  • We'll want to implement additional parameters over time, so the function signature should support that (maybe use spread syntax or a config parameter with keys like recordRawReferrer?)
  • We don't actually want to record raw referrer, but rather a referrer class: "internal_referrer", "external_referrer", "no_referrer" (or "direct"?)
    • We technically could do "external_search_referrer" and "external_social_referrer" as classes but IMO distinguishing the type of external referrer is not valuable for on-site experiments
    • Dan A.'s pageVisitBotDetection.js may be a helpful reference
    • Referrer classification should align with RefererClassifier.java (what we use for webrequest/pageview data)
  • Should we consider a separate anyPageVisitWithReferrer reusable instrumentation, rather than parameterizing anyPageVisit?
    • No, it's better to have a single parameterized/configurable one so we don't end up duplicating or fragmenting logic across multiple.

Acceptance criteria

Event Timeline

Something to consider: differentiating between different types of internal referrers, e.g. Wikimedia (broadly) vs Wikipedia vs same wiki? e.g. action_source: "internal_referrer|wikimedia" or action_source: "internal_referrer|wikipedia" or action_source: "internal_referrer|same_wiki" – but only if we actually need to differentiate between those in the metrics. Then we can use contains row filter.

JVanderhoop-WMF updated the task description. (Show Details)
JVanderhoop-WMF set the point value for this task to 5.

Change #1328757 had a related patch set uploaded (by Clare Ming; author: Clare Ming):

[mediawiki/extensions/WikimediaEvents@master] anyPageVisit: record referrer class in action_source

https://gerrit.wikimedia.org/r/1328757

Change #1328757 merged by jenkins-bot:

[mediawiki/extensions/WikimediaEvents@master] anyPageVisit: record referrer class in action_source

https://gerrit.wikimedia.org/r/1328757