Facebook Ads Manager Destination

MorphL makes it easy to send predictions to Facebook Ads Manager.

A common use case is creating custom audiences (ex. website visitors who are likely to add a product to the shopping cart), to be used in remarketing ads.

This tutorial uses the Facebook Business Manager panel to create a custom audience for Facebook Ads Manager.

Prerequisites

Google Analytics or Google Analytics 360 data source

The Facebook Ads destination requires that your ML models use the Google Analytics or Google Analytics 360 data source.

Facebook Pixel

Facebook Pixel collects data that helps you track conversions from Facebook ads, optimize ads, build targeted audiences for future ads and remarket to people who have already taken some kind of action on your website. See the Create and Install a Facebook Pixel doc for instructions.

(Recommended) Google Tag Manager

We recommend using Google Tag Manager for easier deployment of custom scripts.

Sending predictions to Facebook Ads

Once predictions are available through the MorphL API, they can be consumed in Facebook or Google Ads through custom audiences.

Generate authentication token

With the API key and API secret created in the MorphL Dashboard, call the /authorize endpoint to generate an access token.

As a requirement for protecting the API credentials, the authentication request must be implemented in the backend.

Create script for retrieving predictions

The predictions are retrieved from the MorphL API by sending the client id as a parameter. The client id is retrieved from the _ga cookie, which is set by the Google Analytics tracking script.

Please see below a script that calls the MorphL API to retrieve predictions for the Shopping Stage Completeness ML model and processes the response:

function MorphlPredictions() {
    var JSObject = this;

    this.apiUrl =
        "https://service.morphlapis.com/predictions/<account>/shopping_stage/get";
    this.accessToken = "<jwt_token>";
    this.facebookPixel = "<facebook_pixel_id>";
    this.cookieName = "morphl_shoppingstage";

    /**
    * Initialize API call
    */
    this.init = function() {
        // Check if we already have a prediction in the browser cookie
        var predictedShoppingStage = JSObject.getCookie(
            JSObject.cookieName
        );
        if (predictedShoppingStage !== "") {
            return;
        }

        // Make call to get prediction from the API
        JSObject.getAPIPrediction();
    };

    /**
    * Get a browser cookie
    *
    * @param  string cname = The cookie name
    * @return  string = The cookie value or an empty string ("") if the cookie doesn't exist
    */
    this.getCookie = function(cname) {
        var name = cname + "=";
        var decodedCookie = decodeURIComponent(document.cookie);
        var ca = decodedCookie.split(";");
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == " ") {
                c = c.substring(1);
            }
            if (c.indexOf(name) == 0) {
                return c.substring(name.length, c.length);
            }
        }
        return "";
    };

    /**
    * Set a browser cookie
    *
    * @param  string cname = The cookie name
    * @param  string cvalue = The cookie value
    * @param  string exhours = The expiration interval, in hours
    */
    this.setCookie = function(cname, cvalue, exhours) {
        var d = new Date();
        d.setTime(d.getTime() + Number(exhours) * 60 * 60 * 1000);
        var expires = "expires=" + d.toUTCString();
        document.cookie =
            cname +
            "=" +
            encodeURIComponent(cvalue) +
            ";" +
            expires +
            ";path=/; secure";
    };

    /**
    * Get the client id from the Google Analytics cookie.
    */
    this.getGoogleAnalyticsClientId = function() {
        var gaCookie = JSObject.getCookie("_ga");

        if (gaCookie === "") {
            return null;
        }

        // Parse the _ga cookie value to the right format.
        var lastElements = gaCookie.split(".").slice(-2);

        if (lastElements.length == 2) {
            return 'GA' + lastElements.join(".");
        }

        return null;
    };
    
    /**
    * Interogate Morphl API and get the value of the prediction for the client ID.
    */
    this.getAPIPrediction = function() {
        // Set up our HTTP request
        var xhr = new XMLHttpRequest();

        // Setup our listener to process completed requests
        xhr.onload = function() {
            // Set a default value for the shopping stage
            var shoppingStage = "n/a";

            // Process response data
            if (xhr.status == 200 || xhr.status == 404) {
                // This will run when the request is successful
                var morphlRes = JSON.parse(xhr.response);

                // Validate the response received from the API
                // Check if the client id has a valid prediction
                if (
                    morphlRes &&
                    morphlRes.status &&
                    Number(morphlRes.status) == 1 &&
                    typeof morphlRes.shopping_stage === "number"
                ) {
                    // Get the shopping stage with the highest probability
                    var nextShoppingStage = Number(
                        morphlRes.shopping_stage
                    );

                    shoppingStage =
                        nextShoppingStage >= 0.5
                            ? "add_to_cart"
                            : "all_visits";
                }

                // Set a cookie with the Morphl prediction value
                JSObject.setCookie(JSObject.cookieName, shoppingStage, 2);

                // (Optionally)
                if (JSObject.facebookPixel !== "" && typeof fbq !== undefined) {
                    fbq("setUserProperties", JSObject.facebookPixel, {
                        morphl_prediction: shoppingStage
                    });
                }
            }
        };

        var clientId = JSObject.getGoogleAnalyticsClientId();

        if (clientId !== null) {

            // Create and send the GET request
            // The first argument is the post type (GET, POST, PUT, DELETE, etc.)
            // The second argument is the endpoint URL
            xhr.open(
                "GET",
                String(JSObject.apiUrl) +
                    "?client_id=" +
                    String(clientId)
            );
            xhr.setRequestHeader("Authorization", JSObject.accessToken);
            xhr.send();
        }
    };
}

var morphlPredictions = new MorphlPredictions();
morphlPredictions.init();

Overview

The anatomy of the sample script is as follows:

  • It assumes your activated ML models use Google Analytics or Google Analytics 360 as a data source. For more details, see the Google Analytics data source guide.
  • It doesn't include authentication and assumes that a valid access token was already generated. This token should be set in the accessToken property.
  • The prediction value is sent as a User Property to Facebook Pixel.
  • The prediction value is also saved in a cookie, identified by the cookieName property.

Parameters

The script parameters are:

  • <account> represents your unique account number, which can be retrieved from the MorphL Dashboard.
  • <jwt_token> is the JWT returned by the /authorize endpoint.
  • <facebook_pixel_id> is your Facebook Pixel ID.

Add script from GTM or website source

The script can be loaded in a website using Google Tag Manager or it can be added as a custom script directly in the source of your website. Follow this guide to include it from GTM.

Use Facebook Pixel to create a custom audience

  1. From your Facebook Business Manager, go to the Analytics section. From the Analytics Entity column, select your Facebook Pixel.

  2. From the Overview tab, create a new filter.
    Facebook Analytics - Create filter
  3. From the dropdown menu, select the have user property option.
    Facebook Analytics - Select filter option
  4. Scroll down and select your user property. Please note that the name of the property is set from the integration script created at Step 2.
    Facebook Analytics - Select property
  5. Add a condition for your filter. In this example, we are targeting users with a prediction value greater than 50% (0.5).
    Facebook Analytics - Set filter condition
  6. Click the arrow from the purple button and select the Create Custom Audience option. After saving the audience, it will become available for use in Facebook Ads Manager.
    Facebook Analytics - Set filter condition