SlideShare una empresa de Scribd logo
1 de 44
Descargar para leer sin conexión
Spicy Javascript
Alban Gérôme
@albangerome
MeasureCamp London
11 July 2020
Your first Chrome Extension for Web Analytics QA
Spicy javascript: Create your first Chrome extension for web analytics QA
Why a Chrome Extension?
• Intercept, block, redirect, report all web requests
• Inject Javascript code anywhere, any time of the page
• Surface all the analytics tracking on the current web
page
Why a Chrome Extension?
• Inject code on the page locally without speaking to a
single web developer before the page has even
finished rendering
• Surface deep internal Adobe Launch rules information
• Report the information using little-known Javascript
console tricks
Spicy javascript: Create your first Chrome extension for web analytics QA
The Four Elements
• Manifest file
• Content script
• Popup script
• Background script
mandatory metadata
runs on the current page
runs in the extension popup
invisible broker
Spicy javascript: Create your first Chrome extension for web analytics QA
Manifest
{
"name": "Duckface",
"version": "1.1",
"manifest_version": 2,
"description": "Adobe Launch Debugger",
"browser_action": {
"default_icon": "duckface-icon.png",
"default_popup": "duckface2.html"
},
"permissions": [
"webRequest",
"<all_urls>",
"activeTab"
],
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content2.js"],
"run_at": "document_start"
}],
"background": {
"persistent": true,
"scripts": [
"background2.js"
]
}
}
Manifest
{
"name": "Duckface",
"version": "1.1",
"manifest_version": 2,
"description": "Adobe Launch Debugger",
"browser_action": {
"default_icon": "duckface-icon.png",
"default_popup": "duckface2.html"
},
"permissions": [
"webRequest",
"<all_urls>",
"activeTab"
],
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content2.js"],
"run_at": "document_start"
}],
"background": {
"persistent": true,
"scripts": [
"background2.js"
]
}
}
Manifest
{
"name": "Duckface",
"version": "1.1",
"manifest_version": 2,
"description": "Adobe Launch Debugger",
"browser_action": {
"default_icon": "duckface-icon.png",
"default_popup": "duckface2.html"
},
"permissions": [
"webRequest",
"<all_urls>",
"activeTab"
],
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content2.js"],
"run_at": "document_start"
}],
"background": {
"persistent": true,
"scripts": [
"background2.js"
]
}
}
Manifest
{
"name": "Duckface",
"version": "1.1",
"manifest_version": 2,
"description": "Adobe Launch Debugger",
"browser_action": {
"default_icon": "duckface-icon.png",
"default_popup": "duckface2.html"
},
"permissions": [
"webRequest",
"<all_urls>",
"activeTab"
],
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content2.js"],
"run_at": "document_start"
}],
"background": {
"persistent": true,
"scripts": [
"background2.js"
]
}
}
Manifest
{
"name": "Duckface",
"version": "1.1",
"manifest_version": 2,
"description": "Adobe Launch Debugger",
"browser_action": {
"default_icon": "duckface-icon.png",
"default_popup": "duckface2.html"
},
"permissions": [
"webRequest",
"<all_urls>",
"activeTab"
],
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content2.js"],
"run_at": "document_start"
}],
"background": {
"persistent": true,
"scripts": [
"background2.js"
]
}
}
Spicy javascript: Create your first Chrome extension for web analytics QA
Content
• Executes on the page you see in Chrome
• Observes the page as it builds
• Intercepts the script element loading Adobe Launch
• Injects Adobe Launch monitoring hooks in response
• Receives from the extension popup the rule identifiers
• Generates the output in the console
Observe DOM Mutations
new MutationObserver(r => r.map(s => {
const t = s.addedNodes;
if(t && t.length==1){
const u = t[0];
if(u && u.nodeName=="SCRIPT" && /^https://assets.adobedtm.com/launch-/.test(u.src))
u.insertAdjacentElement("beforebegin", e);
};
})).observe(document.documentElement, {
childList: !0,
subtree: !0
});
Observe DOM Mutations
new MutationObserver(r => r.map(s => {
const t = s.addedNodes;
if(t && t.length==1){
const u = t[0];
if(u && u.nodeName=="SCRIPT" && /^https://assets.adobedtm.com/launch-/.test(u.src))
u.insertAdjacentElement("beforebegin", e);
};
})).observe(document.documentElement, {
childList: !0,
subtree: !0
});
Observe DOM Mutations
new MutationObserver(r => r.map(s => {
const t = s.addedNodes;
if(t && t.length==1){
const u = t[0];
if(u && u.nodeName=="SCRIPT" && /^https://assets.adobedtm.com/launch-/.test(u.src))
u.insertAdjacentElement("beforebegin", e);
};
})).observe(document.documentElement, {
childList: !0,
subtree: !0
});
Spicy javascript: Create your first Chrome extension for web analytics QA
Adobe Launch monitoring hooks
window._satellite = window._satellite || {};
window._satellite._monitors = window._satellite._monitors || [];
window._satellite._monitors.push({
ruleTriggered: q => h(q, 'rule triggered'),
ruleCompleted: q => h(q, 'rule completed'),
ruleActionFailed: q => h(q, 'rule action failed'),
ruleConditionFailed: q => h(q, 'rule condition failed')
});
Spicy javascript: Create your first Chrome extension for web analytics QA
Popup
<!doctype html>
<html>
<head>
<title>Duckface</title>
<link rel="stylesheet" type="text/css" href="duckface2.css" />
</head>
<body>
<form>
<input type="text" id="rule" autofocus />
<input type="button" value="Submit" id="submit" />
<input type="button" value="Reset" id="reset" />
</form>
</body>
<script type="text/javascript" src="duckface2.js"></script>
</html>
Popup
<!doctype html>
<html>
<head>
<title>Duckface</title>
<link rel="stylesheet" type="text/css" href="duckface2.css" />
</head>
<body>
<form>
<input type="text" id="rule" autofocus />
<input type="button" value="Submit" id="submit" />
<input type="button" value="Reset" id="reset" />
</form>
</body>
<script type="text/javascript" src="duckface2.js"></script>
</html>
Spicy javascript: Create your first Chrome extension for web analytics QA
Background
chrome.webRequest.onBeforeRequest.addListener(e => {
let f = e.url, g;
try{
if(e.requestBody && e.requestBody.raw && e.requestBody.raw[0]) g =
decodeURIComponent(String.fromCharCode.apply(null, new Uint8Array(e.requestBody.raw[0].bytes)))
if(b==e.tabId){
let D = {url : f};
if(e.method=="POST") D.postPayload = g;
C.push(D);
};
}catch(h){
console.log(h.message);
};
}, {urls : ["<all_urls>"]}, ["requestBody"]);
Background
chrome.webRequest.onBeforeRequest.addListener(e => {
let f = e.url, g;
try{
if(e.requestBody && e.requestBody.raw && e.requestBody.raw[0]) g =
decodeURIComponent(String.fromCharCode.apply(null, new Uint8Array(e.requestBody.raw[0].bytes)))
if(b==e.tabId){
let D = {url : f};
if(e.method=="POST") D.postPayload = g;
C.push(D);
};
}catch(h){
console.log(h.message);
};
}, {urls : ["<all_urls>"]}, ["requestBody"]);
Background
chrome.webRequest.onBeforeRequest.addListener(e => {
let f = e.url, g;
try{
if(e.requestBody && e.requestBody.raw && e.requestBody.raw[0]) g =
decodeURIComponent(String.fromCharCode.apply(null, new Uint8Array(e.requestBody.raw[0].bytes)))
if(b==e.tabId){
let D = {url : f};
if(e.method=="POST") D.postPayload = g;
C.push(D);
};
}catch(h){
console.log(h.message);
};
}, {urls : ["<all_urls>"]}, ["requestBody"]);
Spicy javascript: Create your first Chrome extension for web analytics QA
Messaging
Can
Respond
Can
Listen
Can
Initiate
Content Yes Yes Yes
Popup Yes No Yes
Background Yes Yes No
Messaging from popup to backgd
chrome.runtime.sendMessage({
somethingRandom : "Anything will do"
}, response => {
console.log(response);
});
Messaging from popup to content
chrome.tabs.query({active: true, currentWindow: true}, tabs => {
chrome.tabs.sendMessage(tabs[0].id, {
rule : rule
}, response => {
console.log(response);
});
});
Messaging from content
Same as for messages from popup to background
Received by popup and background
chrome.runtime.sendMessage({
somethingRandom : "Anything will do"
}, response => {
console.log(response);
});
Listening and responding
Only content and background scripts can listen
chrome.runtime.onMessage.addListener((message, sender,
sendResponse) => {
sendResponse({
somethingElse : "message received"
});
});
Spicy javascript: Create your first Chrome extension for web analytics QA
Console tricks
• console.group("this is an expanded group");
console.log(1);
console.log(2);
console.groupEnd();
• console.groupCollapsed("this is a collapsed group");
console.log(3);
console.log(4);
console.groupEnd();
Console tricks
• console.log(1);
• var a=2; console.log(`string template ${a}`);
• var b=3, c=4; console.log("%cb%cc", "color:red", "font-weight:bold");
• var d="background-
image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATC
AIAAAD9MqGbAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcw
AADsMAAA7DAcdvqGQAAAFNSURBVDhPY/hPLhjkOvfv219VUXH+3HkIF4vOSxcvT
p44MTIs3MPFtbmxsaigMDkhkZeTiwEM+Ll5YqOijx87hqKzvbVNiI+fh4NTREBQSkxc
WlxCVFAIqNrM2OTokaP37t79/v07VCnczon9/YK8fCL8AooyssryChCkKCsnKyl19swZ
iBo0wHDq5ClJUTGgwVysbHyc3ApIOuWlZfS0tKEKMQDUzh8/frx9+/bZ06cSIqIK0jIQ
nUpy8hzMLBAFmAA9hIBeF+YTAOqBaOZkYYVKYAAsYWuoqycnJQ2xk52JGSqKAbD
odHZwlJGQBOoEhpAgDx9UFANg0Tl18mRhPn6gTqB+Z3sHqCgGwKITCAS4eYAWA
mP/xfPnUCEMgF1nalKyML8AO+6ABQLsOoFAW10TqBnKwQZw6vzw4QMw0UI52A
BOnQQBuTr//wcAng5zdjL4M8cAAAAASUVORK5CYII=');background-repeat:no-
repeat"; console.log(`%c ${a} ${b} ${c}`, d);
Console tricks
• var e="expanded";
console.group(`%c ${e} group`, "font-weight:bold");
console.log(5);
console.log(6);
console.groupEnd();
• var f="collapsed";
console.groupCollapsed(`%c ${f} group`, "font-weight:italic");
console.log(5);
console.log(6);
console.groupEnd();
Console tricks
console.table([
{"d" : 1, "e" : 2, "f" : 3},
{"d" : 4, "e" : 5, "f" : 6},
{"d" : 7, "e" : 8, "f" : 9}
]);
console.table({
"a" : {"d" : 1, "e" : 2, "f" : 3},
"b" : {"d" : 4, "e" : 5, "f" : 6},
"c" : {"d" : 7, "e" : 8, "f" : 9}
});
Packing the extension
Extension demo
Extension demo
Extension demo
Quack quack!
http://www.albangerome.com
@albangerome
Thank you!
References
• All the code is available at https://github.com/alban-gerome/adobe-
analytics/blob/master/README.md
• Adobe Launch monitoring hooks info at:
• https://medium.com/adobetech/launch-library-monitoring-hooks-
c674d16deae3
• https://github.com/adobe/reactor-turbine/tree/master/src/rules

Más contenido relacionado

La actualidad más candente

Protocol-Oriented Networking
Protocol-Oriented NetworkingProtocol-Oriented Networking
Protocol-Oriented NetworkingMostafa Amer
 
The Ring programming language version 1.6 book - Part 41 of 189
The Ring programming language version 1.6 book - Part 41 of 189The Ring programming language version 1.6 book - Part 41 of 189
The Ring programming language version 1.6 book - Part 41 of 189Mahmoud Samir Fayed
 
GDG Cloud Taipei: Meetup #52 - Istio Security: API Authorization
GDG Cloud Taipei: Meetup #52 - Istio Security: API AuthorizationGDG Cloud Taipei: Meetup #52 - Istio Security: API Authorization
GDG Cloud Taipei: Meetup #52 - Istio Security: API AuthorizationKAI CHU CHUNG
 
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume LaforgeGroovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume LaforgeGuillaume Laforge
 
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTRT3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTRDavid Gómez García
 
14922 java script built (1)
14922 java script built (1)14922 java script built (1)
14922 java script built (1)dineshrana201992
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineAndy McKay
 
mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecturezefhemel
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETtdc-globalcode
 
maxbox starter72 multilanguage coding
maxbox starter72 multilanguage codingmaxbox starter72 multilanguage coding
maxbox starter72 multilanguage codingMax Kleiner
 
Scala for scripting
Scala for scriptingScala for scripting
Scala for scriptingday
 
SymfonyCon Berlin 2016 Jenkins Deployment Pipelines
SymfonyCon Berlin 2016 Jenkins Deployment PipelinesSymfonyCon Berlin 2016 Jenkins Deployment Pipelines
SymfonyCon Berlin 2016 Jenkins Deployment Pipelinescpsitgmbh
 
Compatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsCompatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsKai Cui
 
Understanding reactive programming with microsoft reactive extensions
Understanding reactive programming  with microsoft reactive extensionsUnderstanding reactive programming  with microsoft reactive extensions
Understanding reactive programming with microsoft reactive extensionsOleksandr Zhevzhyk
 
The Challenges of Container Configuration
The Challenges of Container ConfigurationThe Challenges of Container Configuration
The Challenges of Container ConfigurationGareth Rushgrove
 
The Ring programming language version 1.4.1 book - Part 18 of 31
The Ring programming language version 1.4.1 book - Part 18 of 31The Ring programming language version 1.4.1 book - Part 18 of 31
The Ring programming language version 1.4.1 book - Part 18 of 31Mahmoud Samir Fayed
 

La actualidad más candente (20)

groovy & grails - lecture 9
groovy & grails - lecture 9groovy & grails - lecture 9
groovy & grails - lecture 9
 
Protocol-Oriented Networking
Protocol-Oriented NetworkingProtocol-Oriented Networking
Protocol-Oriented Networking
 
TDD per Webapps
TDD per WebappsTDD per Webapps
TDD per Webapps
 
The Ring programming language version 1.6 book - Part 41 of 189
The Ring programming language version 1.6 book - Part 41 of 189The Ring programming language version 1.6 book - Part 41 of 189
The Ring programming language version 1.6 book - Part 41 of 189
 
GDG Cloud Taipei: Meetup #52 - Istio Security: API Authorization
GDG Cloud Taipei: Meetup #52 - Istio Security: API AuthorizationGDG Cloud Taipei: Meetup #52 - Istio Security: API Authorization
GDG Cloud Taipei: Meetup #52 - Istio Security: API Authorization
 
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume LaforgeGroovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
 
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTRT3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
 
14922 java script built (1)
14922 java script built (1)14922 java script built (1)
14922 java script built (1)
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
 
mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecture
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NET
 
maxbox starter72 multilanguage coding
maxbox starter72 multilanguage codingmaxbox starter72 multilanguage coding
maxbox starter72 multilanguage coding
 
Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
 
Scala for scripting
Scala for scriptingScala for scripting
Scala for scripting
 
SymfonyCon Berlin 2016 Jenkins Deployment Pipelines
SymfonyCon Berlin 2016 Jenkins Deployment PipelinesSymfonyCon Berlin 2016 Jenkins Deployment Pipelines
SymfonyCon Berlin 2016 Jenkins Deployment Pipelines
 
Compatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsCompatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensions
 
Understanding reactive programming with microsoft reactive extensions
Understanding reactive programming  with microsoft reactive extensionsUnderstanding reactive programming  with microsoft reactive extensions
Understanding reactive programming with microsoft reactive extensions
 
Test
TestTest
Test
 
The Challenges of Container Configuration
The Challenges of Container ConfigurationThe Challenges of Container Configuration
The Challenges of Container Configuration
 
The Ring programming language version 1.4.1 book - Part 18 of 31
The Ring programming language version 1.4.1 book - Part 18 of 31The Ring programming language version 1.4.1 book - Part 18 of 31
The Ring programming language version 1.4.1 book - Part 18 of 31
 

Similar a Spicy javascript: Create your first Chrome extension for web analytics QA

CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
The Big Picture and How to Get Started
The Big Picture and How to Get StartedThe Big Picture and How to Get Started
The Big Picture and How to Get Startedguest1af57e
 
Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2Asher Martin
 
Parse cloud code
Parse cloud codeParse cloud code
Parse cloud code維佋 唐
 
Enhance Web Performance
Enhance Web PerformanceEnhance Web Performance
Enhance Web PerformanceAdam Lu
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensionserwanl
 
How to automate all your SEO projects
How to automate all your SEO projectsHow to automate all your SEO projects
How to automate all your SEO projectsVincent Terrasi
 
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...BradNeuberg
 
Performance Metrics in a Day with Selenium
Performance Metrics in a Day with SeleniumPerformance Metrics in a Day with Selenium
Performance Metrics in a Day with SeleniumMark Watson
 
The Ring programming language version 1.10 book - Part 50 of 212
The Ring programming language version 1.10 book - Part 50 of 212The Ring programming language version 1.10 book - Part 50 of 212
The Ring programming language version 1.10 book - Part 50 of 212Mahmoud Samir Fayed
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Guillaume Laforge
 
Django - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazosDjango - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazosIgor Sobreira
 
Refresh Austin - Intro to Dexy
Refresh Austin - Intro to DexyRefresh Austin - Intro to Dexy
Refresh Austin - Intro to Dexyananelson
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)Christian Rokitta
 

Similar a Spicy javascript: Create your first Chrome extension for web analytics QA (20)

CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
The Big Picture and How to Get Started
The Big Picture and How to Get StartedThe Big Picture and How to Get Started
The Big Picture and How to Get Started
 
Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2
 
huhu
huhuhuhu
huhu
 
Parse cloud code
Parse cloud codeParse cloud code
Parse cloud code
 
Enhance Web Performance
Enhance Web PerformanceEnhance Web Performance
Enhance Web Performance
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensions
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fallHtml5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
 
Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
How to automate all your SEO projects
How to automate all your SEO projectsHow to automate all your SEO projects
How to automate all your SEO projects
 
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
 
Performance Metrics in a Day with Selenium
Performance Metrics in a Day with SeleniumPerformance Metrics in a Day with Selenium
Performance Metrics in a Day with Selenium
 
The Ring programming language version 1.10 book - Part 50 of 212
The Ring programming language version 1.10 book - Part 50 of 212The Ring programming language version 1.10 book - Part 50 of 212
The Ring programming language version 1.10 book - Part 50 of 212
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
Django - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazosDjango - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazos
 
Sanjeev ghai 12
Sanjeev ghai 12Sanjeev ghai 12
Sanjeev ghai 12
 
Html5 Overview
Html5 OverviewHtml5 Overview
Html5 Overview
 
Refresh Austin - Intro to Dexy
Refresh Austin - Intro to DexyRefresh Austin - Intro to Dexy
Refresh Austin - Intro to Dexy
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)
 

Más de Alban Gérôme

Avoir de l’impact, autrement
Avoir de l’impact, autrementAvoir de l’impact, autrement
Avoir de l’impact, autrementAlban Gérôme
 
Earning more as a Digital or Web Analyst
Earning more as a Digital or Web AnalystEarning more as a Digital or Web Analyst
Earning more as a Digital or Web AnalystAlban Gérôme
 
Is it just me, or the C-suite doesn't care about data?
Is it just me, or the C-suite doesn't care about data?Is it just me, or the C-suite doesn't care about data?
Is it just me, or the C-suite doesn't care about data?Alban Gérôme
 
Cracking trading cards packs and web analytics
Cracking trading cards packs and web analyticsCracking trading cards packs and web analytics
Cracking trading cards packs and web analyticsAlban Gérôme
 
The us vs the uk web analytics job slideshare
The us vs the uk web analytics job slideshareThe us vs the uk web analytics job slideshare
The us vs the uk web analytics job slideshareAlban Gérôme
 
Implementing Web Analytics on Single Page Applications
Implementing Web Analytics on Single Page ApplicationsImplementing Web Analytics on Single Page Applications
Implementing Web Analytics on Single Page ApplicationsAlban Gérôme
 
Automating boring tasks with Powershell
Automating boring tasks with PowershellAutomating boring tasks with Powershell
Automating boring tasks with PowershellAlban Gérôme
 
Influence and Persuasion
Influence and PersuasionInfluence and Persuasion
Influence and PersuasionAlban Gérôme
 
Reshaping the Hype Cycle
Reshaping the Hype CycleReshaping the Hype Cycle
Reshaping the Hype CycleAlban Gérôme
 
Claiming credit for being data-driven
Claiming credit for being data-drivenClaiming credit for being data-driven
Claiming credit for being data-drivenAlban Gérôme
 
Acceptance, Accessible, Applicable et Auditable
Acceptance, Accessible, Applicable et AuditableAcceptance, Accessible, Applicable et Auditable
Acceptance, Accessible, Applicable et AuditableAlban Gérôme
 
Acceptance, Accessible, Actionable and Auditable
Acceptance, Accessible, Actionable and AuditableAcceptance, Accessible, Actionable and Auditable
Acceptance, Accessible, Actionable and AuditableAlban Gérôme
 
Are you still working for a data justified company?
Are you still working for a data justified company?Are you still working for a data justified company?
Are you still working for a data justified company?Alban Gérôme
 
Build your own analytics power tools
Build your own analytics power toolsBuild your own analytics power tools
Build your own analytics power toolsAlban Gérôme
 
Is data visualisation bullshit?
Is data visualisation bullshit?Is data visualisation bullshit?
Is data visualisation bullshit?Alban Gérôme
 
Acceptance, accessible, actionable and auditable
Acceptance, accessible, actionable and auditableAcceptance, accessible, actionable and auditable
Acceptance, accessible, actionable and auditableAlban Gérôme
 

Más de Alban Gérôme (20)

Avoir de l’impact, autrement
Avoir de l’impact, autrementAvoir de l’impact, autrement
Avoir de l’impact, autrement
 
Earning more as a Digital or Web Analyst
Earning more as a Digital or Web AnalystEarning more as a Digital or Web Analyst
Earning more as a Digital or Web Analyst
 
Is it just me, or the C-suite doesn't care about data?
Is it just me, or the C-suite doesn't care about data?Is it just me, or the C-suite doesn't care about data?
Is it just me, or the C-suite doesn't care about data?
 
Cracking trading cards packs and web analytics
Cracking trading cards packs and web analyticsCracking trading cards packs and web analytics
Cracking trading cards packs and web analytics
 
The us vs the uk web analytics job slideshare
The us vs the uk web analytics job slideshareThe us vs the uk web analytics job slideshare
The us vs the uk web analytics job slideshare
 
Implementing Web Analytics on Single Page Applications
Implementing Web Analytics on Single Page ApplicationsImplementing Web Analytics on Single Page Applications
Implementing Web Analytics on Single Page Applications
 
Tagging differently
Tagging differentlyTagging differently
Tagging differently
 
Automating boring tasks with Powershell
Automating boring tasks with PowershellAutomating boring tasks with Powershell
Automating boring tasks with Powershell
 
Influence and Persuasion
Influence and PersuasionInfluence and Persuasion
Influence and Persuasion
 
Reshaping the Hype Cycle
Reshaping the Hype CycleReshaping the Hype Cycle
Reshaping the Hype Cycle
 
Claiming credit for being data-driven
Claiming credit for being data-drivenClaiming credit for being data-driven
Claiming credit for being data-driven
 
Acceptance, Accessible, Applicable et Auditable
Acceptance, Accessible, Applicable et AuditableAcceptance, Accessible, Applicable et Auditable
Acceptance, Accessible, Applicable et Auditable
 
Acceptance, Accessible, Actionable and Auditable
Acceptance, Accessible, Actionable and AuditableAcceptance, Accessible, Actionable and Auditable
Acceptance, Accessible, Actionable and Auditable
 
Logic or emotions
Logic or emotionsLogic or emotions
Logic or emotions
 
Hub and spoke model
Hub and spoke modelHub and spoke model
Hub and spoke model
 
Are you still working for a data justified company?
Are you still working for a data justified company?Are you still working for a data justified company?
Are you still working for a data justified company?
 
Persuasion
PersuasionPersuasion
Persuasion
 
Build your own analytics power tools
Build your own analytics power toolsBuild your own analytics power tools
Build your own analytics power tools
 
Is data visualisation bullshit?
Is data visualisation bullshit?Is data visualisation bullshit?
Is data visualisation bullshit?
 
Acceptance, accessible, actionable and auditable
Acceptance, accessible, actionable and auditableAcceptance, accessible, actionable and auditable
Acceptance, accessible, actionable and auditable
 

Último

TINJUAN PEMROSESAN TRANSAKSI DAN ERP.pptx
TINJUAN PEMROSESAN TRANSAKSI DAN ERP.pptxTINJUAN PEMROSESAN TRANSAKSI DAN ERP.pptx
TINJUAN PEMROSESAN TRANSAKSI DAN ERP.pptxDwiAyuSitiHartinah
 
Virtuosoft SmartSync Product Introduction
Virtuosoft SmartSync Product IntroductionVirtuosoft SmartSync Product Introduction
Virtuosoft SmartSync Product Introductionsanjaymuralee1
 
Mapping the pubmed data under different suptopics using NLP.pptx
Mapping the pubmed data under different suptopics using NLP.pptxMapping the pubmed data under different suptopics using NLP.pptx
Mapping the pubmed data under different suptopics using NLP.pptxVenkatasubramani13
 
CI, CD -Tools to integrate without manual intervention
CI, CD -Tools to integrate without manual interventionCI, CD -Tools to integrate without manual intervention
CI, CD -Tools to integrate without manual interventionajayrajaganeshkayala
 
Master's Thesis - Data Science - Presentation
Master's Thesis - Data Science - PresentationMaster's Thesis - Data Science - Presentation
Master's Thesis - Data Science - PresentationGiorgio Carbone
 
The Universal GTM - how we design GTM and dataLayer
The Universal GTM - how we design GTM and dataLayerThe Universal GTM - how we design GTM and dataLayer
The Universal GTM - how we design GTM and dataLayerPavel Šabatka
 
ChistaDATA Real-Time DATA Analytics Infrastructure
ChistaDATA Real-Time DATA Analytics InfrastructureChistaDATA Real-Time DATA Analytics Infrastructure
ChistaDATA Real-Time DATA Analytics Infrastructuresonikadigital1
 
How is Real-Time Analytics Different from Traditional OLAP?
How is Real-Time Analytics Different from Traditional OLAP?How is Real-Time Analytics Different from Traditional OLAP?
How is Real-Time Analytics Different from Traditional OLAP?sonikadigital1
 
Elements of language learning - an analysis of how different elements of lang...
Elements of language learning - an analysis of how different elements of lang...Elements of language learning - an analysis of how different elements of lang...
Elements of language learning - an analysis of how different elements of lang...PrithaVashisht1
 
Cash Is Still King: ATM market research '2023
Cash Is Still King: ATM market research '2023Cash Is Still King: ATM market research '2023
Cash Is Still King: ATM market research '2023Vladislav Solodkiy
 
Strategic CX: A Deep Dive into Voice of the Customer Insights for Clarity
Strategic CX: A Deep Dive into Voice of the Customer Insights for ClarityStrategic CX: A Deep Dive into Voice of the Customer Insights for Clarity
Strategic CX: A Deep Dive into Voice of the Customer Insights for ClarityAggregage
 
CCS336-Cloud-Services-Management-Lecture-Notes-1.pptx
CCS336-Cloud-Services-Management-Lecture-Notes-1.pptxCCS336-Cloud-Services-Management-Lecture-Notes-1.pptx
CCS336-Cloud-Services-Management-Lecture-Notes-1.pptxdhiyaneswaranv1
 
Rock Songs common codes and conventions.pptx
Rock Songs common codes and conventions.pptxRock Songs common codes and conventions.pptx
Rock Songs common codes and conventions.pptxFinatron037
 
Persuasive E-commerce, Our Biased Brain @ Bikkeldag 2024
Persuasive E-commerce, Our Biased Brain @ Bikkeldag 2024Persuasive E-commerce, Our Biased Brain @ Bikkeldag 2024
Persuasive E-commerce, Our Biased Brain @ Bikkeldag 2024Guido X Jansen
 
Optimal Decision Making - Cost Reduction in Logistics
Optimal Decision Making - Cost Reduction in LogisticsOptimal Decision Making - Cost Reduction in Logistics
Optimal Decision Making - Cost Reduction in LogisticsThinkInnovation
 
5 Ds to Define Data Archiving Best Practices
5 Ds to Define Data Archiving Best Practices5 Ds to Define Data Archiving Best Practices
5 Ds to Define Data Archiving Best PracticesDataArchiva
 

Último (16)

TINJUAN PEMROSESAN TRANSAKSI DAN ERP.pptx
TINJUAN PEMROSESAN TRANSAKSI DAN ERP.pptxTINJUAN PEMROSESAN TRANSAKSI DAN ERP.pptx
TINJUAN PEMROSESAN TRANSAKSI DAN ERP.pptx
 
Virtuosoft SmartSync Product Introduction
Virtuosoft SmartSync Product IntroductionVirtuosoft SmartSync Product Introduction
Virtuosoft SmartSync Product Introduction
 
Mapping the pubmed data under different suptopics using NLP.pptx
Mapping the pubmed data under different suptopics using NLP.pptxMapping the pubmed data under different suptopics using NLP.pptx
Mapping the pubmed data under different suptopics using NLP.pptx
 
CI, CD -Tools to integrate without manual intervention
CI, CD -Tools to integrate without manual interventionCI, CD -Tools to integrate without manual intervention
CI, CD -Tools to integrate without manual intervention
 
Master's Thesis - Data Science - Presentation
Master's Thesis - Data Science - PresentationMaster's Thesis - Data Science - Presentation
Master's Thesis - Data Science - Presentation
 
The Universal GTM - how we design GTM and dataLayer
The Universal GTM - how we design GTM and dataLayerThe Universal GTM - how we design GTM and dataLayer
The Universal GTM - how we design GTM and dataLayer
 
ChistaDATA Real-Time DATA Analytics Infrastructure
ChistaDATA Real-Time DATA Analytics InfrastructureChistaDATA Real-Time DATA Analytics Infrastructure
ChistaDATA Real-Time DATA Analytics Infrastructure
 
How is Real-Time Analytics Different from Traditional OLAP?
How is Real-Time Analytics Different from Traditional OLAP?How is Real-Time Analytics Different from Traditional OLAP?
How is Real-Time Analytics Different from Traditional OLAP?
 
Elements of language learning - an analysis of how different elements of lang...
Elements of language learning - an analysis of how different elements of lang...Elements of language learning - an analysis of how different elements of lang...
Elements of language learning - an analysis of how different elements of lang...
 
Cash Is Still King: ATM market research '2023
Cash Is Still King: ATM market research '2023Cash Is Still King: ATM market research '2023
Cash Is Still King: ATM market research '2023
 
Strategic CX: A Deep Dive into Voice of the Customer Insights for Clarity
Strategic CX: A Deep Dive into Voice of the Customer Insights for ClarityStrategic CX: A Deep Dive into Voice of the Customer Insights for Clarity
Strategic CX: A Deep Dive into Voice of the Customer Insights for Clarity
 
CCS336-Cloud-Services-Management-Lecture-Notes-1.pptx
CCS336-Cloud-Services-Management-Lecture-Notes-1.pptxCCS336-Cloud-Services-Management-Lecture-Notes-1.pptx
CCS336-Cloud-Services-Management-Lecture-Notes-1.pptx
 
Rock Songs common codes and conventions.pptx
Rock Songs common codes and conventions.pptxRock Songs common codes and conventions.pptx
Rock Songs common codes and conventions.pptx
 
Persuasive E-commerce, Our Biased Brain @ Bikkeldag 2024
Persuasive E-commerce, Our Biased Brain @ Bikkeldag 2024Persuasive E-commerce, Our Biased Brain @ Bikkeldag 2024
Persuasive E-commerce, Our Biased Brain @ Bikkeldag 2024
 
Optimal Decision Making - Cost Reduction in Logistics
Optimal Decision Making - Cost Reduction in LogisticsOptimal Decision Making - Cost Reduction in Logistics
Optimal Decision Making - Cost Reduction in Logistics
 
5 Ds to Define Data Archiving Best Practices
5 Ds to Define Data Archiving Best Practices5 Ds to Define Data Archiving Best Practices
5 Ds to Define Data Archiving Best Practices
 

Spicy javascript: Create your first Chrome extension for web analytics QA

  • 1. Spicy Javascript Alban Gérôme @albangerome MeasureCamp London 11 July 2020 Your first Chrome Extension for Web Analytics QA
  • 3. Why a Chrome Extension? • Intercept, block, redirect, report all web requests • Inject Javascript code anywhere, any time of the page • Surface all the analytics tracking on the current web page
  • 4. Why a Chrome Extension? • Inject code on the page locally without speaking to a single web developer before the page has even finished rendering • Surface deep internal Adobe Launch rules information • Report the information using little-known Javascript console tricks
  • 6. The Four Elements • Manifest file • Content script • Popup script • Background script mandatory metadata runs on the current page runs in the extension popup invisible broker
  • 8. Manifest { "name": "Duckface", "version": "1.1", "manifest_version": 2, "description": "Adobe Launch Debugger", "browser_action": { "default_icon": "duckface-icon.png", "default_popup": "duckface2.html" }, "permissions": [ "webRequest", "<all_urls>", "activeTab" ], "content_scripts": [{ "matches": ["<all_urls>"], "js": ["content2.js"], "run_at": "document_start" }], "background": { "persistent": true, "scripts": [ "background2.js" ] } }
  • 9. Manifest { "name": "Duckface", "version": "1.1", "manifest_version": 2, "description": "Adobe Launch Debugger", "browser_action": { "default_icon": "duckface-icon.png", "default_popup": "duckface2.html" }, "permissions": [ "webRequest", "<all_urls>", "activeTab" ], "content_scripts": [{ "matches": ["<all_urls>"], "js": ["content2.js"], "run_at": "document_start" }], "background": { "persistent": true, "scripts": [ "background2.js" ] } }
  • 10. Manifest { "name": "Duckface", "version": "1.1", "manifest_version": 2, "description": "Adobe Launch Debugger", "browser_action": { "default_icon": "duckface-icon.png", "default_popup": "duckface2.html" }, "permissions": [ "webRequest", "<all_urls>", "activeTab" ], "content_scripts": [{ "matches": ["<all_urls>"], "js": ["content2.js"], "run_at": "document_start" }], "background": { "persistent": true, "scripts": [ "background2.js" ] } }
  • 11. Manifest { "name": "Duckface", "version": "1.1", "manifest_version": 2, "description": "Adobe Launch Debugger", "browser_action": { "default_icon": "duckface-icon.png", "default_popup": "duckface2.html" }, "permissions": [ "webRequest", "<all_urls>", "activeTab" ], "content_scripts": [{ "matches": ["<all_urls>"], "js": ["content2.js"], "run_at": "document_start" }], "background": { "persistent": true, "scripts": [ "background2.js" ] } }
  • 12. Manifest { "name": "Duckface", "version": "1.1", "manifest_version": 2, "description": "Adobe Launch Debugger", "browser_action": { "default_icon": "duckface-icon.png", "default_popup": "duckface2.html" }, "permissions": [ "webRequest", "<all_urls>", "activeTab" ], "content_scripts": [{ "matches": ["<all_urls>"], "js": ["content2.js"], "run_at": "document_start" }], "background": { "persistent": true, "scripts": [ "background2.js" ] } }
  • 14. Content • Executes on the page you see in Chrome • Observes the page as it builds • Intercepts the script element loading Adobe Launch • Injects Adobe Launch monitoring hooks in response • Receives from the extension popup the rule identifiers • Generates the output in the console
  • 15. Observe DOM Mutations new MutationObserver(r => r.map(s => { const t = s.addedNodes; if(t && t.length==1){ const u = t[0]; if(u && u.nodeName=="SCRIPT" && /^https://assets.adobedtm.com/launch-/.test(u.src)) u.insertAdjacentElement("beforebegin", e); }; })).observe(document.documentElement, { childList: !0, subtree: !0 });
  • 16. Observe DOM Mutations new MutationObserver(r => r.map(s => { const t = s.addedNodes; if(t && t.length==1){ const u = t[0]; if(u && u.nodeName=="SCRIPT" && /^https://assets.adobedtm.com/launch-/.test(u.src)) u.insertAdjacentElement("beforebegin", e); }; })).observe(document.documentElement, { childList: !0, subtree: !0 });
  • 17. Observe DOM Mutations new MutationObserver(r => r.map(s => { const t = s.addedNodes; if(t && t.length==1){ const u = t[0]; if(u && u.nodeName=="SCRIPT" && /^https://assets.adobedtm.com/launch-/.test(u.src)) u.insertAdjacentElement("beforebegin", e); }; })).observe(document.documentElement, { childList: !0, subtree: !0 });
  • 19. Adobe Launch monitoring hooks window._satellite = window._satellite || {}; window._satellite._monitors = window._satellite._monitors || []; window._satellite._monitors.push({ ruleTriggered: q => h(q, 'rule triggered'), ruleCompleted: q => h(q, 'rule completed'), ruleActionFailed: q => h(q, 'rule action failed'), ruleConditionFailed: q => h(q, 'rule condition failed') });
  • 21. Popup <!doctype html> <html> <head> <title>Duckface</title> <link rel="stylesheet" type="text/css" href="duckface2.css" /> </head> <body> <form> <input type="text" id="rule" autofocus /> <input type="button" value="Submit" id="submit" /> <input type="button" value="Reset" id="reset" /> </form> </body> <script type="text/javascript" src="duckface2.js"></script> </html>
  • 22. Popup <!doctype html> <html> <head> <title>Duckface</title> <link rel="stylesheet" type="text/css" href="duckface2.css" /> </head> <body> <form> <input type="text" id="rule" autofocus /> <input type="button" value="Submit" id="submit" /> <input type="button" value="Reset" id="reset" /> </form> </body> <script type="text/javascript" src="duckface2.js"></script> </html>
  • 24. Background chrome.webRequest.onBeforeRequest.addListener(e => { let f = e.url, g; try{ if(e.requestBody && e.requestBody.raw && e.requestBody.raw[0]) g = decodeURIComponent(String.fromCharCode.apply(null, new Uint8Array(e.requestBody.raw[0].bytes))) if(b==e.tabId){ let D = {url : f}; if(e.method=="POST") D.postPayload = g; C.push(D); }; }catch(h){ console.log(h.message); }; }, {urls : ["<all_urls>"]}, ["requestBody"]);
  • 25. Background chrome.webRequest.onBeforeRequest.addListener(e => { let f = e.url, g; try{ if(e.requestBody && e.requestBody.raw && e.requestBody.raw[0]) g = decodeURIComponent(String.fromCharCode.apply(null, new Uint8Array(e.requestBody.raw[0].bytes))) if(b==e.tabId){ let D = {url : f}; if(e.method=="POST") D.postPayload = g; C.push(D); }; }catch(h){ console.log(h.message); }; }, {urls : ["<all_urls>"]}, ["requestBody"]);
  • 26. Background chrome.webRequest.onBeforeRequest.addListener(e => { let f = e.url, g; try{ if(e.requestBody && e.requestBody.raw && e.requestBody.raw[0]) g = decodeURIComponent(String.fromCharCode.apply(null, new Uint8Array(e.requestBody.raw[0].bytes))) if(b==e.tabId){ let D = {url : f}; if(e.method=="POST") D.postPayload = g; C.push(D); }; }catch(h){ console.log(h.message); }; }, {urls : ["<all_urls>"]}, ["requestBody"]);
  • 28. Messaging Can Respond Can Listen Can Initiate Content Yes Yes Yes Popup Yes No Yes Background Yes Yes No
  • 29. Messaging from popup to backgd chrome.runtime.sendMessage({ somethingRandom : "Anything will do" }, response => { console.log(response); });
  • 30. Messaging from popup to content chrome.tabs.query({active: true, currentWindow: true}, tabs => { chrome.tabs.sendMessage(tabs[0].id, { rule : rule }, response => { console.log(response); }); });
  • 31. Messaging from content Same as for messages from popup to background Received by popup and background chrome.runtime.sendMessage({ somethingRandom : "Anything will do" }, response => { console.log(response); });
  • 32. Listening and responding Only content and background scripts can listen chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { sendResponse({ somethingElse : "message received" }); });
  • 34. Console tricks • console.group("this is an expanded group"); console.log(1); console.log(2); console.groupEnd(); • console.groupCollapsed("this is a collapsed group"); console.log(3); console.log(4); console.groupEnd();
  • 35. Console tricks • console.log(1); • var a=2; console.log(`string template ${a}`); • var b=3, c=4; console.log("%cb%cc", "color:red", "font-weight:bold"); • var d="background- image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATC AIAAAD9MqGbAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcw AADsMAAA7DAcdvqGQAAAFNSURBVDhPY/hPLhjkOvfv219VUXH+3HkIF4vOSxcvT p44MTIs3MPFtbmxsaigMDkhkZeTiwEM+Ll5YqOijx87hqKzvbVNiI+fh4NTREBQSkxc WlxCVFAIqNrM2OTokaP37t79/v07VCnczon9/YK8fCL8AooyssryChCkKCsnKyl19swZ iBo0wHDq5ClJUTGgwVysbHyc3ApIOuWlZfS0tKEKMQDUzh8/frx9+/bZ06cSIqIK0jIQ nUpy8hzMLBAFmAA9hIBeF+YTAOqBaOZkYYVKYAAsYWuoqycnJQ2xk52JGSqKAbD odHZwlJGQBOoEhpAgDx9UFANg0Tl18mRhPn6gTqB+Z3sHqCgGwKITCAS4eYAWA mP/xfPnUCEMgF1nalKyML8AO+6ABQLsOoFAW10TqBnKwQZw6vzw4QMw0UI52A BOnQQBuTr//wcAng5zdjL4M8cAAAAASUVORK5CYII=');background-repeat:no- repeat"; console.log(`%c ${a} ${b} ${c}`, d);
  • 36. Console tricks • var e="expanded"; console.group(`%c ${e} group`, "font-weight:bold"); console.log(5); console.log(6); console.groupEnd(); • var f="collapsed"; console.groupCollapsed(`%c ${f} group`, "font-weight:italic"); console.log(5); console.log(6); console.groupEnd();
  • 37. Console tricks console.table([ {"d" : 1, "e" : 2, "f" : 3}, {"d" : 4, "e" : 5, "f" : 6}, {"d" : 7, "e" : 8, "f" : 9} ]); console.table({ "a" : {"d" : 1, "e" : 2, "f" : 3}, "b" : {"d" : 4, "e" : 5, "f" : 6}, "c" : {"d" : 7, "e" : 8, "f" : 9} });
  • 44. References • All the code is available at https://github.com/alban-gerome/adobe- analytics/blob/master/README.md • Adobe Launch monitoring hooks info at: • https://medium.com/adobetech/launch-library-monitoring-hooks- c674d16deae3 • https://github.com/adobe/reactor-turbine/tree/master/src/rules