Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(modal-checkout): handle auth modal analytics #1908

Merged
merged 7 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion includes/class-modal-checkout.php
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,8 @@ public static function dequeue_scripts() {
}

$allowed_assets = [
// WP.
'jquery',
'google_gtagjs',
// Newspack.
'newspack-newsletters-',
'newspack-blocks-modal',
Expand Down
8 changes: 6 additions & 2 deletions src/modal-checkout/analytics/ga4/dismissed.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import { getEventPayload, getProductDetails, sendEvent } from './utils';

/**
* Event fired when a checkout modal is dismissed (not when closed automatically due to a completed checkout).
*
* @param {Object} data The data to send with the event.
*/
export const manageDismissed = () => {
export const manageDismissed = ( data ) => {
if ( 'function' !== typeof window.gtag ) {
return;
}

const { action_type, amount = '', currency, price = '', product_id, product_type, recurrence, referrer, variation_id = '' } = getProductDetails( 'newspack_modal_checkout' );
data = data || getProductDetails( 'newspack_modal_checkout' );

const { action_type, amount = '', currency, price = '', product_id, product_type, recurrence, referrer, variation_id = '' } = data;

const params = {
action_type,
Expand Down
6 changes: 3 additions & 3 deletions src/modal-checkout/analytics/ga4/opened.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { getEventPayload, sendEvent } from './utils';
/**
* Execute a callback function to send a GA event when a prompt is dismissed.
*
* @param {Object} getProductDataModal Information about the purchase being made.
* @param {Object} data Information about the purchase being made.
*/
export const manageOpened = ( getProductDataModal = '' ) => {
export const manageOpened = ( data ) => {
if ( 'function' !== typeof window.gtag ) {
return;
}
Expand All @@ -23,7 +23,7 @@ export const manageOpened = ( getProductDataModal = '' ) => {
recurrence,
referrer,
variation_id = '',
} = getProductDataModal;
} = data;

const params = {
action_type,
Expand Down
52 changes: 39 additions & 13 deletions src/modal-checkout/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ const MODAL_CHECKOUT_ID = 'newspack_modal_checkout';
const MODAL_CLASS_PREFIX = `${ CLASS_PREFIX }__modal`;
const VARIATON_MODAL_CLASS_PREFIX = 'newspack-blocks__modal-variation';

let getProductDataModal = {};
// Track the checkout state for analytics.
let analyticsData = {};
// Track the checkout intent to avoid multiple analytics events.
let inCheckoutIntent = false;

domReady( () => {
const modalCheckout = document.querySelector( `#${ MODAL_CHECKOUT_ID }` );
Expand Down Expand Up @@ -228,14 +231,20 @@ domReady( () => {
a11y.trapFocus( variationModal, false );

// Set up some GA4 information.
const getDataProduct = form.getAttribute( 'data-product' );
getProductDataModal = getDataProduct ? JSON.parse( getDataProduct ) : {};
manageOpened( getProductDataModal );
const formAnalyticsData = form.getAttribute( 'data-product' );
analyticsData = formAnalyticsData ? JSON.parse( formAnalyticsData ) : {};

// For the variation modal we will not set `inCheckoutIntent = true` and
// let the `opened` event get triggered once the user selects a
// variation so we track the selection.
if ( ! inCheckoutIntent ) {
manageOpened( analyticsData );
}

// Append product data info to the modal itself, so we can grab it for manageDismissed:
document
.getElementById( 'newspack_modal_checkout' )
.setAttribute( 'data-order-details', JSON.stringify( getProductDataModal ) );
.setAttribute( 'data-order-details', JSON.stringify( analyticsData ) );
return;
}
}
Expand All @@ -247,8 +256,8 @@ domReady( () => {

// Set up some GA4 information.
if ( isCheckoutButtonBlock ) { // this fires on the second in-modal variations screen, too
const getDataProduct = form.getAttribute( 'data-product' );
getProductDataModal = getDataProduct ? JSON.parse( getDataProduct ) : {};
const formAnalyticsData = form.getAttribute( 'data-product' );
analyticsData = formAnalyticsData ? JSON.parse( formAnalyticsData ) : {};
} else if ( isDonateBlock ) {
// Get donation information and append to the modal checkout for GA4:
const donationFreq = formData.get( 'donation_frequency' );
Expand All @@ -275,7 +284,7 @@ domReady( () => {
}

// Get product information together to be appended to the modal for GA4 events outside of the iframe.
getProductDataModal = {
analyticsData = {
amount: donationValue,
action_type: 'donation',
currency: formData.get( 'donation_currency' ),
Expand All @@ -286,6 +295,12 @@ domReady( () => {
};
}

// Analytics.
if ( ! inCheckoutIntent ) {
manageOpened( analyticsData );
}
inCheckoutIntent = true;

if (
typeof newspack_ras_config !== 'undefined' &&
! newspack_ras_config?.is_logged_in &&
Expand Down Expand Up @@ -373,7 +388,7 @@ domReady( () => {
// Initialize auth flow if reader is not authenticated.
window.newspackReaderActivation.openAuthModal( {
title: newspackBlocksModal.labels.auth_modal_title,
callback: ( message, authData ) => {
onSuccess: ( message, authData ) => {
cartReq.then( url => {
// If registered, append the registration flag query param to the url.
if ( authData?.registered ) {
Expand All @@ -387,6 +402,15 @@ domReady( () => {
closeCheckout();
} );
},
onError: () => {
closeCheckout();
},
onDismiss: () => {
// Analytics: Track a dismissal event (modal has been manually closed without completing the checkout).
manageDismissed( analyticsData );
inCheckoutIntent = false;
document.getElementById( 'newspack_modal_checkout' ).removeAttribute( 'data-order-details' );
},
skipSuccess: true,
skipNewslettersSignup: true,
labels: {
Expand All @@ -403,11 +427,10 @@ domReady( () => {
} else {
// Otherwise initialize checkout.
openCheckout();
manageOpened( getProductDataModal );
// Append product data info to the modal, so we can grab it for GA4 events outside of the iframe.
document
.getElementById( 'newspack_modal_checkout' )
.setAttribute( 'data-order-details', JSON.stringify( getProductDataModal ) );
.setAttribute( 'data-order-details', JSON.stringify( analyticsData ) );
}
};

Expand Down Expand Up @@ -499,11 +522,13 @@ domReady( () => {
}
}
window?.newspackReaderActivation?.setPendingCheckout?.();
inCheckoutIntent = false;
};

if ( window?.newspackReaderActivation?.openNewslettersSignupModal ) {
window.newspackReaderActivation.openNewslettersSignupModal( {
callback: handleCheckoutComplete,
onSuccess: handleCheckoutComplete,
onError: handleCheckoutComplete,
closeOnSuccess: shouldCloseModal,
} );
} else {
Expand All @@ -518,8 +543,9 @@ domReady( () => {
} else {
window?.newspackReaderActivation?.setPendingCheckout?.();

// Track a dismissal event (modal has been manually closed without completing the checkout).
// Analytics: Track a dismissal event (modal has been manually closed without completing the checkout).
manageDismissed();
inCheckoutIntent = false;
document.getElementById( 'newspack_modal_checkout' ).removeAttribute( 'data-order-details' );
}
};
Expand Down