Last active
November 17, 2017 21:09
-
-
Save alewolf/2d8e85a9a753fa5ee4039fb1f779f878 to your computer and use it in GitHub Desktop.
Automatic AdWords Website Phone Conversion Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script type="text/javascript"> | |
// In contrary to the original AdWords Phone Conversion Tracking Script this version doesn't require changes on the website. It even can implemented using Google Tag Manager. | |
// The original AdWords script requires an additional <span> element with an id that encloses the phone number. | |
// This new script doens't require that span element anymore. It autoaticall searches through the entire document and changes all phone numbers that match. Also it searches through all href sources and changes the phone number there too (for clickable phone numbers). | |
// In this version of the script there is one requirement though. The phone number on the website has to bee written in the exact same format, with spaces, etc. Only then the script will find and exchange the numbers. | |
// AdWords phone conversion ID. Since this is a number no quotation marks are necessary. | |
var gak = CONVERSION_ID; // eg. 12345678912 | |
// AdWords conversion label | |
var gcl = 'CONVERSION_LABEL'; // eg. X-AB-12A-ASDFFA | |
// The original phone number unformatted. It has to match exactly the phone number as it appears in the visible text of the website. | |
var original_phone_number_formatted = 'PHONE_NUMBER_FORMATTED'; // eg. +1 22 33 44 55 66 77 | |
// The original phone number unformatted. It has to match exactly the phone number as it appears in the href attribute. | |
var original_phone_number_unformatted = 'PHONE_NUMBER_UNFORMATTED'; // eg. +1223344556677 | |
// An array of all text nodes within the website. | |
var textNodes = []; | |
// A node list of all href nodes within the website that match the unformatted phone number. | |
var refs = document.querySelectorAll( '[href*="' + original_phone_number_unformatted + '"]' ); | |
// Execute findText | |
findText( document.body ); | |
// Find all text nodes within the document recursively. | |
function findText( pnode ) { | |
for ( var i = pnode.childNodes.length; i--; ) { | |
var node = pnode.childNodes[i]; | |
if (node.nodeType == 3) { // text | |
textNodes.push( node ); | |
} else { | |
findText( node ); // recursion | |
} | |
} | |
} | |
// The AdWords script which gets a tracking phone number from Googles servers. | |
(function(a,e,c,f,g,b,d){var h={ak:gak,cl:gcl};a[c]=a[c]||function(){(a[c].q=a[c].q||[]).push(arguments)};a[f]||(a[f]=h.ak);b=e.createElement(g);b.async=1;b.src="//www.gstatic.com/wcm/loader.js";d=e.getElementsByTagName(g)[0];d.parentNode.insertBefore(b,d);a._googWcmGet=function(b,d,e){a[c](2,b,h,d,null,new Date,e)}})(window,document,"_googWcmImpl","_googWcmAk","script"); | |
// Exchange all phone numbers on the website | |
var callback = function(formatted_number, unformatted_number) { | |
// Go through all text nodes and exchange the visible phone numbers | |
for ( var i = textNodes.length; i--; ) { | |
textNodes[i].textContent = textNodes[i].textContent.replace( original_phone_number_formatted, formatted_number ); | |
} | |
// Go through all hrefs and exchange the phone numbers | |
for ( var i = refs.length; i--; ) { | |
refs[i].href = refs[i].href.replace( original_phone_number_unformatted, unformatted_number ); | |
} | |
}; | |
// A function that reliably checks if the DOM has been loaded | |
(function(funcName, baseObj) { | |
// The public function name defaults to window.docReady | |
// but you can pass in your own object and own function name and those will be used | |
// if you want to put them in a different namespace | |
funcName = funcName || "docReady"; | |
baseObj = baseObj || window; | |
var readyList = []; | |
var readyFired = false; | |
var readyEventHandlersInstalled = false; | |
// call this when the document is ready | |
// this function protects itself against being called more than once | |
function ready() { | |
if (!readyFired) { | |
// this must be set to true before we start calling callbacks | |
readyFired = true; | |
for (var i = 0; i < readyList.length; i++) { | |
// if a callback here happens to add new ready handlers, | |
// the docReady() function will see that it already fired | |
// and will schedule the callback to run right after | |
// this event loop finishes so all handlers will still execute | |
// in order and no new ones will be added to the readyList | |
// while we are processing the list | |
readyList[i].fn.call(window, readyList[i].ctx); | |
} | |
// allow any closures held by these functions to free | |
readyList = []; | |
} | |
} | |
function readyStateChange() { | |
if (document.readyState === "complete") { | |
ready(); | |
} | |
} | |
// This is the one public interface | |
// docReady(fn, context); | |
// the context argument is optional - if present, it will be passed | |
// as an argument to the callback | |
baseObj[funcName] = function(callback, context) { | |
if (typeof callback !== "function") { | |
throw new TypeError("callback for docReady(fn) must be a function"); | |
} | |
// if ready has already fired, then just schedule the callback | |
// to fire asynchronously, but right away | |
if (readyFired) { | |
setTimeout(function() { | |
callback(context); | |
}, 1); | |
return; | |
} else { | |
// add the function and context to the list | |
readyList.push({ | |
fn: callback, | |
ctx: context | |
}); | |
} | |
// if document already ready to go, schedule the ready function to run | |
if (document.readyState === "complete") { | |
setTimeout(ready, 1); | |
} else if (!readyEventHandlersInstalled) { | |
// otherwise if we don't have event handlers installed, install them | |
if (document.addEventListener) { | |
// first choice is DOMContentLoaded event | |
document.addEventListener("DOMContentLoaded", ready, false); | |
// backup is window load event | |
window.addEventListener("load", ready, false); | |
} else { | |
// must be IE | |
document.attachEvent("onreadystatechange", readyStateChange); | |
window.attachEvent("onload", ready); | |
} | |
readyEventHandlersInstalled = true; | |
} | |
} | |
})("docReady", window); | |
// Request the tracking phone number from Googles servers | |
docReady(function() { | |
_googWcmGet(callback, original_phone_number_formatted); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment