Skip to content
(function() {
'use strict';
// Initialize dataLayer if it doesn't exist
window.dataLayer = window.dataLayer || [];
// Function to push form submit event to dataLayer
function pushFormSubmitEvent() {
window.dataLayer.push({
'event': 'form_submit',
'form_type': 'microsoft_booking',
'form_location': 'consultation_booking',
'form_id': 'booking_iframe',
'timestamp': new Date().toISOString()
});
console.log('Microsoft Booking Form Submit Event Pushed to GTM');
}
// Method 1: Listen for postMessage from Microsoft Booking iframe
function setupPostMessageListener() {
window.addEventListener('message', function(event) {
// Check if message is from Microsoft Booking system
if (event.origin.includes('outlook.office365.com') ||
event.origin.includes('bookings.office.com') ||
event.origin.includes('office365.com')) {
console.log('Message received from booking system:', event.data);
// Look for booking completion/submission indicators
if (event.data) {
// Check for various success indicators
const data = typeof event.data === 'string' ? event.data.toLowerCase() : event.data;
if (typeof data === 'string') {
if (data.includes('booking') && (data.includes('success') || data.includes('complete') || data.includes('confirm'))) {
pushFormSubmitEvent();
}
} else if (typeof data === 'object') {
if (data.type === 'booking_completed' ||
data.action === 'submit' ||
data.status === 'success' ||
data.event === 'booking_success' ||
data.messageType === 'booking_confirmed') {
pushFormSubmitEvent();
}
}
}
}
});
}
// Method 2: Monitor iframe URL changes (if accessible)
function monitorIframeChanges() {
const iframe = document.querySelector('iframe[src*="outlook.office365.com/book"]');
if (iframe) {
// Try to monitor iframe for navigation changes
let lastUrl = '';
const checkIframeUrl = function() {
try {
// This will fail due to CORS, but we can still detect some changes
const currentUrl = iframe.contentWindow.location.href;
if (currentUrl !== lastUrl) {
lastUrl = currentUrl;
// Check if URL indicates booking completion
if (currentUrl.includes('success') ||
currentUrl.includes('complete') ||
currentUrl.includes('confirmation')) {
pushFormSubmitEvent();
}
}
} catch (e) {
// Expected to fail due to CORS, but iframe load events might still work
}
};
// Monitor iframe load events
iframe.addEventListener('load', function() {
console.log('Booking iframe loaded/navigated');
setTimeout(checkIframeUrl, 1000);
});
// Periodic check (as backup)
setInterval(checkIframeUrl, 2000);
}
}
// Method 3: Monitor iframe height changes (booking systems often resize after submission)
function monitorIframeResize() {
const iframe = document.querySelector('iframe[src*="outlook.office365.com/book"]');
if (iframe) {
let initialHeight = iframe.offsetHeight;
let hasResized = false;
const observer = new ResizeObserver(function(entries) {
for (let entry of entries) {
const newHeight = entry.contentRect.height;
// If iframe significantly changes height after initial load, might indicate form submission
if (Math.abs(newHeight - initialHeight) > 100 && !hasResized) {
hasResized = true;
console.log('Booking iframe resized significantly - possible form submission');
// Wait a bit more to see if it's a submission confirmation
setTimeout(function() {
pushFormSubmitEvent();
}, 2000);
}
}
});
// Start observing after iframe loads
iframe.addEventListener('load', function() {
setTimeout(function() {
initialHeight = iframe.offsetHeight;
observer.observe(iframe);
}, 1000);
});
}
}
// Method 4: Enhanced interaction monitoring with focus detection
function monitorUserInteraction() {
const iframe = document.querySelector('iframe[src*="outlook.office365.com/book"]');
if (iframe) {
let interactionStartTime = null;
let hasInteracted = false;
let focusTimeout = null;
// Detect when user starts interacting with iframe
iframe.addEventListener('mouseenter', function() {
if (!interactionStartTime) {
interactionStartTime = Date.now();
console.log('User started interacting with booking form');
}
});
// Detect when iframe gains focus (user clicked inside)
window.addEventListener('blur', function() {
// Window lost focus, possibly because iframe gained focus
if (interactionStartTime && !hasInteracted) {
hasInteracted = true;
console.log('User likely clicked inside booking iframe');
// Set up a longer timeout for form submission detection
focusTimeout = setTimeout(function() {
// Check if user is still interacting (form submission likely occurred)
const interactionDuration = Date.now() - interactionStartTime;
if (interactionDuration > 30000) { // 30 seconds of interaction
console.log('Long interaction detected - likely form submission');
pushFormSubmitEvent();
}
}, 45000); // Wait 45 seconds
}
});
// Cancel timeout if window regains focus quickly (user didn't submit)
window.addEventListener('focus', function() {
if (focusTimeout && (Date.now() - interactionStartTime) < 10000) {
clearTimeout(focusTimeout);
console.log('Quick focus return - probably not a form submission');
}
});
}
}
// Method 5: Network activity monitoring (experimental)
function monitorNetworkActivity() {
// Monitor fetch/XHR requests that might indicate form submission
const originalFetch = window.fetch;
const originalXHR = window.XMLHttpRequest.prototype.open;
// Intercept fetch requests
window.fetch = function(...args) {
const url = args[0];
if (typeof url === 'string' &&
(url.includes('outlook.office365.com') || url.includes('bookings.office.com'))) {
console.log('Booking-related network request detected:', url);
// If it's a POST request to booking endpoints, likely a form submission
if (args[1] && args[1].method === 'POST') {
setTimeout(function() {
pushFormSubmitEvent();
}, 1000);
}
}
return originalFetch.apply(this, args);
};
}
// Initialize all tracking methods
function initializeTracking() {
console.log('Initializing Microsoft Booking iframe tracking...');
setupPostMessageListener();
monitorIframeChanges();
monitorIframeResize();
monitorUserInteraction();
monitorNetworkActivity();
console.log('Microsoft Booking tracking initialized');
}
// Wait for iframe to be available
function waitForIframe() {
const iframe = document.querySelector('iframe[src*="outlook.office365.com/book"]');
if (iframe) {
initializeTracking();
} else {
setTimeout(waitForIframe, 1000);
}
}
// Start tracking when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', waitForIframe);
} else {
waitForIframe();
}
})();