@adobe/alloy 2.29.0 → 2.30.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/PushNotifications/helpers/constants.js +19 -0
- package/libEs5/components/PushNotifications/helpers/readFromIndexedDb.js +41 -0
- package/libEs5/components/PushNotifications/helpers/saveToIndexedDb.js +50 -0
- package/libEs5/components/PushNotifications/helpers/serviceWorkerNotificationClickListener.js +85 -0
- package/libEs5/components/PushNotifications/helpers/serviceWorkerPushListener.js +70 -0
- package/libEs5/components/PushNotifications/index.js +43 -10
- package/libEs5/components/PushNotifications/request/createSendPushSubscriptionPayload.js +3 -3
- package/libEs5/components/PushNotifications/request/makeSendPushSubscriptionRequest.js +8 -3
- package/libEs5/components/PushNotifications/request/makeSendServiceWorkerTrackingData.js +146 -0
- package/libEs5/components/PushNotifications/serviceWorker.js +91 -0
- package/libEs5/components/PushNotifications/types.js +81 -0
- package/libEs5/constants/libraryVersion.js +1 -1
- package/libEs5/utils/index.js +19 -0
- package/libEs5/utils/indexedDb.js +73 -0
- package/libEs6/components/PushNotifications/helpers/constants.js +16 -0
- package/libEs6/components/PushNotifications/helpers/readFromIndexedDb.js +40 -0
- package/libEs6/components/PushNotifications/helpers/saveToIndexedDb.js +48 -0
- package/libEs6/components/PushNotifications/helpers/serviceWorkerNotificationClickListener.js +82 -0
- package/libEs6/components/PushNotifications/helpers/serviceWorkerPushListener.js +69 -0
- package/libEs6/components/PushNotifications/index.js +43 -10
- package/libEs6/components/PushNotifications/request/createSendPushSubscriptionPayload.js +3 -3
- package/libEs6/components/PushNotifications/request/makeSendPushSubscriptionRequest.js +8 -3
- package/libEs6/components/PushNotifications/request/makeSendServiceWorkerTrackingData.js +146 -0
- package/libEs6/components/PushNotifications/serviceWorker.js +90 -0
- package/libEs6/components/PushNotifications/types.js +81 -0
- package/libEs6/constants/libraryVersion.js +1 -1
- package/libEs6/utils/index.js +1 -0
- package/libEs6/utils/indexedDb.js +67 -0
- package/package.json +29 -36
- package/scripts/alloyBuilder.js +130 -4
- package/types/components/PushNotifications/helpers/constants.d.ts +5 -0
- package/types/components/PushNotifications/helpers/constants.d.ts.map +1 -0
- package/types/components/PushNotifications/helpers/readFromIndexedDb.d.ts +4 -0
- package/types/components/PushNotifications/helpers/readFromIndexedDb.d.ts.map +1 -0
- package/types/components/PushNotifications/helpers/saveToIndexedDb.d.ts +9 -0
- package/types/components/PushNotifications/helpers/saveToIndexedDb.d.ts.map +1 -0
- package/types/components/PushNotifications/helpers/serviceWorkerNotificationClickListener.d.ts +9 -0
- package/types/components/PushNotifications/helpers/serviceWorkerNotificationClickListener.d.ts.map +1 -0
- package/types/components/PushNotifications/helpers/serviceWorkerPushListener.d.ts +8 -0
- package/types/components/PushNotifications/helpers/serviceWorkerPushListener.d.ts.map +1 -0
- package/types/components/PushNotifications/index.d.ts +11 -3
- package/types/components/PushNotifications/index.d.ts.map +1 -1
- package/types/components/PushNotifications/request/createSendPushSubscriptionPayload.d.ts +2 -2
- package/types/components/PushNotifications/request/createSendPushSubscriptionPayload.d.ts.map +1 -1
- package/types/components/PushNotifications/request/makeSendPushSubscriptionRequest.d.ts +2 -1
- package/types/components/PushNotifications/request/makeSendPushSubscriptionRequest.d.ts.map +1 -1
- package/types/components/PushNotifications/request/makeSendServiceWorkerTrackingData.d.ts +11 -0
- package/types/components/PushNotifications/request/makeSendServiceWorkerTrackingData.d.ts.map +1 -0
- package/types/components/PushNotifications/serviceWorker.d.ts +2 -0
- package/types/components/PushNotifications/serviceWorker.d.ts.map +1 -0
- package/types/components/PushNotifications/types.d.ts +167 -0
- package/types/components/PushNotifications/types.d.ts.map +1 -1
- package/types/utils/index.d.ts +1 -0
- package/types/utils/indexedDb.d.ts +4 -0
- package/types/utils/indexedDb.d.ts.map +1 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.STORE_NAME = exports.INDEX_KEY = exports.DB_VERSION = exports.DB_NAME = void 0;
|
|
4
|
+
/*
|
|
5
|
+
Copyright 2025 Adobe. All rights reserved.
|
|
6
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
8
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
11
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
12
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
13
|
+
governing permissions and limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const DB_NAME = exports.DB_NAME = "alloyPushNotifications";
|
|
17
|
+
const DB_VERSION = exports.DB_VERSION = 1;
|
|
18
|
+
const STORE_NAME = exports.STORE_NAME = "config";
|
|
19
|
+
const INDEX_KEY = exports.INDEX_KEY = "alloyConfig";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.default = void 0;
|
|
4
|
+
var _indexedDb = require("../../../utils/indexedDb.js");
|
|
5
|
+
var _constants = require("./constants.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
|
+
/** @import { ServiceWorkerLogger } from '../types.js' */
|
|
18
|
+
/**
|
|
19
|
+
* @param {ServiceWorkerLogger} logger
|
|
20
|
+
* @returns {Promise<Object|undefined>}
|
|
21
|
+
* @throws {Error}
|
|
22
|
+
*/
|
|
23
|
+
var _default = async logger => {
|
|
24
|
+
try {
|
|
25
|
+
const db = await (0, _indexedDb.openIndexedDb)(_constants.DB_NAME, _constants.DB_VERSION, (/** @type {IDBDatabase} */db) => {
|
|
26
|
+
if (!db.objectStoreNames.contains(_constants.STORE_NAME)) {
|
|
27
|
+
db.createObjectStore(_constants.STORE_NAME, {
|
|
28
|
+
keyPath: "id"
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const existingConfigData = await (0, _indexedDb.getFromIndexedDbStore)(db, _constants.STORE_NAME, _constants.INDEX_KEY);
|
|
33
|
+
db.close();
|
|
34
|
+
return existingConfigData;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
logger.error("Failed to read data from IndexedDB", {
|
|
37
|
+
error
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
exports.default = _default;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.default = saveToIndexedDB;
|
|
4
|
+
var _index = require("../../../utils/index.js");
|
|
5
|
+
var _constants = require("./constants.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
|
+
/** @import { Logger } from '../../../core/types.js' */
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {Object} data
|
|
22
|
+
* @param {Logger} logger
|
|
23
|
+
*
|
|
24
|
+
* @returns {Promise<void>}
|
|
25
|
+
*/
|
|
26
|
+
async function saveToIndexedDB(data, logger) {
|
|
27
|
+
try {
|
|
28
|
+
const db = await (0, _index.openIndexedDb)(_constants.DB_NAME, _constants.DB_VERSION, (/** @type {IDBDatabase} */db) => {
|
|
29
|
+
if (!db.objectStoreNames.contains(_constants.STORE_NAME)) {
|
|
30
|
+
db.createObjectStore(_constants.STORE_NAME, {
|
|
31
|
+
keyPath: "id"
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const existingConfigData = await (0, _index.getFromIndexedDbStore)(db, _constants.STORE_NAME, _constants.INDEX_KEY);
|
|
36
|
+
const updatedConfigData = {
|
|
37
|
+
...(existingConfigData || {}),
|
|
38
|
+
...data,
|
|
39
|
+
id: _constants.INDEX_KEY,
|
|
40
|
+
timestamp: Date.now()
|
|
41
|
+
};
|
|
42
|
+
await (0, _index.putToIndexedDbStore)(db, _constants.STORE_NAME, updatedConfigData);
|
|
43
|
+
db.close();
|
|
44
|
+
logger.info("Successfully saved web SDK config to IndexedDB", updatedConfigData);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
logger.error("Failed to save config to IndexedDB", {
|
|
47
|
+
error
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.default = void 0;
|
|
4
|
+
var _makeSendServiceWorkerTrackingData = require("../request/makeSendServiceWorkerTrackingData.js");
|
|
5
|
+
/*
|
|
6
|
+
Copyright 2025 Adobe. All rights reserved.
|
|
7
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
9
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
12
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
13
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
14
|
+
governing permissions and limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// @ts-check
|
|
18
|
+
/// <reference lib="webworker" />
|
|
19
|
+
|
|
20
|
+
/** @import { ServiceWorkerLogger } from '../types.js' */
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {string} type
|
|
24
|
+
* @returns {boolean}
|
|
25
|
+
*/
|
|
26
|
+
const canHandleUrl = type => ["DEEPLINK", "WEBURL"].includes(type);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @function
|
|
30
|
+
*
|
|
31
|
+
* @param {Object} options
|
|
32
|
+
* @param {ServiceWorkerGlobalScope} options.sw
|
|
33
|
+
* @param {NotificationEvent} options.event
|
|
34
|
+
* @param {(url: string, options: object) => Promise<Response>} options.fetch
|
|
35
|
+
* @param {ServiceWorkerLogger} options.logger
|
|
36
|
+
*/
|
|
37
|
+
var _default = ({
|
|
38
|
+
event,
|
|
39
|
+
sw,
|
|
40
|
+
logger,
|
|
41
|
+
fetch
|
|
42
|
+
}) => {
|
|
43
|
+
event.notification.close();
|
|
44
|
+
const data = event.notification.data;
|
|
45
|
+
let targetUrl = null;
|
|
46
|
+
let actionLabel = null;
|
|
47
|
+
if (event.action) {
|
|
48
|
+
const actionIndex = parseInt(event.action.replace("action_", ""), 10);
|
|
49
|
+
if (data?.actions?.buttons[actionIndex]) {
|
|
50
|
+
const button = data.actions.buttons[actionIndex];
|
|
51
|
+
actionLabel = button.label;
|
|
52
|
+
if (canHandleUrl(button.type) && button.uri) {
|
|
53
|
+
targetUrl = button.uri;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} else if (canHandleUrl(data?.interaction?.type) && data?.interaction?.uri) {
|
|
57
|
+
targetUrl = data.interaction.uri;
|
|
58
|
+
}
|
|
59
|
+
(0, _makeSendServiceWorkerTrackingData.default)({
|
|
60
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
61
|
+
xdm: data._xdm.mixins,
|
|
62
|
+
actionLabel,
|
|
63
|
+
applicationLaunches: 1
|
|
64
|
+
}, {
|
|
65
|
+
logger,
|
|
66
|
+
fetch
|
|
67
|
+
}).catch(error => {
|
|
68
|
+
logger.error("Failed to send tracking call:", error);
|
|
69
|
+
});
|
|
70
|
+
if (targetUrl) {
|
|
71
|
+
event.waitUntil(sw.clients.matchAll({
|
|
72
|
+
type: "window"
|
|
73
|
+
}).then(clientList => {
|
|
74
|
+
for (const client of clientList) {
|
|
75
|
+
if (client.url === targetUrl && "focus" in client) {
|
|
76
|
+
return client.focus();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (sw.clients.openWindow) {
|
|
80
|
+
return sw.clients.openWindow(targetUrl);
|
|
81
|
+
}
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
exports.default = _default;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.default = void 0;
|
|
4
|
+
/*
|
|
5
|
+
Copyright 2025 Adobe. All rights reserved.
|
|
6
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
8
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
11
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
12
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
13
|
+
governing permissions and limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
// @ts-check
|
|
16
|
+
/// <reference lib="webworker" />
|
|
17
|
+
/** @import { PushNotificationData } from '../types.js' */
|
|
18
|
+
/** @import { ServiceWorkerLogger } from '../types.js' */
|
|
19
|
+
/**
|
|
20
|
+
* @async
|
|
21
|
+
* @function
|
|
22
|
+
*
|
|
23
|
+
* @param {Object} options
|
|
24
|
+
* @param {ServiceWorkerGlobalScope} options.sw
|
|
25
|
+
* @param {PushEvent} options.event
|
|
26
|
+
* @param {ServiceWorkerLogger} options.logger
|
|
27
|
+
* @returns {Promise<void>}
|
|
28
|
+
*/
|
|
29
|
+
var _default = async ({
|
|
30
|
+
sw,
|
|
31
|
+
event,
|
|
32
|
+
logger
|
|
33
|
+
}) => {
|
|
34
|
+
if (!event.data) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** @type {PushNotificationData} */
|
|
39
|
+
let notificationData;
|
|
40
|
+
try {
|
|
41
|
+
notificationData = event.data.json();
|
|
42
|
+
} catch (error) {
|
|
43
|
+
logger.error("Error decoding notification JSON data:", error);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const webData = notificationData.web;
|
|
47
|
+
if (!webData?.title) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const notificationOptions = {
|
|
51
|
+
body: webData.body,
|
|
52
|
+
icon: webData.media,
|
|
53
|
+
image: webData.media,
|
|
54
|
+
data: webData,
|
|
55
|
+
actions: []
|
|
56
|
+
};
|
|
57
|
+
Object.keys(notificationOptions).forEach(k => {
|
|
58
|
+
if (notificationOptions[k] == null) {
|
|
59
|
+
delete notificationOptions[k];
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
if (webData.actions && webData.actions.buttons) {
|
|
63
|
+
notificationOptions.actions = webData.actions.buttons.map((button, index) => ({
|
|
64
|
+
action: "action_" + index,
|
|
65
|
+
title: button.label
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
return sw.registration.showNotification(webData.title, notificationOptions);
|
|
69
|
+
};
|
|
70
|
+
exports.default = _default;
|
|
@@ -4,6 +4,7 @@ exports.default = void 0;
|
|
|
4
4
|
var _index = require("../../utils/validation/index.js");
|
|
5
5
|
var _index2 = require("../../utils/index.js");
|
|
6
6
|
var _makeSendPushSubscriptionRequest = require("./request/makeSendPushSubscriptionRequest.js");
|
|
7
|
+
var _saveToIndexedDb = require("./helpers/saveToIndexedDb.js");
|
|
7
8
|
/*
|
|
8
9
|
Copyright 2025 Adobe. All rights reserved.
|
|
9
10
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -25,24 +26,29 @@ governing permissions and limitations under the License.
|
|
|
25
26
|
const isComponentConfigured = ({
|
|
26
27
|
orgId,
|
|
27
28
|
pushNotifications: {
|
|
28
|
-
vapidPublicKey
|
|
29
|
+
vapidPublicKey,
|
|
30
|
+
appId,
|
|
31
|
+
trackingDatasetId
|
|
29
32
|
} = {
|
|
30
|
-
vapidPublicKey: undefined
|
|
33
|
+
vapidPublicKey: undefined,
|
|
34
|
+
appId: undefined,
|
|
35
|
+
trackingDatasetId: undefined
|
|
31
36
|
}
|
|
32
|
-
}) => orgId && vapidPublicKey;
|
|
37
|
+
}) => orgId && vapidPublicKey && appId && trackingDatasetId;
|
|
33
38
|
|
|
34
39
|
/**
|
|
35
40
|
* @function
|
|
36
41
|
*
|
|
37
42
|
* @param {Object} options
|
|
38
|
-
* @param {{ orgId: string, pushNotifications: { vapidPublicKey: string }}} options.config
|
|
43
|
+
* @param {{ orgId: string, datastreamId: string, edgeDomain: string, edgeBasePath: string, pushNotifications: { vapidPublicKey: string, appId: string, trackingDatasetId: string }}} options.config
|
|
39
44
|
* @param {StorageCreator} options.createNamespacedStorage
|
|
40
45
|
* @param {EventManager} options.eventManager
|
|
41
46
|
* @param {Logger} options.logger
|
|
42
47
|
* @param {ConsentManager} options.consent
|
|
43
48
|
* @param {IdentityManager} options.identity
|
|
49
|
+
* @param {function(): string} options.getBrowser
|
|
44
50
|
* @param {EdgeRequestExecutor} options.sendEdgeNetworkRequest
|
|
45
|
-
* @returns {{
|
|
51
|
+
* @returns {{ lifecycle: object, commands: { sendPushSubscription: object } }}
|
|
46
52
|
*/
|
|
47
53
|
const createPushNotifications = ({
|
|
48
54
|
createNamespacedStorage,
|
|
@@ -51,27 +57,52 @@ const createPushNotifications = ({
|
|
|
51
57
|
logger,
|
|
52
58
|
consent,
|
|
53
59
|
identity,
|
|
60
|
+
getBrowser,
|
|
54
61
|
sendEdgeNetworkRequest
|
|
55
62
|
}) => {
|
|
56
63
|
return {
|
|
64
|
+
lifecycle: {
|
|
65
|
+
async onComponentsRegistered() {
|
|
66
|
+
if (isComponentConfigured(config)) {
|
|
67
|
+
const {
|
|
68
|
+
datastreamId,
|
|
69
|
+
edgeDomain,
|
|
70
|
+
edgeBasePath,
|
|
71
|
+
pushNotifications: {
|
|
72
|
+
trackingDatasetId
|
|
73
|
+
}
|
|
74
|
+
} = config;
|
|
75
|
+
await (0, _saveToIndexedDb.default)({
|
|
76
|
+
datastreamId,
|
|
77
|
+
edgeDomain,
|
|
78
|
+
edgeBasePath,
|
|
79
|
+
datasetId: trackingDatasetId,
|
|
80
|
+
browser: getBrowser()
|
|
81
|
+
}, logger);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
57
85
|
commands: {
|
|
58
86
|
sendPushSubscription: {
|
|
59
87
|
run: async () => {
|
|
60
88
|
if (!isComponentConfigured(config)) {
|
|
61
|
-
throw new Error("Push notifications module is not configured.
|
|
89
|
+
throw new Error("Push notifications module is not configured.");
|
|
62
90
|
}
|
|
63
91
|
const {
|
|
64
92
|
orgId,
|
|
65
93
|
pushNotifications: {
|
|
66
|
-
vapidPublicKey
|
|
94
|
+
vapidPublicKey,
|
|
95
|
+
appId
|
|
67
96
|
} = {
|
|
68
|
-
vapidPublicKey: undefined
|
|
97
|
+
vapidPublicKey: undefined,
|
|
98
|
+
appId: undefined
|
|
69
99
|
}
|
|
70
100
|
} = config || {};
|
|
71
101
|
const storage = createNamespacedStorage((0, _index2.sanitizeOrgIdForCookieName)(orgId) + ".pushNotifications.");
|
|
72
102
|
return (0, _makeSendPushSubscriptionRequest.default)({
|
|
73
103
|
config: {
|
|
74
|
-
vapidPublicKey
|
|
104
|
+
vapidPublicKey,
|
|
105
|
+
appId
|
|
75
106
|
},
|
|
76
107
|
storage: storage.persistent,
|
|
77
108
|
logger,
|
|
@@ -90,7 +121,9 @@ const createPushNotifications = ({
|
|
|
90
121
|
createPushNotifications.namespace = "Push Notifications";
|
|
91
122
|
createPushNotifications.configValidators = (0, _index.objectOf)({
|
|
92
123
|
pushNotifications: (0, _index.objectOf)({
|
|
93
|
-
vapidPublicKey: (0, _index.string)().required()
|
|
124
|
+
vapidPublicKey: (0, _index.string)().required(),
|
|
125
|
+
appId: (0, _index.string)().required(),
|
|
126
|
+
trackingDatasetId: (0, _index.string)().required()
|
|
94
127
|
}).noUnknownFields()
|
|
95
128
|
});
|
|
96
129
|
var _default = exports.default = createPushNotifications;
|
|
@@ -29,7 +29,7 @@ governing permissions and limitations under the License.
|
|
|
29
29
|
* @param {string} options.ecid
|
|
30
30
|
* @param {EventManager} options.eventManager
|
|
31
31
|
* @param {string} options.serializedPushSubscriptionDetails
|
|
32
|
-
* @param {
|
|
32
|
+
* @param {string} options.appId
|
|
33
33
|
*
|
|
34
34
|
* @returns {Promise<DataCollectionRequestPayload>}
|
|
35
35
|
*/
|
|
@@ -37,12 +37,12 @@ var _default = async ({
|
|
|
37
37
|
ecid,
|
|
38
38
|
eventManager,
|
|
39
39
|
serializedPushSubscriptionDetails,
|
|
40
|
-
|
|
40
|
+
appId
|
|
41
41
|
}) => {
|
|
42
42
|
const event = eventManager.createEvent();
|
|
43
43
|
event.setUserData({
|
|
44
44
|
pushNotificationDetails: [{
|
|
45
|
-
appID:
|
|
45
|
+
appID: appId,
|
|
46
46
|
token: serializedPushSubscriptionDetails,
|
|
47
47
|
platform: "web",
|
|
48
48
|
denylisted: false,
|
|
@@ -5,6 +5,7 @@ var _index = require("../../../utils/index.js");
|
|
|
5
5
|
var _getPushSubscriptionDetails = require("../helpers/getPushSubscriptionDetails.js");
|
|
6
6
|
var _createSendPushSubscriptionRequest = require("./createSendPushSubscriptionRequest.js");
|
|
7
7
|
var _createSendPushSubscriptionPayload = require("./createSendPushSubscriptionPayload.js");
|
|
8
|
+
var _saveToIndexedDb = require("../helpers/saveToIndexedDb.js");
|
|
8
9
|
/*
|
|
9
10
|
Copyright 2025 Adobe. All rights reserved.
|
|
10
11
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -35,7 +36,7 @@ const SUBSCRIPTION_DETAILS = "subscriptionDetails";
|
|
|
35
36
|
* @function
|
|
36
37
|
*
|
|
37
38
|
* @param {Object} options
|
|
38
|
-
* @param {{vapidPublicKey: string}} options.config
|
|
39
|
+
* @param {{vapidPublicKey: string, appId: string}} options.config
|
|
39
40
|
* @param {Storage} options.storage
|
|
40
41
|
* @param {Logger} options.logger
|
|
41
42
|
* @param {EventManager} options.eventManager
|
|
@@ -48,7 +49,8 @@ const SUBSCRIPTION_DETAILS = "subscriptionDetails";
|
|
|
48
49
|
*/
|
|
49
50
|
var _default = async ({
|
|
50
51
|
config: {
|
|
51
|
-
vapidPublicKey
|
|
52
|
+
vapidPublicKey,
|
|
53
|
+
appId
|
|
52
54
|
},
|
|
53
55
|
storage,
|
|
54
56
|
logger,
|
|
@@ -75,7 +77,7 @@ var _default = async ({
|
|
|
75
77
|
eventManager,
|
|
76
78
|
ecid,
|
|
77
79
|
serializedPushSubscriptionDetails,
|
|
78
|
-
|
|
80
|
+
appId
|
|
79
81
|
});
|
|
80
82
|
const request = (0, _createSendPushSubscriptionRequest.default)({
|
|
81
83
|
payload
|
|
@@ -84,5 +86,8 @@ var _default = async ({
|
|
|
84
86
|
await sendEdgeNetworkRequest({
|
|
85
87
|
request
|
|
86
88
|
});
|
|
89
|
+
await (0, _saveToIndexedDb.default)({
|
|
90
|
+
ecid
|
|
91
|
+
}, logger);
|
|
87
92
|
};
|
|
88
93
|
exports.default = _default;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.default = void 0;
|
|
4
|
+
var _readFromIndexedDb = require("../helpers/readFromIndexedDb.js");
|
|
5
|
+
var _uuid = require("../../../utils/uuid.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
|
+
/* eslint-disable no-underscore-dangle */
|
|
18
|
+
/** @import { ServiceWorkerLogger } from '../types.js' */
|
|
19
|
+
/** @import { TrackingDataPayload } from '../types.js' */
|
|
20
|
+
/**
|
|
21
|
+
* @async
|
|
22
|
+
* @function
|
|
23
|
+
* @param {Object} options
|
|
24
|
+
* @param {Object} options.xdm
|
|
25
|
+
* @param {string} [options.actionLabel]
|
|
26
|
+
* @param {number} [options.applicationLaunches=0]
|
|
27
|
+
* @param {Object} utils
|
|
28
|
+
* @param {ServiceWorkerLogger} utils.logger
|
|
29
|
+
* @param {(url: string, options: object) => Promise<Response>} utils.fetch
|
|
30
|
+
*
|
|
31
|
+
* @returns {Promise<boolean>}
|
|
32
|
+
* @throws {Error}
|
|
33
|
+
*/
|
|
34
|
+
var _default = async ({
|
|
35
|
+
xdm,
|
|
36
|
+
actionLabel,
|
|
37
|
+
applicationLaunches = 0
|
|
38
|
+
}, {
|
|
39
|
+
logger,
|
|
40
|
+
fetch
|
|
41
|
+
}) => {
|
|
42
|
+
const configData = await (0, _readFromIndexedDb.default)(logger);
|
|
43
|
+
const {
|
|
44
|
+
browser,
|
|
45
|
+
ecid,
|
|
46
|
+
edgeDomain,
|
|
47
|
+
edgeBasePath,
|
|
48
|
+
datastreamId,
|
|
49
|
+
datasetId
|
|
50
|
+
} = configData || {};
|
|
51
|
+
let customActionData = {};
|
|
52
|
+
if (actionLabel) {
|
|
53
|
+
customActionData = {
|
|
54
|
+
customAction: {
|
|
55
|
+
actionID: actionLabel
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const requiredFields = [{
|
|
60
|
+
name: "browser",
|
|
61
|
+
errorField: "Browser"
|
|
62
|
+
}, {
|
|
63
|
+
name: "ecid",
|
|
64
|
+
errorField: "ECID"
|
|
65
|
+
}, {
|
|
66
|
+
name: "edgeDomain",
|
|
67
|
+
errorField: "Edge domain"
|
|
68
|
+
}, {
|
|
69
|
+
name: "edgeBasePath",
|
|
70
|
+
errorField: "Edge base path"
|
|
71
|
+
}, {
|
|
72
|
+
name: "datastreamId",
|
|
73
|
+
errorField: "Datastream ID"
|
|
74
|
+
}, {
|
|
75
|
+
name: "datasetId",
|
|
76
|
+
errorField: "Dataset ID"
|
|
77
|
+
}];
|
|
78
|
+
try {
|
|
79
|
+
for (const field of requiredFields) {
|
|
80
|
+
if (!configData[field.name]) {
|
|
81
|
+
throw new Error("Cannot send tracking call. " + field.errorField + " is missing.");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const url = "https://" + edgeDomain + "/" + edgeBasePath + "/v1/interact?configId=" + datastreamId;
|
|
85
|
+
|
|
86
|
+
/** @type {TrackingDataPayload} */
|
|
87
|
+
const payload = {
|
|
88
|
+
events: [{
|
|
89
|
+
xdm: {
|
|
90
|
+
identityMap: {
|
|
91
|
+
ECID: [{
|
|
92
|
+
id: ecid
|
|
93
|
+
}]
|
|
94
|
+
},
|
|
95
|
+
timestamp: new Date().toISOString(),
|
|
96
|
+
pushNotificationTracking: {
|
|
97
|
+
...customActionData,
|
|
98
|
+
pushProviderMessageID: (0, _uuid.default)(),
|
|
99
|
+
pushProvider: browser.toLowerCase()
|
|
100
|
+
},
|
|
101
|
+
application: {
|
|
102
|
+
launches: {
|
|
103
|
+
value: applicationLaunches
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
eventType: actionLabel ? "pushTracking.customAction" : "pushTracking.applicationOpened",
|
|
107
|
+
_experience: {
|
|
108
|
+
...xdm._experience,
|
|
109
|
+
customerJourneyManagement: {
|
|
110
|
+
...xdm._experience.customerJourneyManagement,
|
|
111
|
+
pushChannelContext: {
|
|
112
|
+
platform: "web"
|
|
113
|
+
},
|
|
114
|
+
messageProfile: {
|
|
115
|
+
channel: {
|
|
116
|
+
_id: "https://ns.adobe.com/xdm/channels/push"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
meta: {
|
|
123
|
+
collect: {
|
|
124
|
+
datasetId
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}]
|
|
128
|
+
};
|
|
129
|
+
const response = await fetch(url, {
|
|
130
|
+
method: "POST",
|
|
131
|
+
headers: {
|
|
132
|
+
"content-type": "text/plain; charset=UTF-8"
|
|
133
|
+
},
|
|
134
|
+
body: JSON.stringify(payload)
|
|
135
|
+
});
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
logger.error("Tracking call failed: ", response.status, response.statusText);
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
logger.error("Error sending tracking call:", error);
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
exports.default = _default;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _serviceWorkerNotificationClickListener = require("./helpers/serviceWorkerNotificationClickListener.js");
|
|
4
|
+
var _serviceWorkerPushListener = require("./helpers/serviceWorkerPushListener.js");
|
|
5
|
+
var _makeSendServiceWorkerTrackingData = require("./request/makeSendServiceWorkerTrackingData.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
|
+
/** @import { ServiceWorkerLogger } from './types.js' */
|
|
19
|
+
|
|
20
|
+
/* eslint-disable no-console */
|
|
21
|
+
/* eslint-disable no-underscore-dangle */
|
|
22
|
+
|
|
23
|
+
// @ts-check
|
|
24
|
+
/// <reference lib="webworker" />
|
|
25
|
+
|
|
26
|
+
/** @type {ServiceWorkerGlobalScope} */
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
const sw = self;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @type {ServiceWorkerLogger}
|
|
32
|
+
*/
|
|
33
|
+
const logger = {
|
|
34
|
+
namespace: "[alloy][pushNotificationWorker]",
|
|
35
|
+
info: (...args) => console.log(logger.namespace, ...args),
|
|
36
|
+
error: (...args) => console.error(logger.namespace, ...args)
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @listens install
|
|
41
|
+
*/
|
|
42
|
+
sw.addEventListener("install", () => {
|
|
43
|
+
sw.skipWaiting();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @listens activate
|
|
48
|
+
* @param {ExtendableEvent} event
|
|
49
|
+
*/
|
|
50
|
+
sw.addEventListener("activate", event => {
|
|
51
|
+
event.waitUntil(sw.clients.claim());
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @listens push
|
|
56
|
+
* @param {PushEvent} event
|
|
57
|
+
* @returns {Promise<void>}
|
|
58
|
+
*/
|
|
59
|
+
sw.addEventListener("push", event => (0, _serviceWorkerPushListener.default)({
|
|
60
|
+
event,
|
|
61
|
+
logger,
|
|
62
|
+
sw
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @listens notificationclick
|
|
67
|
+
* @param {NotificationEvent} event
|
|
68
|
+
*/
|
|
69
|
+
sw.addEventListener("notificationclick", event => (0, _serviceWorkerNotificationClickListener.default)({
|
|
70
|
+
event,
|
|
71
|
+
sw,
|
|
72
|
+
logger,
|
|
73
|
+
fetch
|
|
74
|
+
}));
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @listens notificationclose
|
|
78
|
+
* @param {NotificationEvent} event
|
|
79
|
+
*/
|
|
80
|
+
sw.addEventListener("notificationclose", event => {
|
|
81
|
+
const data = event.notification.data;
|
|
82
|
+
(0, _makeSendServiceWorkerTrackingData.default)({
|
|
83
|
+
xdm: data._xdm.mixins,
|
|
84
|
+
actionLabel: "Dismiss"
|
|
85
|
+
}, {
|
|
86
|
+
logger,
|
|
87
|
+
fetch
|
|
88
|
+
}).catch(error => {
|
|
89
|
+
logger.error("Failed to send tracking call:", error);
|
|
90
|
+
});
|
|
91
|
+
});
|