Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smhmic/07c6835279503206787cd453ca0077fc to your computer and use it in GitHub Desktop.
Save smhmic/07c6835279503206787cd453ca0077fc to your computer and use it in GitHub Desktop.
Add event_id to FB pixels (for redundant deduplicated CAPI tracking)

This does not cover all aspects of setup; just the web pixel side. All this does is add an event_id to all FB pixels (arguably the most complex part of the clientside setup) without having to modify any pixels directly.

This code is for GTM, but would be trivial to modify code for use anywhere.

Usage:

In GTM web container ...

  1. Add Facebook Pixel CAPI Helper as a tag; fire on All Pages.
  2. Add Facebook Event ID as a variable.
  3. In GA4 config tag, set event_id = {{Facebook Event ID}}.
  4. Validate using FB Events Manager. If you see 'Deduplicated' next to the event name, it's working!
function(){
try{
var //globalNamespace = '_fbqSpyData',
//cache = window[globalNamespace] = window[globalNamespace] || {},
//dL = {get:function(k){return cache[k]},set:function(k,v){cache[k]=v}},
dL = google_tag_manager[{{Container ID}}].dataLayer,
dLKey_counter = 'fw.fb.counter',
dLKey_pageloadId = 'fw.core.pageload_id',
pageloadId = {{Pageload ID}} || dL.get(dLKey_pageloadId),
counter;
if( ! pageloadId ) return "";
( counter = dL.get(dLKey_counter) ) || dL.set( dLKey_counter, counter=1 );
return pageloadId+'.'+counter;
}catch(ex){ {{Debug Mode}} && console.error("[GTM Variable: Facebook Event ID]",ex);}
}
<script>
/**
* Deploy clientside to make FB pixels compatible for dual-tracking w/ CAPI.
* Uses https://github.com/smhmic/fbq-spy to listen for data passed to Facebook's
* fbevents.js' `fbq()` and add an event_id to all FB pixels.
*/
window.fbqSpy=window.fbqSpy||function(n){function e(){var e,n=c._fbqOrig=window[u];for(e in r("Hijack",n._fbqOrig?"(already hijacked)":""),window[u]=c,n)n.hasOwnProperty(e)&&(window[u][e]=n[e]===n?c:n[e])}var o,t,a=function(e){if(n=null,e.debugLogPrefix=e.debugLogPrefix||"fbqSpy",e.debug=!!e.debug,!e.callback||"function"!=typeof e.callback){if(e.debug)throw new Error("["+e.debugLogPrefix+"] Aborting; No listener callback provided.");e.callback=function(){}}return e.fbqObjName=e.fbqObjName||"fbq",e}("function"==typeof n?{callback:n}:n),u=a.fbqObjName,i=window[u],r=window.console&&a.debug?function(){var e=[].slice.call(arguments);e.unshift("["+a.debugLogPrefix+"]"),console.log.apply(console,e)}:function(){},l=function(o){var e,n,t={args:o,the:{}},u=t.the;"object"==typeof o[o.length-1]&&o[o.length-1];for(a.debug&&function(e,n){for(e="Intercepted: fbq(",n=0;n<o.length;n++)e+="string"==typeof o[n]?'"'+o[n]+'"':o[n],n+1<o.length&&(e+=", ");r(e+=")")}(),u.command=o[0],"track"!==u.command&&"trackCustom"!==u.command||(u.eventName=o[0]),u.parameters={},e=0;e<o.length;e++)if(o[e]&&"object"==typeof o[e])for(n in o[e])o[e].hasOwnProperty(n)&&(u.parameters[n]=o[e][n]);return r("Run listener callback",u),!1!==a.callback(t)},c=function(){var e=[].slice.call(arguments);if(a.debug){if(!l(e))return r("Command blocked.")}else try{if(!l(e))return}catch(e){}return r("Command allowed:",e),c._fbqOrig.apply(c._fbqOrig,e)},f="callMethod";if(r("Config:",a),i||(r("Instantiating FB command queue"),((i=window[u]=window._fbq=function(){i[f]?i[f].apply(i,arguments):i.queue.push(arguments)}).push=i).loaded=!0,i.version="2.0",i.queue=[]),i[f])r("Loaded after fbevents.js; cannot see previous commands"),e();else if(i.queue){if(r("Command queue instantiated, but library not yet loaded"),i.queue.length){for(r("Applying listener to",i.queue.length," queued commands"),o=[],t=0;t<i.queue.length;t++)l([].slice.call(i.queue[t]))&&o.push(i.queue[t]);i.queue=o}else i.queue=[];e()}else if(a.debug)throw new Error("["+a.debugLogPrefix+"] Aborting; `"+u+"` is not the FB command queue.")};
(function(){
var //globalNamespace = '_fbqSpyData',
//cache = window[globalNamespace] = window[globalNamespace] || {},
//dL = {get:function(k){return cache[k]},set:function(k,v){cache[k]=v}},
dL = google_tag_manager[{{Container ID}}].dataLayer,
dLKey_counter = 'fw.fb.counter',
eventId = {{Facebook Event ID}};
fbqSpy( function(data){
if( 'track' !== data.the.command && 'trackCustom' !== data.the.command ) return;
data.args.push({eventID:eventId});
dL.set( dLKey_counter, (dL.get(dLKey_counter)||0)+1 );
});
})()
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment