Skip to content

Commit 0f2374e

Browse files
authored
Merge pull request #23 from klaviyo/feature/mews-email-phone-reidentify
Add email/phone re-identification for Mews
2 parents 0d0bb0f + 266aed9 commit 0f2374e

File tree

3 files changed

+122
-30
lines changed

3 files changed

+122
-30
lines changed

public/klaviyo_hotel_tracking_mews.js

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,15 @@
221221
debugLog("Error tracking Started Checkout:", err);
222222
});
223223
}
224-
function attemptIdentify(source) {
224+
function attemptIdentify(source, allowReIdentify = false) {
225225
if (source) {
226226
debugLog("attemptIdentify called from:", source);
227227
}
228+
if (allowReIdentify) {
229+
debugLog("Re-identification allowed, proceeding");
230+
performIdentification(source, true);
231+
return;
232+
}
228233
if (klaviyo.isIdentified && typeof klaviyo.isIdentified === "function") {
229234
klaviyo.isIdentified().then(function(isIdentified) {
230235
debugLog("klaviyo.isIdentified():", isIdentified);
@@ -244,7 +249,7 @@
244249
performIdentification(source);
245250
}
246251
}
247-
function performIdentification(source) {
252+
function performIdentification(source, forceReIdentify = false) {
248253
const iframe = document.querySelector("iframe.mews-distributor") || document.querySelector('iframe[name*="mews-distributor"]');
249254
let searchDoc = document;
250255
if (iframe) {
@@ -287,7 +292,8 @@
287292
if (!hasValidPhone && phone) {
288293
debugLog("Phone invalid or incomplete:", phone);
289294
}
290-
if ((hasValidEmail || hasValidPhone) && !identifyAttempted) {
295+
const shouldIdentify = (hasValidEmail || hasValidPhone) && (!identifyAttempted || forceReIdentify);
296+
if (shouldIdentify) {
291297
const identifyData = {};
292298
if (hasValidEmail) {
293299
identifyData["email"] = email;
@@ -304,12 +310,20 @@
304310
if (lastNameField && lastNameField.value.trim()) {
305311
identifyData["last_name"] = lastNameField.value.trim();
306312
}
307-
debugLog("Identifying user with:", identifyData);
313+
if (forceReIdentify) {
314+
debugLog("Re-identifying user with:", identifyData);
315+
} else {
316+
debugLog("Identifying user with:", identifyData);
317+
}
308318
klaviyo.identify(identifyData);
309-
identifyAttempted = true;
310-
debugLog("Identification complete - no further attempts will be made");
319+
if (!forceReIdentify) {
320+
identifyAttempted = true;
321+
debugLog("Identification complete");
322+
} else {
323+
debugLog("Re-identification complete");
324+
}
311325
}
312-
} else if (identifyAttempted) {
326+
} else if (identifyAttempted && !forceReIdentify) {
313327
debugLog("User already identified in this session, skipping");
314328
} else {
315329
debugLog("No valid email or phone found yet, will retry");
@@ -447,16 +461,34 @@
447461
for (let i = 0; i < allInputs.length; i++) {
448462
(function(input) {
449463
input.addEventListener("blur", function() {
450-
debugLog("Form field blur:", input.name || input.type);
451-
setTimeout(function() {
452-
attemptIdentify("field blur: " + (input.name || input.type));
453-
}, 500);
464+
const fieldName = input.name || input.type;
465+
debugLog("Form field blur:", fieldName);
466+
const isEmailField = input.type === "email" || input.name === "email" || input.id === "email" || input.getAttribute("data-test-id") === "checkout-field-email" || input.getAttribute("autocomplete") === "email";
467+
const isPhoneField = input.type === "tel" || input.name === "phone" || input.name === "phoneNumber" || input.id === "phone" || input.getAttribute("data-test-id") === "checkout-field-phone" || input.getAttribute("autocomplete") === "tel";
468+
if (isEmailField) {
469+
debugLog("Email field detected, attempting re-identification");
470+
setTimeout(function() {
471+
attemptIdentify("email blur", true);
472+
}, 500);
473+
} else if (isPhoneField) {
474+
debugLog("Phone field detected, attempting re-identification");
475+
setTimeout(function() {
476+
attemptIdentify("phone blur", true);
477+
}, 500);
478+
} else {
479+
debugLog("Ignoring blur on non-email/phone field:", fieldName);
480+
}
454481
});
455482
input.addEventListener("change", function() {
456-
debugLog("Form field changed:", input.name || input.type);
457-
setTimeout(function() {
458-
attemptIdentify("field change: " + (input.name || input.type));
459-
}, 500);
483+
const fieldName = input.name || input.type;
484+
const isEmailField = input.type === "email" || input.name === "email" || input.id === "email" || input.getAttribute("data-test-id") === "checkout-field-email" || input.getAttribute("autocomplete") === "email";
485+
const isPhoneField = input.type === "tel" || input.name === "phone" || input.name === "phoneNumber" || input.id === "phone" || input.getAttribute("data-test-id") === "checkout-field-phone" || input.getAttribute("autocomplete") === "tel";
486+
if (isEmailField || isPhoneField) {
487+
debugLog("Form field changed:", fieldName);
488+
setTimeout(function() {
489+
attemptIdentify("field change: " + fieldName, true);
490+
}, 500);
491+
}
460492
});
461493
})(allInputs[i]);
462494
}

src/mews/generalUtils.js

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,57 @@ function attachFormListeners(guestForm) {
139139
for (let i = 0; i < allInputs.length; i++) {
140140
(function(input) {
141141
input.addEventListener('blur', function() {
142-
debugLog('Form field blur:', input.name || input.type);
143-
// Check for email/phone whenever any field loses focus
144-
setTimeout(function() { attemptIdentify('field blur: ' + (input.name || input.type)); }, 500);
142+
const fieldName = input.name || input.type;
143+
debugLog('Form field blur:', fieldName);
144+
145+
// Check if this is an email field
146+
const isEmailField = input.type === 'email' ||
147+
input.name === 'email' ||
148+
input.id === 'email' ||
149+
input.getAttribute('data-test-id') === 'checkout-field-email' ||
150+
input.getAttribute('autocomplete') === 'email';
151+
152+
// Check if this is a phone field
153+
const isPhoneField = input.type === 'tel' ||
154+
input.name === 'phone' ||
155+
input.name === 'phoneNumber' ||
156+
input.id === 'phone' ||
157+
input.getAttribute('data-test-id') === 'checkout-field-phone' ||
158+
input.getAttribute('autocomplete') === 'tel';
159+
160+
// Only identify/re-identify on email or phone blur
161+
if (isEmailField) {
162+
debugLog('Email field detected, attempting re-identification');
163+
setTimeout(function() { attemptIdentify('email blur', true); }, 500);
164+
} else if (isPhoneField) {
165+
debugLog('Phone field detected, attempting re-identification');
166+
setTimeout(function() { attemptIdentify('phone blur', true); }, 500);
167+
} else {
168+
debugLog('Ignoring blur on non-email/phone field:', fieldName);
169+
}
145170
});
146171

147-
// Also add change listener
172+
// Also add change listener for email/phone fields only
148173
input.addEventListener('change', function() {
149-
debugLog('Form field changed:', input.name || input.type);
150-
setTimeout(function() { attemptIdentify('field change: ' + (input.name || input.type)); }, 500);
174+
const fieldName = input.name || input.type;
175+
176+
const isEmailField = input.type === 'email' ||
177+
input.name === 'email' ||
178+
input.id === 'email' ||
179+
input.getAttribute('data-test-id') === 'checkout-field-email' ||
180+
input.getAttribute('autocomplete') === 'email';
181+
182+
const isPhoneField = input.type === 'tel' ||
183+
input.name === 'phone' ||
184+
input.name === 'phoneNumber' ||
185+
input.id === 'phone' ||
186+
input.getAttribute('data-test-id') === 'checkout-field-phone' ||
187+
input.getAttribute('autocomplete') === 'tel';
188+
189+
if (isEmailField || isPhoneField) {
190+
debugLog('Form field changed:', fieldName);
191+
setTimeout(function() { attemptIdentify('field change: ' + fieldName, true); }, 500);
192+
}
151193
});
152194
})(allInputs[i]);
153195
}

src/mews/klaviyoUtils.js

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -267,12 +267,19 @@ export function trackStartedCheckout(items, ecommerceData) {
267267
});
268268
}
269269
// User identification functions
270-
export function attemptIdentify(source) {
270+
export function attemptIdentify(source, allowReIdentify = false) {
271271

272272
if (source) {
273273
debugLog('attemptIdentify called from:', source);
274274
}
275275

276+
// If allowReIdentify is true (email/phone blur), skip the isIdentified check
277+
if (allowReIdentify) {
278+
debugLog('Re-identification allowed, proceeding');
279+
performIdentification(source, true);
280+
return;
281+
}
282+
276283
// Check if user is already identified
277284
if (klaviyo.isIdentified && typeof klaviyo.isIdentified === 'function') {
278285
klaviyo.isIdentified().then(function(isIdentified) {
@@ -297,7 +304,7 @@ export function attemptIdentify(source) {
297304
}
298305
}
299306

300-
export function performIdentification(source) {
307+
export function performIdentification(source, forceReIdentify = false) {
301308

302309
// Find the Mews iframe and get its document
303310
const iframe = document.querySelector('iframe.mews-distributor') ||
@@ -356,8 +363,10 @@ export function performIdentification(source) {
356363
debugLog('Phone invalid or incomplete:', phone);
357364
}
358365

359-
// Only identify if we have valid email or phone
360-
if ((hasValidEmail || hasValidPhone) && !identifyAttempted) {
366+
// Check if we should proceed with identification
367+
const shouldIdentify = (hasValidEmail || hasValidPhone) && (!identifyAttempted || forceReIdentify);
368+
369+
if (shouldIdentify) {
361370
const identifyData = {};
362371

363372
if (hasValidEmail) {
@@ -387,14 +396,23 @@ export function performIdentification(source) {
387396
identifyData['last_name'] = lastNameField.value.trim();
388397
}
389398

390-
debugLog('Identifying user with:', identifyData);
399+
if (forceReIdentify) {
400+
debugLog('Re-identifying user with:', identifyData);
401+
} else {
402+
debugLog('Identifying user with:', identifyData);
403+
}
404+
391405
klaviyo.identify(identifyData);
392406

393-
// Mark as attempted - never try again
394-
identifyAttempted = true;
395-
debugLog('Identification complete - no further attempts will be made');
407+
// Mark as attempted (unless this is a re-identify for email/phone only)
408+
if (!forceReIdentify) {
409+
identifyAttempted = true;
410+
debugLog('Identification complete');
411+
} else {
412+
debugLog('Re-identification complete');
413+
}
396414
}
397-
} else if (identifyAttempted) {
415+
} else if (identifyAttempted && !forceReIdentify) {
398416
debugLog('User already identified in this session, skipping');
399417
} else {
400418
debugLog('No valid email or phone found yet, will retry');

0 commit comments

Comments
 (0)