@adobe/alloy 2.28.1 → 2.29.0-beta.0

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.
Files changed (80) hide show
  1. package/libEs5/components/Advertising/configValidators.js +26 -0
  2. package/libEs5/components/Advertising/constants/index.js +78 -0
  3. package/libEs5/components/Advertising/createComponent.js +59 -0
  4. package/libEs5/components/Advertising/handlers/clickThroughHandler.js +81 -0
  5. package/libEs5/components/Advertising/handlers/createAdConversionHandler.js +55 -0
  6. package/libEs5/components/Advertising/handlers/onBeforeSendEventHandler.js +69 -0
  7. package/libEs5/components/Advertising/handlers/sendAdConversion.js +67 -0
  8. package/libEs5/components/Advertising/handlers/viewThroughHandler.js +56 -0
  9. package/libEs5/components/Advertising/identities/collectAllIdentities.js +34 -0
  10. package/libEs5/components/Advertising/identities/collectID5Id.js +112 -0
  11. package/libEs5/components/Advertising/identities/collectRampId.js +183 -0
  12. package/libEs5/components/Advertising/identities/collectSurferId.js +146 -0
  13. package/libEs5/components/Advertising/index.js +52 -0
  14. package/libEs5/components/Advertising/utils/advertisingCookieManager.js +80 -0
  15. package/libEs5/components/Advertising/utils/helpers.js +123 -0
  16. package/libEs5/components/DataCollector/validateUserEventOptions.js +5 -1
  17. package/libEs5/constants/consentStatus.js +5 -2
  18. package/libEs5/constants/libraryVersion.js +1 -1
  19. package/libEs5/core/componentCreators.js +8 -1
  20. package/libEs5/utils/dom/index.js +7 -0
  21. package/libEs5/utils/dom/loadScript.js +93 -0
  22. package/libEs6/components/Advertising/configValidators.js +24 -0
  23. package/libEs6/components/Advertising/constants/index.js +75 -0
  24. package/libEs6/components/Advertising/createComponent.js +56 -0
  25. package/libEs6/components/Advertising/handlers/clickThroughHandler.js +79 -0
  26. package/libEs6/components/Advertising/handlers/createAdConversionHandler.js +52 -0
  27. package/libEs6/components/Advertising/handlers/onBeforeSendEventHandler.js +66 -0
  28. package/libEs6/components/Advertising/handlers/sendAdConversion.js +65 -0
  29. package/libEs6/components/Advertising/handlers/viewThroughHandler.js +53 -0
  30. package/libEs6/components/Advertising/identities/collectAllIdentities.js +31 -0
  31. package/libEs6/components/Advertising/identities/collectID5Id.js +108 -0
  32. package/libEs6/components/Advertising/identities/collectRampId.js +179 -0
  33. package/libEs6/components/Advertising/identities/collectSurferId.js +143 -0
  34. package/libEs6/components/Advertising/index.js +49 -0
  35. package/libEs6/components/Advertising/utils/advertisingCookieManager.js +77 -0
  36. package/libEs6/components/Advertising/utils/helpers.js +113 -0
  37. package/libEs6/components/DataCollector/validateUserEventOptions.js +6 -2
  38. package/libEs6/constants/consentStatus.js +4 -1
  39. package/libEs6/constants/libraryVersion.js +1 -1
  40. package/libEs6/core/componentCreators.js +2 -1
  41. package/libEs6/utils/dom/index.js +1 -0
  42. package/libEs6/utils/dom/loadScript.js +90 -0
  43. package/package.json +2 -2
  44. package/types/components/Advertising/configValidators.d.ts +3 -0
  45. package/types/components/Advertising/configValidators.d.ts.map +1 -0
  46. package/types/components/Advertising/constants/index.d.ts +46 -0
  47. package/types/components/Advertising/constants/index.d.ts.map +1 -0
  48. package/types/components/Advertising/createComponent.d.ts +18 -0
  49. package/types/components/Advertising/createComponent.d.ts.map +1 -0
  50. package/types/components/Advertising/handlers/clickThroughHandler.d.ts +22 -0
  51. package/types/components/Advertising/handlers/clickThroughHandler.d.ts.map +1 -0
  52. package/types/components/Advertising/handlers/createAdConversionHandler.d.ts +13 -0
  53. package/types/components/Advertising/handlers/createAdConversionHandler.d.ts.map +1 -0
  54. package/types/components/Advertising/handlers/onBeforeSendEventHandler.d.ts +21 -0
  55. package/types/components/Advertising/handlers/onBeforeSendEventHandler.d.ts.map +1 -0
  56. package/types/components/Advertising/handlers/sendAdConversion.d.ts +10 -0
  57. package/types/components/Advertising/handlers/sendAdConversion.d.ts.map +1 -0
  58. package/types/components/Advertising/handlers/viewThroughHandler.d.ts +9 -0
  59. package/types/components/Advertising/handlers/viewThroughHandler.d.ts.map +1 -0
  60. package/types/components/Advertising/identities/collectAllIdentities.d.ts +7 -0
  61. package/types/components/Advertising/identities/collectAllIdentities.d.ts.map +1 -0
  62. package/types/components/Advertising/identities/collectID5Id.d.ts +3 -0
  63. package/types/components/Advertising/identities/collectID5Id.d.ts.map +1 -0
  64. package/types/components/Advertising/identities/collectRampId.d.ts +3 -0
  65. package/types/components/Advertising/identities/collectRampId.d.ts.map +1 -0
  66. package/types/components/Advertising/identities/collectSurferId.d.ts +3 -0
  67. package/types/components/Advertising/identities/collectSurferId.d.ts.map +1 -0
  68. package/types/components/Advertising/index.d.ts +23 -0
  69. package/types/components/Advertising/index.d.ts.map +1 -0
  70. package/types/components/Advertising/utils/advertisingCookieManager.d.ts +9 -0
  71. package/types/components/Advertising/utils/advertisingCookieManager.d.ts.map +1 -0
  72. package/types/components/Advertising/utils/helpers.d.ts +23 -0
  73. package/types/components/Advertising/utils/helpers.d.ts.map +1 -0
  74. package/types/components/DataCollector/validateUserEventOptions.d.ts.map +1 -1
  75. package/types/constants/consentStatus.d.ts +3 -0
  76. package/types/constants/consentStatus.d.ts.map +1 -1
  77. package/types/core/componentCreators.d.ts +1 -0
  78. package/types/utils/dom/index.d.ts +1 -0
  79. package/types/utils/dom/loadScript.d.ts +17 -0
  80. 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;