diff --git a/src/constants/cookie-names.js b/src/constants/cookie-names.js index 2756a8eb7..c52debc2a 100644 --- a/src/constants/cookie-names.js +++ b/src/constants/cookie-names.js @@ -1,5 +1,10 @@ const cookieNames = { FUNNEL_SESSION_INFO: "FunnelSessionInfo", + + // Existing Safelite.com cookies + DXDEV: "dxdev", + SESSION_ID: "sid", + SESSION_KEY: "skey" }; export { cookieNames }; diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 2aa1fe226..2325c29cd 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -63,6 +63,10 @@ const endpoints = { url: "/location/api/v1/location/zip", method: "GET", }, + LogExperimentExposureIfAssigned:{ + url: "/analytics/api/v1/analytics/log-experiment-exposure", + method: "POST", + } }; export { endpoints }; diff --git a/src/constants/experiments.js b/src/constants/experiments.js new file mode 100644 index 000000000..13a51aa7f --- /dev/null +++ b/src/constants/experiments.js @@ -0,0 +1,6 @@ +const experimentUniverses = { + CONCEPT_FUNNEL: 'ConceptFunnel' +}; + +export { experimentUniverses }; + \ No newline at end of file diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index 36516a570..1dfa6af4d 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -24,13 +24,13 @@ export function updateOrCreateFunnelCookie() { /* Gets the current instance of the funnel cookie. Returns null if cookie isn't valid JSON. -*/ +*/ export function getFunnelCookie() { const cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.FUNNEL_SESSION_INFO}=`)) ?.split("=")[1]; - + try { return JSON.parse(cookieJson); } catch (error) { @@ -45,6 +45,61 @@ export function deleteFunnelCookie() { document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=; Max-Age=0; path=${applicationConfig.COOKIE_PATH}; ${getCookieDomainValue()}`; } +/* + Gets cookie domain value. Localhost will be empty "". +*/ +export function getCookieDomainValue() { + return location.hostname.includes("localhost") ? "" : `domain=${getDomainWithoutSubdomain()};`; +} + +/* + Gets value of dxdev cookie, and then extracts "did" value from it. + Returns empty string if cookie not found or "did" string not present. +*/ +export function getDeviceIdValue(){ + const cookieValue = getCookieByName(cookieNames.DXDEV); + const cookieValueMatch = cookieValue.match("(?<=did=).*?(?=&)"); + + if(cookieValueMatch){ + return cookieValueMatch[0]; + } + + return ''; +} + +/* + Gets value of sid cookie, returns empty string if not found. +*/ +export function getSessionIdValue(){ + const cookieValue = getCookieByName(cookieNames.SESSION_ID); + + if(cookieValue){ + return cookieValue; + } + + return ''; +} + +/* + Gets value of skey cookie, returns empty string if not found. +*/ +export function getSessionKeyValue(){ + const cookieValue = getCookieByName(cookieNames.SESSION_KEY); + + if(cookieValue){ + return cookieValue; + } + + return ''; +} + +/* +=========================== += PRIVATE FUNCTIONS = +=========================== +*/ + + /* Used to set properties on the funnel cookie. Takes an object with properties to set. Will overwrite existing properties. @@ -65,10 +120,9 @@ function setFunnelCookieProperties(properties) { } } -export function getCookieDomainValue() { - return location.hostname.includes("localhost") ? "" : `domain=${getDomainWithoutSubdomain()};`; -} - +/* + Gets current domain without the subdomain for cookie. +*/ function getDomainWithoutSubdomain() { let url = location.hostname; if (url.includes("localhost")) { @@ -82,3 +136,16 @@ function getDomainWithoutSubdomain() { .slice(-(urlParts.length === 4 ? 3 : 2)) .join('.')}`; } + +/* + Gets cookie value by name, returns empty string if not found. +*/ +function getCookieByName(name) { + const value = "; " + document.cookie; + const parts = value.split("; " + name + "="); + + if (parts.length === 2) { + return parts.pop().split(";").shift(); + } + return ""; +} \ No newline at end of file diff --git a/src/layouts/vehicle-year/vehicle-year.vue b/src/layouts/vehicle-year/vehicle-year.vue index c04b5bd9d..85faa0d61 100644 --- a/src/layouts/vehicle-year/vehicle-year.vue +++ b/src/layouts/vehicle-year/vehicle-year.vue @@ -17,11 +17,16 @@ import yearQuestion from "@/layouts/vehicle-year/year-question/year-question"; import funnelHeader from "@/common-components/funnel-header/funnel-header"; import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner"; import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; + // Supporting files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; import { storeMutations } from "@/constants/store-mutations"; import { storeActions } from "@/constants/store-actions"; +import { experimentUniverses } from "@/constants/experiments"; +import { getDeviceIdValue, getSessionIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper"; + +import baseMixin from "@/mixins/base-mixin"; import store from "@/store"; export default { @@ -38,6 +43,18 @@ export default { const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); const yearQuestionInitialDataPromise = yearQuestion.methods.loadInitialData(); + // Log experiment exposure + const logExperimentExposurePromise = baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOG_EXPERIMENT_EXPOSURE, + { + userId: getDeviceIdValue(), + sessionKey: getSessionKeyValue(), + sessionId: getSessionIdValue(), + pageName: to.query.fmgPage, + serverName: 'ConceptFunnel', + pageEvent: { action: '', event: 'ENTRY' }, + universeName: experimentUniverses.CONCEPT_FUNNEL + }, false); + // Settle promises and get results const promiseResultMap = [ { @@ -48,6 +65,10 @@ export default { resultKey: "yearQuestionInitialData", promise: yearQuestionInitialDataPromise, }, + { + resultKey: "logExperimentExposure", + promise: logExperimentExposurePromise, + }, ]; let resultMap = await settleAllPromises(promiseResultMap); diff --git a/src/store/index.js b/src/store/index.js index fb9c6f525..d7f00dca3 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -364,7 +364,19 @@ export const actions = { }, logExperimentExposure(context, {userId, sessionKey, sessionId, pageName, serverName, pageEvent, universeName }){ - + return globalMethods.callHttpClient({ + method: endpoints.LogExperimentExposureIfAssigned.method, + endpoint: endpoints.LogExperimentExposureIfAssigned.url, + payload: { + userId: userId, + sessionKey: sessionKey, + sessionId: sessionId, + pageName: pageName, + serverName: serverName, + pageEvent: pageEvent, + universeName: universeName + } + }) }, // Parts API Actions