@blotoutio/providers-spotify-sdk 1.17.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.
- package/README.md +15 -0
- package/index.cjs.js +357 -0
- package/index.d.ts +1 -0
- package/index.js +360 -0
- package/index.mjs +355 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# providers-spotify-sdk
|
|
2
|
+
|
|
3
|
+
This library was generated with [Nx](https://nx.dev).
|
|
4
|
+
|
|
5
|
+
## Building
|
|
6
|
+
|
|
7
|
+
Run `nx build providers-spotify-sdk` to build the library.
|
|
8
|
+
|
|
9
|
+
## Running unit tests
|
|
10
|
+
|
|
11
|
+
Run `nx test providers-spotify-sdk` to execute the unit tests via [Jest](https://jestjs.io).
|
|
12
|
+
|
|
13
|
+
## Running lint
|
|
14
|
+
|
|
15
|
+
Run `nx lint providers-spotify-sdk` to execute the lint via [ESLint](https://eslint.org/).
|
package/index.cjs.js
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const packageName = 'spotify';
|
|
4
|
+
|
|
5
|
+
const init = ({ manifest }) => {
|
|
6
|
+
var _a, _b;
|
|
7
|
+
if (typeof window === 'undefined' ||
|
|
8
|
+
typeof document === 'undefined' ||
|
|
9
|
+
!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.variables) === null || _a === void 0 ? void 0 : _a['spotifyPixelId']) ||
|
|
10
|
+
!(manifest === null || manifest === void 0 ? void 0 : manifest.variables['enableBrowser'])) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const spotifyScriptURL = 'https://pixel.byspotify.com/ping.min.js';
|
|
14
|
+
const scriptId = 'spdt-capture';
|
|
15
|
+
if (!document.getElementById(scriptId)) {
|
|
16
|
+
window.spdt =
|
|
17
|
+
window.spdt ||
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
+
function (...args) {
|
|
20
|
+
(window.spdt.q = window.spdt.q || []).push(args);
|
|
21
|
+
};
|
|
22
|
+
const element = document.createElement('script');
|
|
23
|
+
element.id = scriptId;
|
|
24
|
+
element.async = true;
|
|
25
|
+
element.src = spotifyScriptURL;
|
|
26
|
+
const firstScript = document.getElementsByTagName('script')[0];
|
|
27
|
+
(_b = firstScript === null || firstScript === void 0 ? void 0 : firstScript.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(element, firstScript);
|
|
28
|
+
window.spdt('conf', { key: manifest.variables['spotifyPixelId'] });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const sha = async (algorithm, text) => {
|
|
33
|
+
if (!text) {
|
|
34
|
+
return '';
|
|
35
|
+
}
|
|
36
|
+
const encodedText = new TextEncoder().encode(text);
|
|
37
|
+
const hashBuffer = await crypto.subtle.digest({
|
|
38
|
+
name: algorithm,
|
|
39
|
+
}, encodedText);
|
|
40
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
41
|
+
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
42
|
+
};
|
|
43
|
+
const sha256 = async (text) => {
|
|
44
|
+
return await sha('SHA-256', text);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const user = ({ userId, data }) => {
|
|
48
|
+
if (typeof window === 'undefined' ||
|
|
49
|
+
typeof window.spdt !== 'function' ||
|
|
50
|
+
!data) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const payload = {};
|
|
54
|
+
payload['id'] = userId;
|
|
55
|
+
if (data['email']) {
|
|
56
|
+
sha256(data['email'].toString())
|
|
57
|
+
.then((hashedEmail) => {
|
|
58
|
+
payload['email'] = hashedEmail;
|
|
59
|
+
window.spdt('alias', payload);
|
|
60
|
+
})
|
|
61
|
+
.catch(() => undefined);
|
|
62
|
+
}
|
|
63
|
+
else if (payload['id']) {
|
|
64
|
+
window.spdt('alias', { id: payload['id'] });
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const parseNumericValue = (value) => {
|
|
69
|
+
const parsed = typeof value === 'number' ? value : parseFloat(value);
|
|
70
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const getEventData = (eventName, data, options = {}) => {
|
|
74
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
75
|
+
switch (eventName) {
|
|
76
|
+
case 'Lead': {
|
|
77
|
+
return {
|
|
78
|
+
name: 'lead',
|
|
79
|
+
data: {
|
|
80
|
+
category: data.category,
|
|
81
|
+
currency: data.currency,
|
|
82
|
+
value: data.value,
|
|
83
|
+
type: data.name,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
case 'AddToCart': {
|
|
88
|
+
const parsedValue = parseNumericValue(data.value);
|
|
89
|
+
if (parsedValue === undefined) {
|
|
90
|
+
console.error('addtocart : data.value should be a number');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (typeof data.currency !== 'string') {
|
|
94
|
+
console.error('addtocart : data.currecy should be a string');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const currency = data.currency;
|
|
98
|
+
const items = [];
|
|
99
|
+
for (const item of (_a = data.contents) !== null && _a !== void 0 ? _a : []) {
|
|
100
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
101
|
+
if (parsedItemPrice === undefined) {
|
|
102
|
+
console.error('addtocart : content item_price should be a number');
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
106
|
+
if (parsedItemQuantity === undefined) {
|
|
107
|
+
console.error('addtocart : content quantity should be a number');
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
111
|
+
console.error('addtocart : content id should be a string');
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
items.push({
|
|
115
|
+
value: parsedItemPrice * parsedItemQuantity,
|
|
116
|
+
currency,
|
|
117
|
+
quantity: parsedItemQuantity,
|
|
118
|
+
product_id: item.id,
|
|
119
|
+
product_name: item.title,
|
|
120
|
+
product_type: item.type,
|
|
121
|
+
product_vendor: item.brand,
|
|
122
|
+
variant_id: item.variantId,
|
|
123
|
+
variant_name: item.sku,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
name: 'addtocart',
|
|
128
|
+
data: items,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
case 'ViewContent': {
|
|
132
|
+
if (typeof data.currency !== 'string') {
|
|
133
|
+
console.error('product : data.currency should be a string');
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const items = [];
|
|
137
|
+
for (const item of (_b = data.contents) !== null && _b !== void 0 ? _b : []) {
|
|
138
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
139
|
+
if (parsedItemPrice === undefined) {
|
|
140
|
+
console.error('checkout : content item_price should be a number');
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
144
|
+
if (parsedItemQuantity === undefined) {
|
|
145
|
+
console.error('checkout : content quantity should be a number');
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
149
|
+
console.error('checkout : content id should be a string');
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
items.push({
|
|
153
|
+
value: parsedItemPrice * parsedItemQuantity,
|
|
154
|
+
currency: data.currency,
|
|
155
|
+
product_id: item.id,
|
|
156
|
+
product_name: item.title,
|
|
157
|
+
product_type: item.sku,
|
|
158
|
+
product_vendor: item.brand,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
name: 'product',
|
|
163
|
+
data: items,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
case 'InitiateCheckout': {
|
|
167
|
+
const parsedValue = parseNumericValue(data.value);
|
|
168
|
+
if (parsedValue === undefined) {
|
|
169
|
+
console.error('checkout : data.value should be a number');
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (typeof data.currency !== 'string') {
|
|
173
|
+
console.error('checkout : data.currency should be a string');
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const value = parsedValue;
|
|
177
|
+
const currency = data.currency;
|
|
178
|
+
const discount_code = (_d = (_c = data.discounts) === null || _c === void 0 ? void 0 : _c.map((discount) => discount.code).join(' ,')) !== null && _d !== void 0 ? _d : '';
|
|
179
|
+
const items = [];
|
|
180
|
+
for (const item of (_e = data.contents) !== null && _e !== void 0 ? _e : []) {
|
|
181
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
182
|
+
if (parsedItemPrice === undefined) {
|
|
183
|
+
console.error('checkout : content item_price should be a number');
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
187
|
+
if (parsedItemQuantity === undefined) {
|
|
188
|
+
console.error('checkout : content quantity should be a number');
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
192
|
+
console.error('checkout : content id should be a string');
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
items.push({
|
|
196
|
+
value: parsedItemPrice,
|
|
197
|
+
quantity: parsedItemQuantity,
|
|
198
|
+
product_id: item.id,
|
|
199
|
+
product_name: item.title,
|
|
200
|
+
product_type: item.sku,
|
|
201
|
+
product_vendor: item.brand,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
name: 'checkout',
|
|
206
|
+
data: {
|
|
207
|
+
value,
|
|
208
|
+
currency,
|
|
209
|
+
discount_code,
|
|
210
|
+
line_items: items,
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
case 'Purchase': {
|
|
215
|
+
const { isNewCustomer } = options;
|
|
216
|
+
if (isNewCustomer === undefined) {
|
|
217
|
+
console.error('purchase : isNewCustomer is not defined');
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const parsedValue = parseNumericValue(data.value);
|
|
221
|
+
if (parsedValue === undefined) {
|
|
222
|
+
console.error('purchase : data.value should be a number');
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (typeof data.currency !== 'string') {
|
|
226
|
+
console.error('purchase : data.currency should be a string');
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (typeof data.orderId !== 'string') {
|
|
230
|
+
console.error('purchase : data.orderId should be a string');
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const value = parsedValue;
|
|
234
|
+
const currency = data.currency;
|
|
235
|
+
const order_id = data.orderId;
|
|
236
|
+
const discount_code = (_g = ((_f = data.discounts) !== null && _f !== void 0 ? _f : []).map((discount) => discount.code).join(' ,')) !== null && _g !== void 0 ? _g : '';
|
|
237
|
+
const items = [];
|
|
238
|
+
for (const item of (_h = data.contents) !== null && _h !== void 0 ? _h : []) {
|
|
239
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
240
|
+
if (parsedItemPrice === undefined) {
|
|
241
|
+
console.error('purchase : content item_price should be a number');
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
245
|
+
if (parsedItemQuantity === undefined) {
|
|
246
|
+
console.error('purchase : content quantity should be a number');
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
250
|
+
console.error('purchase : content id should be a string');
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
items.push({
|
|
254
|
+
value: parsedItemPrice,
|
|
255
|
+
quantity: parsedItemQuantity,
|
|
256
|
+
product_id: item.id,
|
|
257
|
+
product_name: item.title,
|
|
258
|
+
product_type: item.type,
|
|
259
|
+
product_vendor: item.brand,
|
|
260
|
+
variant_id: item.variantId,
|
|
261
|
+
variant_name: item.sku,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
const quantity = items.reduce((sum, item) => sum + item.quantity, 0);
|
|
265
|
+
return {
|
|
266
|
+
name: 'purchase',
|
|
267
|
+
data: {
|
|
268
|
+
value,
|
|
269
|
+
currency,
|
|
270
|
+
order_id,
|
|
271
|
+
discount_code,
|
|
272
|
+
quantity,
|
|
273
|
+
line_items: items,
|
|
274
|
+
is_new_customer: isNewCustomer,
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
case 'PageView': {
|
|
279
|
+
return {
|
|
280
|
+
name: 'view',
|
|
281
|
+
data: {},
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return;
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const isNewCustomer = async (getData) => {
|
|
289
|
+
const edgeData = await new Promise((resolve) => getData(['is_new_customer'], resolve));
|
|
290
|
+
/*
|
|
291
|
+
if we are getting undefined value for is_new_customer
|
|
292
|
+
from the custom table, we should send is_new_customer as true
|
|
293
|
+
to spotify.
|
|
294
|
+
*/
|
|
295
|
+
return (edgeData['is_new_customer'] === undefined ||
|
|
296
|
+
edgeData['is_new_customer'] === 'true');
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const handleTag = async ({ data, eventName, getEdgeData, }) => {
|
|
300
|
+
var _a, _b, _c;
|
|
301
|
+
if (!eventName || !data || !getEdgeData) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
let options = {};
|
|
305
|
+
if (eventName === 'Purchase') {
|
|
306
|
+
const is_new_customer = await isNewCustomer(getEdgeData);
|
|
307
|
+
options = { isNewCustomer: is_new_customer };
|
|
308
|
+
}
|
|
309
|
+
const event = getEventData(eventName, data, options);
|
|
310
|
+
if (event) {
|
|
311
|
+
const { name, data } = event;
|
|
312
|
+
if (data && Array.isArray(data)) {
|
|
313
|
+
if (data.length === 0) {
|
|
314
|
+
(_a = window.spdt) === null || _a === void 0 ? void 0 : _a.call(window, name, []);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
for (const item of data) {
|
|
318
|
+
(_b = window.spdt) === null || _b === void 0 ? void 0 : _b.call(window, name, item);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
(_c = window.spdt) === null || _c === void 0 ? void 0 : _c.call(window, name, data);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const tag = ({ data, eventName, getEdgeData }) => {
|
|
329
|
+
const payload = {
|
|
330
|
+
sdkVersion: "1.17.0" ,
|
|
331
|
+
};
|
|
332
|
+
if (typeof window !== 'undefined' && typeof window.spdt === 'function') {
|
|
333
|
+
handleTag({ data, eventName, getEdgeData });
|
|
334
|
+
}
|
|
335
|
+
return payload;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
// eslint-disable-next-line @nx/enforce-module-boundaries
|
|
339
|
+
const data = {
|
|
340
|
+
name: packageName,
|
|
341
|
+
init,
|
|
342
|
+
user,
|
|
343
|
+
tag,
|
|
344
|
+
};
|
|
345
|
+
try {
|
|
346
|
+
if (window) {
|
|
347
|
+
if (!window.edgetagProviders) {
|
|
348
|
+
window.edgetagProviders = [];
|
|
349
|
+
}
|
|
350
|
+
window.edgetagProviders.push(data);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
catch {
|
|
354
|
+
// No window
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
module.exports = data;
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '@blotoutio/providers-spotify-sdk'
|
package/index.js
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
var ProvidersSpotifySdk = (function () {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const packageName = 'spotify';
|
|
5
|
+
|
|
6
|
+
const init = ({ manifest }) => {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
if (typeof window === 'undefined' ||
|
|
9
|
+
typeof document === 'undefined' ||
|
|
10
|
+
!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.variables) === null || _a === void 0 ? void 0 : _a['spotifyPixelId']) ||
|
|
11
|
+
!(manifest === null || manifest === void 0 ? void 0 : manifest.variables['enableBrowser'])) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const spotifyScriptURL = 'https://pixel.byspotify.com/ping.min.js';
|
|
15
|
+
const scriptId = 'spdt-capture';
|
|
16
|
+
if (!document.getElementById(scriptId)) {
|
|
17
|
+
window.spdt =
|
|
18
|
+
window.spdt ||
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
+
function (...args) {
|
|
21
|
+
(window.spdt.q = window.spdt.q || []).push(args);
|
|
22
|
+
};
|
|
23
|
+
const element = document.createElement('script');
|
|
24
|
+
element.id = scriptId;
|
|
25
|
+
element.async = true;
|
|
26
|
+
element.src = spotifyScriptURL;
|
|
27
|
+
const firstScript = document.getElementsByTagName('script')[0];
|
|
28
|
+
(_b = firstScript === null || firstScript === void 0 ? void 0 : firstScript.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(element, firstScript);
|
|
29
|
+
window.spdt('conf', { key: manifest.variables['spotifyPixelId'] });
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const sha = async (algorithm, text) => {
|
|
34
|
+
if (!text) {
|
|
35
|
+
return '';
|
|
36
|
+
}
|
|
37
|
+
const encodedText = new TextEncoder().encode(text);
|
|
38
|
+
const hashBuffer = await crypto.subtle.digest({
|
|
39
|
+
name: algorithm,
|
|
40
|
+
}, encodedText);
|
|
41
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
42
|
+
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
43
|
+
};
|
|
44
|
+
const sha256 = async (text) => {
|
|
45
|
+
return await sha('SHA-256', text);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const user = ({ userId, data }) => {
|
|
49
|
+
if (typeof window === 'undefined' ||
|
|
50
|
+
typeof window.spdt !== 'function' ||
|
|
51
|
+
!data) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const payload = {};
|
|
55
|
+
payload['id'] = userId;
|
|
56
|
+
if (data['email']) {
|
|
57
|
+
sha256(data['email'].toString())
|
|
58
|
+
.then((hashedEmail) => {
|
|
59
|
+
payload['email'] = hashedEmail;
|
|
60
|
+
window.spdt('alias', payload);
|
|
61
|
+
})
|
|
62
|
+
.catch(() => undefined);
|
|
63
|
+
}
|
|
64
|
+
else if (payload['id']) {
|
|
65
|
+
window.spdt('alias', { id: payload['id'] });
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const parseNumericValue = (value) => {
|
|
70
|
+
const parsed = typeof value === 'number' ? value : parseFloat(value);
|
|
71
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const getEventData = (eventName, data, options = {}) => {
|
|
75
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
76
|
+
switch (eventName) {
|
|
77
|
+
case 'Lead': {
|
|
78
|
+
return {
|
|
79
|
+
name: 'lead',
|
|
80
|
+
data: {
|
|
81
|
+
category: data.category,
|
|
82
|
+
currency: data.currency,
|
|
83
|
+
value: data.value,
|
|
84
|
+
type: data.name,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
case 'AddToCart': {
|
|
89
|
+
const parsedValue = parseNumericValue(data.value);
|
|
90
|
+
if (parsedValue === undefined) {
|
|
91
|
+
console.error('addtocart : data.value should be a number');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (typeof data.currency !== 'string') {
|
|
95
|
+
console.error('addtocart : data.currecy should be a string');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const currency = data.currency;
|
|
99
|
+
const items = [];
|
|
100
|
+
for (const item of (_a = data.contents) !== null && _a !== void 0 ? _a : []) {
|
|
101
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
102
|
+
if (parsedItemPrice === undefined) {
|
|
103
|
+
console.error('addtocart : content item_price should be a number');
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
107
|
+
if (parsedItemQuantity === undefined) {
|
|
108
|
+
console.error('addtocart : content quantity should be a number');
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
112
|
+
console.error('addtocart : content id should be a string');
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
items.push({
|
|
116
|
+
value: parsedItemPrice * parsedItemQuantity,
|
|
117
|
+
currency,
|
|
118
|
+
quantity: parsedItemQuantity,
|
|
119
|
+
product_id: item.id,
|
|
120
|
+
product_name: item.title,
|
|
121
|
+
product_type: item.type,
|
|
122
|
+
product_vendor: item.brand,
|
|
123
|
+
variant_id: item.variantId,
|
|
124
|
+
variant_name: item.sku,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
name: 'addtocart',
|
|
129
|
+
data: items,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
case 'ViewContent': {
|
|
133
|
+
if (typeof data.currency !== 'string') {
|
|
134
|
+
console.error('product : data.currency should be a string');
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const items = [];
|
|
138
|
+
for (const item of (_b = data.contents) !== null && _b !== void 0 ? _b : []) {
|
|
139
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
140
|
+
if (parsedItemPrice === undefined) {
|
|
141
|
+
console.error('checkout : content item_price should be a number');
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
145
|
+
if (parsedItemQuantity === undefined) {
|
|
146
|
+
console.error('checkout : content quantity should be a number');
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
150
|
+
console.error('checkout : content id should be a string');
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
items.push({
|
|
154
|
+
value: parsedItemPrice * parsedItemQuantity,
|
|
155
|
+
currency: data.currency,
|
|
156
|
+
product_id: item.id,
|
|
157
|
+
product_name: item.title,
|
|
158
|
+
product_type: item.sku,
|
|
159
|
+
product_vendor: item.brand,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
name: 'product',
|
|
164
|
+
data: items,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
case 'InitiateCheckout': {
|
|
168
|
+
const parsedValue = parseNumericValue(data.value);
|
|
169
|
+
if (parsedValue === undefined) {
|
|
170
|
+
console.error('checkout : data.value should be a number');
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (typeof data.currency !== 'string') {
|
|
174
|
+
console.error('checkout : data.currency should be a string');
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const value = parsedValue;
|
|
178
|
+
const currency = data.currency;
|
|
179
|
+
const discount_code = (_d = (_c = data.discounts) === null || _c === void 0 ? void 0 : _c.map((discount) => discount.code).join(' ,')) !== null && _d !== void 0 ? _d : '';
|
|
180
|
+
const items = [];
|
|
181
|
+
for (const item of (_e = data.contents) !== null && _e !== void 0 ? _e : []) {
|
|
182
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
183
|
+
if (parsedItemPrice === undefined) {
|
|
184
|
+
console.error('checkout : content item_price should be a number');
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
188
|
+
if (parsedItemQuantity === undefined) {
|
|
189
|
+
console.error('checkout : content quantity should be a number');
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
193
|
+
console.error('checkout : content id should be a string');
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
items.push({
|
|
197
|
+
value: parsedItemPrice,
|
|
198
|
+
quantity: parsedItemQuantity,
|
|
199
|
+
product_id: item.id,
|
|
200
|
+
product_name: item.title,
|
|
201
|
+
product_type: item.sku,
|
|
202
|
+
product_vendor: item.brand,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
name: 'checkout',
|
|
207
|
+
data: {
|
|
208
|
+
value,
|
|
209
|
+
currency,
|
|
210
|
+
discount_code,
|
|
211
|
+
line_items: items,
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
case 'Purchase': {
|
|
216
|
+
const { isNewCustomer } = options;
|
|
217
|
+
if (isNewCustomer === undefined) {
|
|
218
|
+
console.error('purchase : isNewCustomer is not defined');
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const parsedValue = parseNumericValue(data.value);
|
|
222
|
+
if (parsedValue === undefined) {
|
|
223
|
+
console.error('purchase : data.value should be a number');
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (typeof data.currency !== 'string') {
|
|
227
|
+
console.error('purchase : data.currency should be a string');
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (typeof data.orderId !== 'string') {
|
|
231
|
+
console.error('purchase : data.orderId should be a string');
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const value = parsedValue;
|
|
235
|
+
const currency = data.currency;
|
|
236
|
+
const order_id = data.orderId;
|
|
237
|
+
const discount_code = (_g = ((_f = data.discounts) !== null && _f !== void 0 ? _f : []).map((discount) => discount.code).join(' ,')) !== null && _g !== void 0 ? _g : '';
|
|
238
|
+
const items = [];
|
|
239
|
+
for (const item of (_h = data.contents) !== null && _h !== void 0 ? _h : []) {
|
|
240
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
241
|
+
if (parsedItemPrice === undefined) {
|
|
242
|
+
console.error('purchase : content item_price should be a number');
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
246
|
+
if (parsedItemQuantity === undefined) {
|
|
247
|
+
console.error('purchase : content quantity should be a number');
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
251
|
+
console.error('purchase : content id should be a string');
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
items.push({
|
|
255
|
+
value: parsedItemPrice,
|
|
256
|
+
quantity: parsedItemQuantity,
|
|
257
|
+
product_id: item.id,
|
|
258
|
+
product_name: item.title,
|
|
259
|
+
product_type: item.type,
|
|
260
|
+
product_vendor: item.brand,
|
|
261
|
+
variant_id: item.variantId,
|
|
262
|
+
variant_name: item.sku,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
const quantity = items.reduce((sum, item) => sum + item.quantity, 0);
|
|
266
|
+
return {
|
|
267
|
+
name: 'purchase',
|
|
268
|
+
data: {
|
|
269
|
+
value,
|
|
270
|
+
currency,
|
|
271
|
+
order_id,
|
|
272
|
+
discount_code,
|
|
273
|
+
quantity,
|
|
274
|
+
line_items: items,
|
|
275
|
+
is_new_customer: isNewCustomer,
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
case 'PageView': {
|
|
280
|
+
return {
|
|
281
|
+
name: 'view',
|
|
282
|
+
data: {},
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const isNewCustomer = async (getData) => {
|
|
290
|
+
const edgeData = await new Promise((resolve) => getData(['is_new_customer'], resolve));
|
|
291
|
+
/*
|
|
292
|
+
if we are getting undefined value for is_new_customer
|
|
293
|
+
from the custom table, we should send is_new_customer as true
|
|
294
|
+
to spotify.
|
|
295
|
+
*/
|
|
296
|
+
return (edgeData['is_new_customer'] === undefined ||
|
|
297
|
+
edgeData['is_new_customer'] === 'true');
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const handleTag = async ({ data, eventName, getEdgeData, }) => {
|
|
301
|
+
var _a, _b, _c;
|
|
302
|
+
if (!eventName || !data || !getEdgeData) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
let options = {};
|
|
306
|
+
if (eventName === 'Purchase') {
|
|
307
|
+
const is_new_customer = await isNewCustomer(getEdgeData);
|
|
308
|
+
options = { isNewCustomer: is_new_customer };
|
|
309
|
+
}
|
|
310
|
+
const event = getEventData(eventName, data, options);
|
|
311
|
+
if (event) {
|
|
312
|
+
const { name, data } = event;
|
|
313
|
+
if (data && Array.isArray(data)) {
|
|
314
|
+
if (data.length === 0) {
|
|
315
|
+
(_a = window.spdt) === null || _a === void 0 ? void 0 : _a.call(window, name, []);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
for (const item of data) {
|
|
319
|
+
(_b = window.spdt) === null || _b === void 0 ? void 0 : _b.call(window, name, item);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
(_c = window.spdt) === null || _c === void 0 ? void 0 : _c.call(window, name, data);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const tag = ({ data, eventName, getEdgeData }) => {
|
|
330
|
+
const payload = {
|
|
331
|
+
sdkVersion: "1.17.0" ,
|
|
332
|
+
};
|
|
333
|
+
if (typeof window !== 'undefined' && typeof window.spdt === 'function') {
|
|
334
|
+
handleTag({ data, eventName, getEdgeData });
|
|
335
|
+
}
|
|
336
|
+
return payload;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
// eslint-disable-next-line @nx/enforce-module-boundaries
|
|
340
|
+
const data = {
|
|
341
|
+
name: packageName,
|
|
342
|
+
init,
|
|
343
|
+
user,
|
|
344
|
+
tag,
|
|
345
|
+
};
|
|
346
|
+
try {
|
|
347
|
+
if (window) {
|
|
348
|
+
if (!window.edgetagProviders) {
|
|
349
|
+
window.edgetagProviders = [];
|
|
350
|
+
}
|
|
351
|
+
window.edgetagProviders.push(data);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
catch {
|
|
355
|
+
// No window
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return data;
|
|
359
|
+
|
|
360
|
+
})();
|
package/index.mjs
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
const packageName = 'spotify';
|
|
2
|
+
|
|
3
|
+
const init = ({ manifest }) => {
|
|
4
|
+
var _a, _b;
|
|
5
|
+
if (typeof window === 'undefined' ||
|
|
6
|
+
typeof document === 'undefined' ||
|
|
7
|
+
!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.variables) === null || _a === void 0 ? void 0 : _a['spotifyPixelId']) ||
|
|
8
|
+
!(manifest === null || manifest === void 0 ? void 0 : manifest.variables['enableBrowser'])) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const spotifyScriptURL = 'https://pixel.byspotify.com/ping.min.js';
|
|
12
|
+
const scriptId = 'spdt-capture';
|
|
13
|
+
if (!document.getElementById(scriptId)) {
|
|
14
|
+
window.spdt =
|
|
15
|
+
window.spdt ||
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
function (...args) {
|
|
18
|
+
(window.spdt.q = window.spdt.q || []).push(args);
|
|
19
|
+
};
|
|
20
|
+
const element = document.createElement('script');
|
|
21
|
+
element.id = scriptId;
|
|
22
|
+
element.async = true;
|
|
23
|
+
element.src = spotifyScriptURL;
|
|
24
|
+
const firstScript = document.getElementsByTagName('script')[0];
|
|
25
|
+
(_b = firstScript === null || firstScript === void 0 ? void 0 : firstScript.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(element, firstScript);
|
|
26
|
+
window.spdt('conf', { key: manifest.variables['spotifyPixelId'] });
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const sha = async (algorithm, text) => {
|
|
31
|
+
if (!text) {
|
|
32
|
+
return '';
|
|
33
|
+
}
|
|
34
|
+
const encodedText = new TextEncoder().encode(text);
|
|
35
|
+
const hashBuffer = await crypto.subtle.digest({
|
|
36
|
+
name: algorithm,
|
|
37
|
+
}, encodedText);
|
|
38
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
39
|
+
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
40
|
+
};
|
|
41
|
+
const sha256 = async (text) => {
|
|
42
|
+
return await sha('SHA-256', text);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const user = ({ userId, data }) => {
|
|
46
|
+
if (typeof window === 'undefined' ||
|
|
47
|
+
typeof window.spdt !== 'function' ||
|
|
48
|
+
!data) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const payload = {};
|
|
52
|
+
payload['id'] = userId;
|
|
53
|
+
if (data['email']) {
|
|
54
|
+
sha256(data['email'].toString())
|
|
55
|
+
.then((hashedEmail) => {
|
|
56
|
+
payload['email'] = hashedEmail;
|
|
57
|
+
window.spdt('alias', payload);
|
|
58
|
+
})
|
|
59
|
+
.catch(() => undefined);
|
|
60
|
+
}
|
|
61
|
+
else if (payload['id']) {
|
|
62
|
+
window.spdt('alias', { id: payload['id'] });
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const parseNumericValue = (value) => {
|
|
67
|
+
const parsed = typeof value === 'number' ? value : parseFloat(value);
|
|
68
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const getEventData = (eventName, data, options = {}) => {
|
|
72
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
73
|
+
switch (eventName) {
|
|
74
|
+
case 'Lead': {
|
|
75
|
+
return {
|
|
76
|
+
name: 'lead',
|
|
77
|
+
data: {
|
|
78
|
+
category: data.category,
|
|
79
|
+
currency: data.currency,
|
|
80
|
+
value: data.value,
|
|
81
|
+
type: data.name,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
case 'AddToCart': {
|
|
86
|
+
const parsedValue = parseNumericValue(data.value);
|
|
87
|
+
if (parsedValue === undefined) {
|
|
88
|
+
console.error('addtocart : data.value should be a number');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (typeof data.currency !== 'string') {
|
|
92
|
+
console.error('addtocart : data.currecy should be a string');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const currency = data.currency;
|
|
96
|
+
const items = [];
|
|
97
|
+
for (const item of (_a = data.contents) !== null && _a !== void 0 ? _a : []) {
|
|
98
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
99
|
+
if (parsedItemPrice === undefined) {
|
|
100
|
+
console.error('addtocart : content item_price should be a number');
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
104
|
+
if (parsedItemQuantity === undefined) {
|
|
105
|
+
console.error('addtocart : content quantity should be a number');
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
109
|
+
console.error('addtocart : content id should be a string');
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
items.push({
|
|
113
|
+
value: parsedItemPrice * parsedItemQuantity,
|
|
114
|
+
currency,
|
|
115
|
+
quantity: parsedItemQuantity,
|
|
116
|
+
product_id: item.id,
|
|
117
|
+
product_name: item.title,
|
|
118
|
+
product_type: item.type,
|
|
119
|
+
product_vendor: item.brand,
|
|
120
|
+
variant_id: item.variantId,
|
|
121
|
+
variant_name: item.sku,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
name: 'addtocart',
|
|
126
|
+
data: items,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
case 'ViewContent': {
|
|
130
|
+
if (typeof data.currency !== 'string') {
|
|
131
|
+
console.error('product : data.currency should be a string');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const items = [];
|
|
135
|
+
for (const item of (_b = data.contents) !== null && _b !== void 0 ? _b : []) {
|
|
136
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
137
|
+
if (parsedItemPrice === undefined) {
|
|
138
|
+
console.error('checkout : content item_price should be a number');
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
142
|
+
if (parsedItemQuantity === undefined) {
|
|
143
|
+
console.error('checkout : content quantity should be a number');
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
147
|
+
console.error('checkout : content id should be a string');
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
items.push({
|
|
151
|
+
value: parsedItemPrice * parsedItemQuantity,
|
|
152
|
+
currency: data.currency,
|
|
153
|
+
product_id: item.id,
|
|
154
|
+
product_name: item.title,
|
|
155
|
+
product_type: item.sku,
|
|
156
|
+
product_vendor: item.brand,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
name: 'product',
|
|
161
|
+
data: items,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
case 'InitiateCheckout': {
|
|
165
|
+
const parsedValue = parseNumericValue(data.value);
|
|
166
|
+
if (parsedValue === undefined) {
|
|
167
|
+
console.error('checkout : data.value should be a number');
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (typeof data.currency !== 'string') {
|
|
171
|
+
console.error('checkout : data.currency should be a string');
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const value = parsedValue;
|
|
175
|
+
const currency = data.currency;
|
|
176
|
+
const discount_code = (_d = (_c = data.discounts) === null || _c === void 0 ? void 0 : _c.map((discount) => discount.code).join(' ,')) !== null && _d !== void 0 ? _d : '';
|
|
177
|
+
const items = [];
|
|
178
|
+
for (const item of (_e = data.contents) !== null && _e !== void 0 ? _e : []) {
|
|
179
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
180
|
+
if (parsedItemPrice === undefined) {
|
|
181
|
+
console.error('checkout : content item_price should be a number');
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
185
|
+
if (parsedItemQuantity === undefined) {
|
|
186
|
+
console.error('checkout : content quantity should be a number');
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
190
|
+
console.error('checkout : content id should be a string');
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
items.push({
|
|
194
|
+
value: parsedItemPrice,
|
|
195
|
+
quantity: parsedItemQuantity,
|
|
196
|
+
product_id: item.id,
|
|
197
|
+
product_name: item.title,
|
|
198
|
+
product_type: item.sku,
|
|
199
|
+
product_vendor: item.brand,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
name: 'checkout',
|
|
204
|
+
data: {
|
|
205
|
+
value,
|
|
206
|
+
currency,
|
|
207
|
+
discount_code,
|
|
208
|
+
line_items: items,
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
case 'Purchase': {
|
|
213
|
+
const { isNewCustomer } = options;
|
|
214
|
+
if (isNewCustomer === undefined) {
|
|
215
|
+
console.error('purchase : isNewCustomer is not defined');
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const parsedValue = parseNumericValue(data.value);
|
|
219
|
+
if (parsedValue === undefined) {
|
|
220
|
+
console.error('purchase : data.value should be a number');
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (typeof data.currency !== 'string') {
|
|
224
|
+
console.error('purchase : data.currency should be a string');
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (typeof data.orderId !== 'string') {
|
|
228
|
+
console.error('purchase : data.orderId should be a string');
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const value = parsedValue;
|
|
232
|
+
const currency = data.currency;
|
|
233
|
+
const order_id = data.orderId;
|
|
234
|
+
const discount_code = (_g = ((_f = data.discounts) !== null && _f !== void 0 ? _f : []).map((discount) => discount.code).join(' ,')) !== null && _g !== void 0 ? _g : '';
|
|
235
|
+
const items = [];
|
|
236
|
+
for (const item of (_h = data.contents) !== null && _h !== void 0 ? _h : []) {
|
|
237
|
+
const parsedItemPrice = parseNumericValue(item === null || item === void 0 ? void 0 : item.item_price);
|
|
238
|
+
if (parsedItemPrice === undefined) {
|
|
239
|
+
console.error('purchase : content item_price should be a number');
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const parsedItemQuantity = parseNumericValue(item === null || item === void 0 ? void 0 : item.quantity);
|
|
243
|
+
if (parsedItemQuantity === undefined) {
|
|
244
|
+
console.error('purchase : content quantity should be a number');
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (typeof (item === null || item === void 0 ? void 0 : item.id) !== 'string') {
|
|
248
|
+
console.error('purchase : content id should be a string');
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
items.push({
|
|
252
|
+
value: parsedItemPrice,
|
|
253
|
+
quantity: parsedItemQuantity,
|
|
254
|
+
product_id: item.id,
|
|
255
|
+
product_name: item.title,
|
|
256
|
+
product_type: item.type,
|
|
257
|
+
product_vendor: item.brand,
|
|
258
|
+
variant_id: item.variantId,
|
|
259
|
+
variant_name: item.sku,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
const quantity = items.reduce((sum, item) => sum + item.quantity, 0);
|
|
263
|
+
return {
|
|
264
|
+
name: 'purchase',
|
|
265
|
+
data: {
|
|
266
|
+
value,
|
|
267
|
+
currency,
|
|
268
|
+
order_id,
|
|
269
|
+
discount_code,
|
|
270
|
+
quantity,
|
|
271
|
+
line_items: items,
|
|
272
|
+
is_new_customer: isNewCustomer,
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
case 'PageView': {
|
|
277
|
+
return {
|
|
278
|
+
name: 'view',
|
|
279
|
+
data: {},
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const isNewCustomer = async (getData) => {
|
|
287
|
+
const edgeData = await new Promise((resolve) => getData(['is_new_customer'], resolve));
|
|
288
|
+
/*
|
|
289
|
+
if we are getting undefined value for is_new_customer
|
|
290
|
+
from the custom table, we should send is_new_customer as true
|
|
291
|
+
to spotify.
|
|
292
|
+
*/
|
|
293
|
+
return (edgeData['is_new_customer'] === undefined ||
|
|
294
|
+
edgeData['is_new_customer'] === 'true');
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
const handleTag = async ({ data, eventName, getEdgeData, }) => {
|
|
298
|
+
var _a, _b, _c;
|
|
299
|
+
if (!eventName || !data || !getEdgeData) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
let options = {};
|
|
303
|
+
if (eventName === 'Purchase') {
|
|
304
|
+
const is_new_customer = await isNewCustomer(getEdgeData);
|
|
305
|
+
options = { isNewCustomer: is_new_customer };
|
|
306
|
+
}
|
|
307
|
+
const event = getEventData(eventName, data, options);
|
|
308
|
+
if (event) {
|
|
309
|
+
const { name, data } = event;
|
|
310
|
+
if (data && Array.isArray(data)) {
|
|
311
|
+
if (data.length === 0) {
|
|
312
|
+
(_a = window.spdt) === null || _a === void 0 ? void 0 : _a.call(window, name, []);
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
for (const item of data) {
|
|
316
|
+
(_b = window.spdt) === null || _b === void 0 ? void 0 : _b.call(window, name, item);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
(_c = window.spdt) === null || _c === void 0 ? void 0 : _c.call(window, name, data);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
const tag = ({ data, eventName, getEdgeData }) => {
|
|
327
|
+
const payload = {
|
|
328
|
+
sdkVersion: "1.17.0" ,
|
|
329
|
+
};
|
|
330
|
+
if (typeof window !== 'undefined' && typeof window.spdt === 'function') {
|
|
331
|
+
handleTag({ data, eventName, getEdgeData });
|
|
332
|
+
}
|
|
333
|
+
return payload;
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// eslint-disable-next-line @nx/enforce-module-boundaries
|
|
337
|
+
const data = {
|
|
338
|
+
name: packageName,
|
|
339
|
+
init,
|
|
340
|
+
user,
|
|
341
|
+
tag,
|
|
342
|
+
};
|
|
343
|
+
try {
|
|
344
|
+
if (window) {
|
|
345
|
+
if (!window.edgetagProviders) {
|
|
346
|
+
window.edgetagProviders = [];
|
|
347
|
+
}
|
|
348
|
+
window.edgetagProviders.push(data);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
// No window
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export { data as default };
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blotoutio/providers-spotify-sdk",
|
|
3
|
+
"version": "1.17.0",
|
|
4
|
+
"description": "Spotify Browser SDK for EdgeTag",
|
|
5
|
+
"author": "Blotout",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://github.com/blotoutio/edgetag-sdk",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"main": "./index.cjs.js",
|
|
12
|
+
"module": "./index.mjs",
|
|
13
|
+
"types": "./index.d.ts",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/blotoutio/edgetag-sdk.git"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"index.js",
|
|
20
|
+
"index.d.ts",
|
|
21
|
+
"index.cjs.js",
|
|
22
|
+
"index.mjs",
|
|
23
|
+
"package.json",
|
|
24
|
+
"README.md"
|
|
25
|
+
]
|
|
26
|
+
}
|