@adobe/alloy 2.28.1 → 2.29.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libEs5/components/Advertising/configValidators.js +26 -0
- package/libEs5/components/Advertising/constants/index.js +78 -0
- package/libEs5/components/Advertising/createComponent.js +59 -0
- package/libEs5/components/Advertising/handlers/clickThroughHandler.js +81 -0
- package/libEs5/components/Advertising/handlers/createAdConversionHandler.js +55 -0
- package/libEs5/components/Advertising/handlers/onBeforeSendEventHandler.js +69 -0
- package/libEs5/components/Advertising/handlers/sendAdConversion.js +67 -0
- package/libEs5/components/Advertising/handlers/viewThroughHandler.js +56 -0
- package/libEs5/components/Advertising/identities/collectAllIdentities.js +34 -0
- package/libEs5/components/Advertising/identities/collectID5Id.js +112 -0
- package/libEs5/components/Advertising/identities/collectRampId.js +183 -0
- package/libEs5/components/Advertising/identities/collectSurferId.js +146 -0
- package/libEs5/components/Advertising/index.js +52 -0
- package/libEs5/components/Advertising/utils/advertisingCookieManager.js +80 -0
- package/libEs5/components/Advertising/utils/helpers.js +123 -0
- package/libEs5/components/DataCollector/validateUserEventOptions.js +5 -1
- package/libEs5/constants/consentStatus.js +5 -2
- package/libEs5/constants/libraryVersion.js +1 -1
- package/libEs5/core/componentCreators.js +8 -1
- package/libEs5/utils/dom/index.js +7 -0
- package/libEs5/utils/dom/loadScript.js +93 -0
- package/libEs6/components/Advertising/configValidators.js +24 -0
- package/libEs6/components/Advertising/constants/index.js +75 -0
- package/libEs6/components/Advertising/createComponent.js +56 -0
- package/libEs6/components/Advertising/handlers/clickThroughHandler.js +79 -0
- package/libEs6/components/Advertising/handlers/createAdConversionHandler.js +52 -0
- package/libEs6/components/Advertising/handlers/onBeforeSendEventHandler.js +66 -0
- package/libEs6/components/Advertising/handlers/sendAdConversion.js +65 -0
- package/libEs6/components/Advertising/handlers/viewThroughHandler.js +53 -0
- package/libEs6/components/Advertising/identities/collectAllIdentities.js +31 -0
- package/libEs6/components/Advertising/identities/collectID5Id.js +108 -0
- package/libEs6/components/Advertising/identities/collectRampId.js +179 -0
- package/libEs6/components/Advertising/identities/collectSurferId.js +143 -0
- package/libEs6/components/Advertising/index.js +49 -0
- package/libEs6/components/Advertising/utils/advertisingCookieManager.js +77 -0
- package/libEs6/components/Advertising/utils/helpers.js +113 -0
- package/libEs6/components/DataCollector/validateUserEventOptions.js +6 -2
- package/libEs6/constants/consentStatus.js +4 -1
- package/libEs6/constants/libraryVersion.js +1 -1
- package/libEs6/core/componentCreators.js +2 -1
- package/libEs6/utils/dom/index.js +1 -0
- package/libEs6/utils/dom/loadScript.js +90 -0
- package/package.json +2 -2
- package/types/components/Advertising/configValidators.d.ts +3 -0
- package/types/components/Advertising/configValidators.d.ts.map +1 -0
- package/types/components/Advertising/constants/index.d.ts +46 -0
- package/types/components/Advertising/constants/index.d.ts.map +1 -0
- package/types/components/Advertising/createComponent.d.ts +18 -0
- package/types/components/Advertising/createComponent.d.ts.map +1 -0
- package/types/components/Advertising/handlers/clickThroughHandler.d.ts +22 -0
- package/types/components/Advertising/handlers/clickThroughHandler.d.ts.map +1 -0
- package/types/components/Advertising/handlers/createAdConversionHandler.d.ts +13 -0
- package/types/components/Advertising/handlers/createAdConversionHandler.d.ts.map +1 -0
- package/types/components/Advertising/handlers/onBeforeSendEventHandler.d.ts +21 -0
- package/types/components/Advertising/handlers/onBeforeSendEventHandler.d.ts.map +1 -0
- package/types/components/Advertising/handlers/sendAdConversion.d.ts +10 -0
- package/types/components/Advertising/handlers/sendAdConversion.d.ts.map +1 -0
- package/types/components/Advertising/handlers/viewThroughHandler.d.ts +9 -0
- package/types/components/Advertising/handlers/viewThroughHandler.d.ts.map +1 -0
- package/types/components/Advertising/identities/collectAllIdentities.d.ts +7 -0
- package/types/components/Advertising/identities/collectAllIdentities.d.ts.map +1 -0
- package/types/components/Advertising/identities/collectID5Id.d.ts +3 -0
- package/types/components/Advertising/identities/collectID5Id.d.ts.map +1 -0
- package/types/components/Advertising/identities/collectRampId.d.ts +3 -0
- package/types/components/Advertising/identities/collectRampId.d.ts.map +1 -0
- package/types/components/Advertising/identities/collectSurferId.d.ts +3 -0
- package/types/components/Advertising/identities/collectSurferId.d.ts.map +1 -0
- package/types/components/Advertising/index.d.ts +23 -0
- package/types/components/Advertising/index.d.ts.map +1 -0
- package/types/components/Advertising/utils/advertisingCookieManager.d.ts +9 -0
- package/types/components/Advertising/utils/advertisingCookieManager.d.ts.map +1 -0
- package/types/components/Advertising/utils/helpers.d.ts +23 -0
- package/types/components/Advertising/utils/helpers.d.ts.map +1 -0
- package/types/components/DataCollector/validateUserEventOptions.d.ts.map +1 -1
- package/types/constants/consentStatus.d.ts +3 -0
- package/types/constants/consentStatus.d.ts.map +1 -1
- package/types/core/componentCreators.d.ts +1 -0
- package/types/utils/dom/index.d.ts +1 -0
- package/types/utils/dom/loadScript.d.ts +17 -0
- package/types/utils/dom/loadScript.d.ts.map +1 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.default = void 0;
|
|
4
|
+
var _createNode = require("./createNode.js");
|
|
5
|
+
var _appendNode = require("./appendNode.js");
|
|
6
|
+
/*
|
|
7
|
+
Copyright 2025 Adobe. All rights reserved.
|
|
8
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
10
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
|
|
12
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
13
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
14
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
15
|
+
governing permissions and limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
let nonce;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Returns the nonce if available.
|
|
22
|
+
* @param {Node} [context=document] defaults to document
|
|
23
|
+
* @returns {(String|undefined)} the nonce or undefined if not available
|
|
24
|
+
*/
|
|
25
|
+
const getNonce = (context = document) => {
|
|
26
|
+
if (nonce === undefined) {
|
|
27
|
+
const n = context.querySelector("[nonce]");
|
|
28
|
+
// NOTE: We're keeping n.getAttribute("nonce") until it is safe to remove:
|
|
29
|
+
// ref: https://github.com/whatwg/html/issues/2369#issuecomment-280853946
|
|
30
|
+
nonce = n && (n.nonce || n.getAttribute("nonce"));
|
|
31
|
+
}
|
|
32
|
+
return nonce;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Loads an external JavaScript file using Alloy's DOM utilities.
|
|
37
|
+
* Enhanced version that supports additional script attributes.
|
|
38
|
+
* @param {string} url The URL of the script to load.
|
|
39
|
+
* @param {Object} options Additional options for script loading
|
|
40
|
+
* @param {Object} options.attributes Additional attributes to set on script element
|
|
41
|
+
* @param {Function} options.onLoad Optional callback when script loads successfully
|
|
42
|
+
* @param {Function} options.onError Optional callback when script fails to load
|
|
43
|
+
* @returns {Promise<void>} A promise that resolves when the script is loaded or rejects on error.
|
|
44
|
+
*/
|
|
45
|
+
const loadScript = (url, options = {}) => {
|
|
46
|
+
// Check if script already exists
|
|
47
|
+
if (document.querySelector("script[src=\"" + url + "\"]")) {
|
|
48
|
+
if (options.onLoad) options.onLoad();
|
|
49
|
+
return Promise.resolve();
|
|
50
|
+
}
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
const {
|
|
53
|
+
attributes = {},
|
|
54
|
+
onLoad,
|
|
55
|
+
onError
|
|
56
|
+
} = options;
|
|
57
|
+
const script = (0, _createNode.default)("script", {
|
|
58
|
+
type: "text/javascript",
|
|
59
|
+
src: url,
|
|
60
|
+
async: true,
|
|
61
|
+
...(getNonce() && {
|
|
62
|
+
nonce: getNonce()
|
|
63
|
+
}),
|
|
64
|
+
...attributes // Allow additional attributes like crossorigin
|
|
65
|
+
}, {
|
|
66
|
+
onload: () => {
|
|
67
|
+
if (onLoad) onLoad();
|
|
68
|
+
resolve();
|
|
69
|
+
},
|
|
70
|
+
onerror: () => {
|
|
71
|
+
const error = new Error("Failed to load script: " + url);
|
|
72
|
+
if (onError) onError(error);
|
|
73
|
+
reject(error);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
const appendToDOM = () => {
|
|
77
|
+
const parent = document.head || document.body;
|
|
78
|
+
if (parent) {
|
|
79
|
+
(0, _appendNode.default)(parent, script);
|
|
80
|
+
} else {
|
|
81
|
+
const error = new Error("Neither <head> nor <body> available for script insertion.");
|
|
82
|
+
if (onError) onError(error);
|
|
83
|
+
reject(error);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
if (document.readyState === "loading") {
|
|
87
|
+
document.addEventListener("DOMContentLoaded", appendToDOM);
|
|
88
|
+
} else {
|
|
89
|
+
appendToDOM();
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
var _default = exports.default = loadScript;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2023 Adobe. All rights reserved.
|
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { objectOf, string, arrayOf, boolean } from "../../utils/validation/index.js";
|
|
14
|
+
export default objectOf({
|
|
15
|
+
advertising: objectOf({
|
|
16
|
+
id5PartnerId: string(),
|
|
17
|
+
rampIdJSPath: string(),
|
|
18
|
+
dspEnabled: boolean(),
|
|
19
|
+
advertiserSettings: arrayOf(objectOf({
|
|
20
|
+
advertiserId: string().required(),
|
|
21
|
+
enabled: boolean().required()
|
|
22
|
+
}).noUnknownFields())
|
|
23
|
+
}).noUnknownFields()
|
|
24
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// Cookie Keys
|
|
14
|
+
export const ADVERTISING_COOKIE_KEY = "advertising";
|
|
15
|
+
export const SURFER_ID_COOKIE_KEY = "surfer_id";
|
|
16
|
+
export const RAMP_ID_COOKIE_KEY = "ramp_id";
|
|
17
|
+
export const ID5_COOKIE_KEY = "id5_id";
|
|
18
|
+
export const LAST_CLICK_COOKIE_KEY = "_les_lsc";
|
|
19
|
+
export const LAST_CONVERSION_TIME_KEY = "lastConversionTime";
|
|
20
|
+
export const DISPLAY_CLICK_COOKIE_KEY_EXPIRES = "displayClickCookieExpires";
|
|
21
|
+
export const RAMP_ID_EXPIRES = "rampIdExpires";
|
|
22
|
+
export const LAST_CONVERSION_TIME_KEY_EXPIRES = "lastConversionTimeExpires";
|
|
23
|
+
// URL Parameters
|
|
24
|
+
export const SKWCID_PARAM = "s_kwcid";
|
|
25
|
+
export const EFID_PARAM = "ef_id";
|
|
26
|
+
|
|
27
|
+
// Identity Types
|
|
28
|
+
export const SURFER_ID = "surferId";
|
|
29
|
+
export const RAMP_ID = "rampId";
|
|
30
|
+
export const ID5_ID = "id5Id";
|
|
31
|
+
|
|
32
|
+
// Default Values
|
|
33
|
+
export const UNKNOWN_ADVERTISER = "";
|
|
34
|
+
export const DEFAULT_THROTTLE_MINUTES = 30;
|
|
35
|
+
export const DEFAULT_COOKIE_EXPIRATION_MINUTES = 527040; // 365 days
|
|
36
|
+
|
|
37
|
+
// Event Types
|
|
38
|
+
export const AD_CONVERSION_CLICK_EVENT_TYPE = "advertising.enrichment_ct";
|
|
39
|
+
export const AD_CONVERSION_VIEW_EVENT_TYPE = "advertising.enrichment";
|
|
40
|
+
|
|
41
|
+
// XDM Paths
|
|
42
|
+
export const XDM_AD_CLOUD_PATH = "_experience.adloud";
|
|
43
|
+
export const XDM_AD_ASSET_REFERENCE = "adAssetReference";
|
|
44
|
+
export const XDM_AD_STITCH_DATA = "adStitchData";
|
|
45
|
+
export const XDM_AD_ASSET_DATA = "adAssetData";
|
|
46
|
+
export const XDM_ADVERTISER = "advertiser";
|
|
47
|
+
export const TRACKING_CODE = "trackingCode";
|
|
48
|
+
export const TRACKING_IDENTITIES = "trackingIdentities";
|
|
49
|
+
|
|
50
|
+
// Script URLs
|
|
51
|
+
export const ID5_SCRIPT_URL = "https://www.everestjs.net/static/id5-api.js";
|
|
52
|
+
|
|
53
|
+
// Surfer ID Configuration
|
|
54
|
+
export const SURFER_PIXEL_HOST = "pixel.everesttech.net";
|
|
55
|
+
export const SURFER_USER_ID = "1";
|
|
56
|
+
export const SURFER_TIMEOUT_MS = 5000;
|
|
57
|
+
export const SURFER_TRUSTED_ORIGIN = "www.everestjs.net";
|
|
58
|
+
export const SURFER_PARAM_KEY = "gsurfer";
|
|
59
|
+
|
|
60
|
+
// Error Messages
|
|
61
|
+
export const ERROR_ID5_PARTNER_ID_REQUIRED = "ID5 partner ID is required";
|
|
62
|
+
export const ERROR_RAMP_ID_MAX_RETRIES = "Failed to retrieve RampID after maximum retries";
|
|
63
|
+
|
|
64
|
+
// Log Messages
|
|
65
|
+
export const LOG_AD_CONVERSION_START = "Processing ad conversion";
|
|
66
|
+
export const LOG_COOKIE_WRITTEN = "Ad tracking data saved";
|
|
67
|
+
export const LOG_CONVERSION_TIME_UPDATED = "Conversion timing recorded";
|
|
68
|
+
export const LOG_SENDING_CONVERSION = "Submitting ad conversion data";
|
|
69
|
+
export const LOG_ALL_IDS_THROTTLED = "Ad conversion paused to prevent duplicate submissions";
|
|
70
|
+
export const LOG_ALL_IDS_USED = "Ad conversion already processed";
|
|
71
|
+
export const LOG_ID_RESOLVED = "Ad identity available";
|
|
72
|
+
export const LOG_ERROR_RESOLVING_ID = "Unable to obtain ad identity";
|
|
73
|
+
export const LOG_ID_CONVERSION_SUCCESS = "Ad conversion submitted successfully";
|
|
74
|
+
export const LOG_AD_CONVERSION_FAILED = "Ad conversion submission failed";
|
|
75
|
+
export const DISPLAY_CLICK_COOKIE_KEY = "ev_lcc";
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2023 Adobe. All rights reserved.
|
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import createSendAdConversion from "./handlers/sendAdConversion.js";
|
|
14
|
+
import handleOnBeforeSendEvent from "./handlers/onBeforeSendEventHandler.js";
|
|
15
|
+
export default ({
|
|
16
|
+
logger,
|
|
17
|
+
config,
|
|
18
|
+
eventManager,
|
|
19
|
+
cookieManager,
|
|
20
|
+
adConversionHandler,
|
|
21
|
+
getBrowser
|
|
22
|
+
}) => {
|
|
23
|
+
const componentConfig = config.advertising;
|
|
24
|
+
const sharedState = {
|
|
25
|
+
processedAdvertisingIds: false
|
|
26
|
+
};
|
|
27
|
+
const sendAdConversionHandler = createSendAdConversion({
|
|
28
|
+
eventManager,
|
|
29
|
+
cookieManager,
|
|
30
|
+
adConversionHandler,
|
|
31
|
+
logger,
|
|
32
|
+
componentConfig,
|
|
33
|
+
getBrowser
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
lifecycle: {
|
|
37
|
+
onComponentsRegistered() {
|
|
38
|
+
sendAdConversionHandler(sharedState);
|
|
39
|
+
},
|
|
40
|
+
onBeforeEvent: ({
|
|
41
|
+
event,
|
|
42
|
+
advertising = {}
|
|
43
|
+
}) => {
|
|
44
|
+
return handleOnBeforeSendEvent({
|
|
45
|
+
cookieManager,
|
|
46
|
+
logger,
|
|
47
|
+
state: sharedState,
|
|
48
|
+
event,
|
|
49
|
+
componentConfig,
|
|
50
|
+
advertising,
|
|
51
|
+
getBrowser
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2023 Adobe. All rights reserved.
|
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { LAST_CLICK_COOKIE_KEY, LAST_CONVERSION_TIME_KEY, LOG_AD_CONVERSION_START, LOG_AD_CONVERSION_FAILED, AD_CONVERSION_CLICK_EVENT_TYPE, TRACKING_CODE, TRACKING_IDENTITIES, LAST_CONVERSION_TIME_KEY_EXPIRES } from "../constants/index.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Handles click-through ad conversions
|
|
17
|
+
* @param {Object} params - All required parameters
|
|
18
|
+
* @param {Object} params.eventManager - Event manager for creating events
|
|
19
|
+
* @param {Object} params.cookieManager - Session manager for cookie operations
|
|
20
|
+
* @param {Object} params.adConversionHandler - Handler for sending ad conversion events
|
|
21
|
+
* @param {Object} params.logger - Logger instance
|
|
22
|
+
* @param {string} params.skwcid - Search keyword click ID
|
|
23
|
+
* @param {string} params.efid - EF ID parameter
|
|
24
|
+
* @param {Object} params.optionsFromCommand - Additional options from command
|
|
25
|
+
* @returns {Promise} Result of the ad conversion tracking
|
|
26
|
+
*/
|
|
27
|
+
export default async function handleClickThrough({
|
|
28
|
+
eventManager,
|
|
29
|
+
cookieManager,
|
|
30
|
+
adConversionHandler,
|
|
31
|
+
logger,
|
|
32
|
+
skwcid,
|
|
33
|
+
efid
|
|
34
|
+
}) {
|
|
35
|
+
logger.info(LOG_AD_CONVERSION_START, {
|
|
36
|
+
skwcid,
|
|
37
|
+
efid
|
|
38
|
+
});
|
|
39
|
+
const event = eventManager.createEvent();
|
|
40
|
+
if (typeof skwcid !== "undefined" && typeof efid !== "undefined" && skwcid.startsWith("AL!")) {
|
|
41
|
+
const clickData = {
|
|
42
|
+
click_time: Date.now(),
|
|
43
|
+
...(typeof skwcid !== "undefined" && {
|
|
44
|
+
skwcid
|
|
45
|
+
}),
|
|
46
|
+
...(typeof efid !== "undefined" && {
|
|
47
|
+
efid
|
|
48
|
+
})
|
|
49
|
+
};
|
|
50
|
+
cookieManager.setValue(LAST_CLICK_COOKIE_KEY, clickData);
|
|
51
|
+
}
|
|
52
|
+
const xdm = {
|
|
53
|
+
_experience: {
|
|
54
|
+
adcloud: {
|
|
55
|
+
conversionDetails: {
|
|
56
|
+
...(typeof skwcid !== "undefined" && {
|
|
57
|
+
[TRACKING_CODE]: skwcid
|
|
58
|
+
}),
|
|
59
|
+
...(typeof efid !== "undefined" && {
|
|
60
|
+
[TRACKING_IDENTITIES]: efid
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
eventType: AD_CONVERSION_CLICK_EVENT_TYPE
|
|
66
|
+
};
|
|
67
|
+
event.setUserXdm(xdm);
|
|
68
|
+
cookieManager.setValue(LAST_CONVERSION_TIME_KEY);
|
|
69
|
+
cookieManager.setValue(LAST_CONVERSION_TIME_KEY_EXPIRES, Date.now() + 91 * 24 * 60 * 60 * 1000); //expires in 91 days
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
return await adConversionHandler.trackAdConversion({
|
|
73
|
+
event
|
|
74
|
+
});
|
|
75
|
+
} catch (error) {
|
|
76
|
+
logger.error(LOG_AD_CONVERSION_FAILED, error);
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2023 Adobe. All rights reserved.
|
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates a specialized handler for ad conversion events.
|
|
15
|
+
* This follows a similar pattern to the media event handling in the StreamingMedia component.
|
|
16
|
+
*/
|
|
17
|
+
export default ({
|
|
18
|
+
sendEdgeNetworkRequest,
|
|
19
|
+
consent,
|
|
20
|
+
createDataCollectionRequest,
|
|
21
|
+
createDataCollectionRequestPayload,
|
|
22
|
+
logger
|
|
23
|
+
}) => {
|
|
24
|
+
/**
|
|
25
|
+
* Tracks an ad conversion event by sending it directly to the Edge Network
|
|
26
|
+
*/
|
|
27
|
+
const trackAdConversion = ({
|
|
28
|
+
event
|
|
29
|
+
}) => {
|
|
30
|
+
const dataCollectionRequestPayload = createDataCollectionRequestPayload();
|
|
31
|
+
dataCollectionRequestPayload.addEvent(event);
|
|
32
|
+
event.finalize();
|
|
33
|
+
const request = createDataCollectionRequest({
|
|
34
|
+
payload: dataCollectionRequestPayload
|
|
35
|
+
});
|
|
36
|
+
return consent.awaitConsent().then(() => {
|
|
37
|
+
return sendEdgeNetworkRequest({
|
|
38
|
+
request
|
|
39
|
+
}).then(() => {
|
|
40
|
+
return {
|
|
41
|
+
success: true
|
|
42
|
+
};
|
|
43
|
+
}).catch(error => {
|
|
44
|
+
logger.error("Failed to send ad conversion event", error);
|
|
45
|
+
throw error;
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
trackAdConversion
|
|
51
|
+
};
|
|
52
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2023 Adobe. All rights reserved.
|
|
3
|
+
Licensed under the Apache License, Version 2.0.
|
|
4
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import collectSurferId from "../identities/collectSurferId.js";
|
|
8
|
+
import { getID5Id } from "../identities/collectID5Id.js";
|
|
9
|
+
import { getRampId } from "../identities/collectRampId.js";
|
|
10
|
+
import { appendAdvertisingIdQueryToEvent, getUrlParams, isThrottled } from "../utils/helpers.js";
|
|
11
|
+
import { SURFER_ID, ID5_ID, RAMP_ID } from "../constants/index.js";
|
|
12
|
+
import { AUTO, WAIT } from "../../../constants/consentStatus.js";
|
|
13
|
+
const isAdvertisingDisabled = advertising => {
|
|
14
|
+
return ![AUTO, WAIT].includes(advertising?.handleAdvertisingData);
|
|
15
|
+
};
|
|
16
|
+
const waitForAdvertisingId = advertising => {
|
|
17
|
+
return advertising?.handleAdvertisingData === WAIT;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Appends advertising identity IDs to AEP event query if not already added.
|
|
22
|
+
* @param {Object} params
|
|
23
|
+
* @param {Object} params.cookieManager
|
|
24
|
+
* @param {Object} params.logger
|
|
25
|
+
* @param {Object} params.state
|
|
26
|
+
* @param {Object} params.event
|
|
27
|
+
* @param {Object} params.componentConfig
|
|
28
|
+
* @param {Object} params.advertising
|
|
29
|
+
* @param {Function} params.getBrowser
|
|
30
|
+
*/
|
|
31
|
+
export default async function handleOnBeforeSendEvent({
|
|
32
|
+
cookieManager,
|
|
33
|
+
logger,
|
|
34
|
+
event,
|
|
35
|
+
componentConfig,
|
|
36
|
+
advertising,
|
|
37
|
+
getBrowser
|
|
38
|
+
}) {
|
|
39
|
+
const {
|
|
40
|
+
skwcid,
|
|
41
|
+
efid
|
|
42
|
+
} = getUrlParams();
|
|
43
|
+
const isClickThru = !!(skwcid && efid);
|
|
44
|
+
if (isAdvertisingDisabled(advertising) || isClickThru || isThrottled(SURFER_ID, cookieManager) && isThrottled(ID5_ID, cookieManager) && isThrottled(RAMP_ID, cookieManager)) return;
|
|
45
|
+
try {
|
|
46
|
+
const useShortTimeout = waitForAdvertisingId(advertising);
|
|
47
|
+
const [surferIdResult, id5IdResult, rampIdResult] = await Promise.allSettled([collectSurferId(cookieManager, getBrowser, useShortTimeout), getID5Id(logger, componentConfig.id5PartnerId, useShortTimeout, useShortTimeout), getRampId(logger, componentConfig.rampIdJSPath, cookieManager, useShortTimeout, useShortTimeout)]);
|
|
48
|
+
const availableIds = {};
|
|
49
|
+
if (surferIdResult.status === "fulfilled" && surferIdResult.value && !isThrottled(SURFER_ID, cookieManager)) {
|
|
50
|
+
availableIds.surferId = surferIdResult.value;
|
|
51
|
+
}
|
|
52
|
+
if (id5IdResult.status === "fulfilled" && id5IdResult.value && !isThrottled(ID5_ID, cookieManager)) {
|
|
53
|
+
availableIds.id5Id = id5IdResult.value;
|
|
54
|
+
}
|
|
55
|
+
if (rampIdResult.status === "fulfilled" && rampIdResult.value && !isThrottled(RAMP_ID, cookieManager)) {
|
|
56
|
+
availableIds.rampId = rampIdResult.value;
|
|
57
|
+
}
|
|
58
|
+
// If no IDs are available and any ID is throttled, return , because we dont have new info to send
|
|
59
|
+
if (Object.keys(availableIds).length === 0 && (isThrottled(SURFER_ID, cookieManager) || isThrottled(ID5_ID, cookieManager) || isThrottled(RAMP_ID, cookieManager))) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
appendAdvertisingIdQueryToEvent(availableIds, event, cookieManager, componentConfig);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
logger.error("Error in onBeforeSendEvent hook:", error);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2023 Adobe. All rights reserved.
|
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import handleClickThrough from "./clickThroughHandler.js";
|
|
14
|
+
import handleViewThrough from "./viewThroughHandler.js";
|
|
15
|
+
import { getUrlParams, normalizeAdvertiser } from "../utils/helpers.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Creates a handler for sending ad conversions.
|
|
19
|
+
* Handles both click-through and view-through conversions.
|
|
20
|
+
* This is a workaround to avoid the full lifecycle of the eventManager.sendEvent
|
|
21
|
+
*/
|
|
22
|
+
export default ({
|
|
23
|
+
eventManager,
|
|
24
|
+
cookieManager,
|
|
25
|
+
adConversionHandler,
|
|
26
|
+
logger,
|
|
27
|
+
componentConfig,
|
|
28
|
+
getBrowser
|
|
29
|
+
}) => {
|
|
30
|
+
const activeAdvertiserIds = componentConfig?.advertiserSettings ? normalizeAdvertiser(componentConfig.advertiserSettings) : "";
|
|
31
|
+
return async () => {
|
|
32
|
+
const {
|
|
33
|
+
skwcid,
|
|
34
|
+
efid
|
|
35
|
+
} = getUrlParams();
|
|
36
|
+
const isClickThru = !!(skwcid && efid);
|
|
37
|
+
try {
|
|
38
|
+
let result = null;
|
|
39
|
+
if (isClickThru) {
|
|
40
|
+
result = await handleClickThrough({
|
|
41
|
+
eventManager,
|
|
42
|
+
cookieManager,
|
|
43
|
+
adConversionHandler,
|
|
44
|
+
logger,
|
|
45
|
+
skwcid,
|
|
46
|
+
efid
|
|
47
|
+
});
|
|
48
|
+
return result;
|
|
49
|
+
} else if (activeAdvertiserIds) {
|
|
50
|
+
result = await handleViewThrough({
|
|
51
|
+
eventManager,
|
|
52
|
+
cookieManager,
|
|
53
|
+
logger,
|
|
54
|
+
componentConfig,
|
|
55
|
+
adConversionHandler,
|
|
56
|
+
getBrowser
|
|
57
|
+
});
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
logger.error("Error in sendAdConversion:", error);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
Licensed under the Apache License, Version 2.0.
|
|
4
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import collectAllIdentities from "../identities/collectAllIdentities.js";
|
|
8
|
+
import { LOG_ERROR_RESOLVING_ID, LOG_AD_CONVERSION_FAILED, AD_CONVERSION_VIEW_EVENT_TYPE } from "../constants/index.js";
|
|
9
|
+
import { isAnyIdUnused, appendAdvertisingIdQueryToEvent, markIdsAsConverted } from "../utils/helpers.js";
|
|
10
|
+
export default async function handleViewThrough({
|
|
11
|
+
eventManager,
|
|
12
|
+
cookieManager,
|
|
13
|
+
logger,
|
|
14
|
+
componentConfig,
|
|
15
|
+
adConversionHandler,
|
|
16
|
+
getBrowser
|
|
17
|
+
}) {
|
|
18
|
+
const resolvedIds = {};
|
|
19
|
+
const usedIdTracker = {};
|
|
20
|
+
const triggerConversion = async () => {
|
|
21
|
+
if (!isAnyIdUnused(resolvedIds, usedIdTracker)) return null;
|
|
22
|
+
const idTypesToUse = Object.keys(resolvedIds);
|
|
23
|
+
try {
|
|
24
|
+
const event = appendAdvertisingIdQueryToEvent(resolvedIds, eventManager.createEvent(), cookieManager, componentConfig, true);
|
|
25
|
+
const xdm = {
|
|
26
|
+
eventType: AD_CONVERSION_VIEW_EVENT_TYPE
|
|
27
|
+
};
|
|
28
|
+
event.setUserXdm(xdm);
|
|
29
|
+
const result = await adConversionHandler.trackAdConversion({
|
|
30
|
+
event
|
|
31
|
+
});
|
|
32
|
+
markIdsAsConverted(idTypesToUse, usedIdTracker, cookieManager, logger);
|
|
33
|
+
return result;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
logger.error(LOG_AD_CONVERSION_FAILED, error);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const identityPromisesMap = collectAllIdentities(logger, componentConfig, cookieManager, getBrowser);
|
|
40
|
+
if (Object.keys(identityPromisesMap).length === 0) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
const identityPromises = Object.entries(identityPromisesMap).map(([idType, idPromise]) => idPromise.then(idValue => {
|
|
44
|
+
if (idValue) {
|
|
45
|
+
resolvedIds[idType] = idValue;
|
|
46
|
+
return triggerConversion(); // Return the promise directly
|
|
47
|
+
}
|
|
48
|
+
}).catch(error => {
|
|
49
|
+
logger.error(LOG_ERROR_RESOLVING_ID.replace("{0}", idType), error);
|
|
50
|
+
return null;
|
|
51
|
+
}));
|
|
52
|
+
return Promise.allSettled(identityPromises); // Remove the separate conversionTasks handling
|
|
53
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import collectSurferId from "./collectSurferId.js";
|
|
14
|
+
import { getRampId } from "./collectRampId.js";
|
|
15
|
+
import { getID5Id } from "./collectID5Id.js";
|
|
16
|
+
import { ID5_ID, RAMP_ID, SURFER_ID } from "../constants/index.js";
|
|
17
|
+
import { isThrottled } from "../utils/helpers.js";
|
|
18
|
+
const collectAllIdentities = (logger, componentConfig, cookieManager, getBrowser) => {
|
|
19
|
+
const promises = {};
|
|
20
|
+
if (!isThrottled(SURFER_ID, cookieManager)) {
|
|
21
|
+
promises.surferId = collectSurferId(cookieManager, getBrowser, true).catch(() => null);
|
|
22
|
+
}
|
|
23
|
+
if (componentConfig.id5PartnerId && componentConfig.dspEnabled && !isThrottled(ID5_ID, cookieManager)) {
|
|
24
|
+
promises.id5Id = getID5Id(logger, componentConfig.id5PartnerId).catch(() => null);
|
|
25
|
+
}
|
|
26
|
+
if (componentConfig.rampIdJSPath && componentConfig.dspEnabled && !isThrottled(RAMP_ID, cookieManager)) {
|
|
27
|
+
promises.rampId = getRampId(logger, componentConfig.rampIdJSPath, cookieManager, true).catch(() => null);
|
|
28
|
+
}
|
|
29
|
+
return promises;
|
|
30
|
+
};
|
|
31
|
+
export default collectAllIdentities;
|