choreograph-create-pixel 1.2.0 β 1.3.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/README.md +52 -45
- package/dist/bundle.cjs.js +21 -20
- package/dist/bundle.esm.js +21 -20
- package/dist/bundle.iife.min.js +2 -2
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -4,26 +4,32 @@ This library lets you apply best practises to [Create](https://www.lemonpi.io/)
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- [x] Supports
|
|
8
|
-
- [x] Supports
|
|
9
|
-
- [x]
|
|
7
|
+
- [x] Supports [scraper](#scraper-pixels), [segment](#segment-pixels) and [conversion](#conversion-pixels) (coming soon) pixels
|
|
8
|
+
- [x] Supports dynamic page content updates
|
|
9
|
+
- [x] Prevents scraping browser-translated content
|
|
10
10
|
- [x] Continuous URL validation
|
|
11
|
-
- [x]
|
|
12
|
-
- [x] Console debugger
|
|
11
|
+
- [x] User interaction triggers
|
|
12
|
+
- [x] [Console debugger](#debugging)
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
### Scraper pixels
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
<small>Type: `scraper`</small>
|
|
17
17
|
|
|
18
|
-
Scraper pixels are used to scrape (read) data from websites, and store
|
|
18
|
+
Scraper pixels are used to scrape (read) data from websites, and store that data as products within an advertiser's product store.
|
|
19
19
|
|
|
20
|
-
###
|
|
20
|
+
### Segment pixels
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
<small>Types: `viewed`, `basketed` and `purchased`</small>
|
|
23
|
+
|
|
24
|
+
Products in ads are shown by recommendation. Segment pixels determine this recommendation on a consumer level, by storing a **cookie** at different moments or events during the consumer's journey.
|
|
25
|
+
|
|
26
|
+
### Conversion pixels
|
|
27
|
+
|
|
28
|
+
_(coming soon)_
|
|
23
29
|
|
|
24
30
|
## Quickstart
|
|
25
31
|
|
|
26
|
-
The following snippet
|
|
32
|
+
The following theoretical snippet includes all pixel types, can be embedded on every page of _example.com_, and will automatically determine which pixel to enable and disable through continuous URL validation.
|
|
27
33
|
|
|
28
34
|
### ES module
|
|
29
35
|
|
|
@@ -35,9 +41,10 @@ new Pixel({
|
|
|
35
41
|
advertiser: 0,
|
|
36
42
|
type: "scraper",
|
|
37
43
|
|
|
38
|
-
// Where should this pixel be enabled?
|
|
44
|
+
// Where on the website should this pixel be enabled?
|
|
39
45
|
url: /example\.com\/products\/\d/,
|
|
40
46
|
|
|
47
|
+
// Functions here are continuously being evaluated for value changes
|
|
41
48
|
scrape: {
|
|
42
49
|
// Data layer example
|
|
43
50
|
sku: () => window.dataLayer[0].product.sku,
|
|
@@ -66,13 +73,13 @@ new Pixel({
|
|
|
66
73
|
type: "basketed",
|
|
67
74
|
url: /example\.com/,
|
|
68
75
|
|
|
69
|
-
// [Optional]
|
|
70
|
-
|
|
76
|
+
// [Optional] Trigger by DOM events, rather than scrape content updates
|
|
77
|
+
trigger: {
|
|
71
78
|
event: "click",
|
|
72
|
-
elements:
|
|
79
|
+
elements: "button.basket[data-sku]",
|
|
73
80
|
},
|
|
74
81
|
|
|
75
|
-
// The "element" parameter
|
|
82
|
+
// The "element" parameter only becomes available when using a trigger
|
|
76
83
|
scrape: (element) => element.getAttribute("data-sku"),
|
|
77
84
|
});
|
|
78
85
|
|
|
@@ -82,9 +89,9 @@ new Pixel({
|
|
|
82
89
|
type: "purchased",
|
|
83
90
|
url: /example\.com\/cart/,
|
|
84
91
|
|
|
85
|
-
|
|
92
|
+
trigger: {
|
|
86
93
|
event: "click",
|
|
87
|
-
elements:
|
|
94
|
+
elements: "button.checkout",
|
|
88
95
|
},
|
|
89
96
|
|
|
90
97
|
// Segment pixels support multiple SKUs
|
|
@@ -92,11 +99,11 @@ new Pixel({
|
|
|
92
99
|
});
|
|
93
100
|
```
|
|
94
101
|
|
|
95
|
-
> ES modules require manual bundling and transpiling before they can be safely
|
|
102
|
+
> ES modules require manual bundling and transpiling before they can be safely embedded on websites.
|
|
96
103
|
|
|
97
104
|
### CDN library
|
|
98
105
|
|
|
99
|
-
This implementation method allows for
|
|
106
|
+
This alternative implementation method allows for direct embedding on pages without the need for bundling nor transpiling.
|
|
100
107
|
|
|
101
108
|
```html
|
|
102
109
|
<script src="https://cdn.jsdelivr.net/npm/choreograph-create-pixel@1"></script>
|
|
@@ -117,43 +124,43 @@ Enable browser console debugging by adding `?pixel_debug` or `#pixel_debug` to t
|
|
|
117
124
|
|
|
118
125
|
## Configuration
|
|
119
126
|
|
|
120
|
-
| Property | Type | Description | Default
|
|
121
|
-
| ------------------------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
122
|
-
| `advertiser` | Number | You can retrieve the advertiser ID from the URL in Create: _manage.lemonpi.io/r/AGENCY_ID/advertiser/`ADVERTISER_ID`_. | _Required_
|
|
123
|
-
| `type` | String | Pixel type. One of: `"scraper"`, `"viewed"`, `"basketed"` or `"purchased"`. | _Required_
|
|
124
|
-
| `url` | RegExp | Only enables the pixel on page URLs that are matched by this pattern. | _Required_
|
|
125
|
-
| `scrape`<br>_(segments only)_ | String, Array or Function | Scrapes the product's SKU for segments. | _Required_
|
|
126
|
-
| `scrape.*`<br>_(scrapers only)_ | String, Number, Boolean or Function | Scrapes arbitrary product data. `*` should always match with existing field names in the advertiser's product store. | _Required_
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `optional`<br>_(scrapers only)_ | Array | An array of field names (as used in `scrape.*`) that are allowed to have empty values. | `[]`
|
|
131
|
-
| `before` | Function | A custom function that's executed just before the pixel is executed. | `(
|
|
132
|
-
| `after` | Function | A custom function that's executed just after the pixel has been executed. | `(
|
|
127
|
+
| Property | Type | Description | Default |
|
|
128
|
+
| ------------------------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
|
|
129
|
+
| `advertiser` | Number | You can retrieve the advertiser ID from the URL in Create: _manage.lemonpi.io/r/AGENCY_ID/advertiser/`ADVERTISER_ID`_. | _Required_ |
|
|
130
|
+
| `type` | String | Pixel type. One of: `"scraper"`, `"viewed"`, `"basketed"` or `"purchased"`. | _Required_ |
|
|
131
|
+
| `url` | RegExp | Only enables the pixel on page URLs that are matched by this pattern. | _Required_ |
|
|
132
|
+
| `scrape`<br>_(segments only)_ | String, Array or Function | Scrapes the product's SKU for segments. | _Required_ |
|
|
133
|
+
| `scrape.*`<br>_(scrapers only)_ | String, Number, Boolean or Function | Scrapes arbitrary product data. `*` should always match with existing field names in the advertiser's product store. | _Required_ |
|
|
134
|
+
| `trigger` | Object | Adds an event listener to enable the pixel only on a specific DOM event, instead of on scrape content updates. | `undefined` |
|
|
135
|
+
| `trigger.event` | String | DOM event type. [List of supported values.](https://www.w3schools.com/jsref/dom_obj_event.asp) | _Required_ |
|
|
136
|
+
| `trigger.elements` | String, Function | This query selector string, or function returning DOM element(s), is used to apply the event listener to. | _Required_ |
|
|
137
|
+
| `optional`<br>_(scrapers only)_ | Array | An array of field names (as used in `scrape.*`) that are allowed to have empty values. | `[]` |
|
|
138
|
+
| `before` | Function | A custom function that's executed just before the pixel is executed. | `(scrapedData, callback) => { callback(scrapedData); }` |
|
|
139
|
+
| `after` | Function | A custom function that's executed just after the pixel has been executed. | `(scrapedData) => {}` |
|
|
133
140
|
|
|
134
141
|
## Static methods (helpers)
|
|
135
142
|
|
|
136
|
-
###
|
|
143
|
+
### `.getUrl({ allowedQueryParameters, allowHash })`
|
|
137
144
|
|
|
138
|
-
Returns the bare page URL without query parameters or location hash. This is recommended to
|
|
145
|
+
Returns the bare page URL without query parameters or location hash. This is highly recommended to exclude (UTM) tagging, or other unwanted side effects.
|
|
139
146
|
|
|
140
|
-
| Property | Type | Description
|
|
141
|
-
| ------------------------ | ------- |
|
|
142
|
-
| `allowedQueryParameters` | Array | Explicitly allow query parameters in the
|
|
143
|
-
| `allowHash` | Boolean |
|
|
147
|
+
| Property | Type | Description | Default |
|
|
148
|
+
| ------------------------ | ------- | ----------------------------------------------------------------- | ------- |
|
|
149
|
+
| `allowedQueryParameters` | Array | Explicitly allow query parameters in the URL. | `[]` |
|
|
150
|
+
| `allowHash` | Boolean | Explicitly allow including the location hash (`#foo`) in the URL. | `false` |
|
|
144
151
|
|
|
145
|
-
###
|
|
152
|
+
### `.getAllPathSegments()`
|
|
146
153
|
|
|
147
154
|
Retrieves all path segments from the URL as an array. E.g. _http://www.example.com/foo/bar_ returns `["foo", "bar"]`.
|
|
148
155
|
|
|
149
|
-
###
|
|
156
|
+
### `.getPathSegment(index)`
|
|
150
157
|
|
|
151
|
-
Retrieves a specific segment from the URL. E.g. `getPathSegment(0)`
|
|
158
|
+
Retrieves a specific segment from the URL. E.g. `getPathSegment(0)` on _http://www.example.com/foo/bar_ returns `"foo"`.
|
|
152
159
|
|
|
153
|
-
###
|
|
160
|
+
### `.getAllQueryParameters()`
|
|
154
161
|
|
|
155
162
|
Retrieves all query string parameters from the URL as an object. E.g. _http://www.example.com/?foo=bar_ returns `{ foo: "bar" }`.
|
|
156
163
|
|
|
157
|
-
###
|
|
164
|
+
### `.getQueryParameter(key)`
|
|
158
165
|
|
|
159
|
-
Retrieves a specific query parameter from the URL. E.g. `getQueryParameter('foo')`
|
|
166
|
+
Retrieves a specific query parameter from the URL. E.g. `getQueryParameter('foo')` on _http://www.example.com/?foo=bar_ returns `"bar"`.
|
package/dist/bundle.cjs.js
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
/*! choreograph-create-pixel v1.
|
|
1
|
+
/*! choreograph-create-pixel v1.3.1 2022/11/25 */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
const CONFIG = {
|
|
5
|
-
colors: { error: "red", warn: "orange", success: "green" },
|
|
6
|
-
icons: {
|
|
7
|
-
scraper: "π",
|
|
8
|
-
viewed: "π",
|
|
9
|
-
basketed: "π",
|
|
10
|
-
purchased: "π§Ύ",
|
|
11
|
-
attribution: "π",
|
|
12
|
-
conversion: "π΅",
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
|
|
16
4
|
class ChoreographCreatePixel {
|
|
17
5
|
constructor(userConfig) {
|
|
18
6
|
this.previouslyScrapedHash = null;
|
|
19
7
|
this.logs = [];
|
|
20
8
|
|
|
21
9
|
this.config = {
|
|
10
|
+
colors: { error: "red", warn: "orange", success: "green" },
|
|
11
|
+
icons: {
|
|
12
|
+
scraper: "π",
|
|
13
|
+
viewed: "π",
|
|
14
|
+
basketed: "π",
|
|
15
|
+
purchased: "π§Ύ",
|
|
16
|
+
attribution: "π",
|
|
17
|
+
conversion: "π΅",
|
|
18
|
+
},
|
|
22
19
|
debug: /(pixel|lemonpi)_debug/i.test(location.href),
|
|
23
20
|
before: (data, callback) => callback(data),
|
|
24
21
|
after: () => {},
|
|
@@ -89,11 +86,11 @@ class ChoreographCreatePixel {
|
|
|
89
86
|
|
|
90
87
|
const args = [
|
|
91
88
|
`%cβΈ¬ create%c ${this.config.type} ${
|
|
92
|
-
|
|
89
|
+
this.config.icons[this.config.type]
|
|
93
90
|
} %c${message}`,
|
|
94
91
|
"background:black;color:white;border-radius:3px;padding:3px 6px",
|
|
95
92
|
"font-weight:bold",
|
|
96
|
-
`color:${
|
|
93
|
+
`color:${this.config.colors[level]}`,
|
|
97
94
|
];
|
|
98
95
|
|
|
99
96
|
if (data) args.push(data);
|
|
@@ -136,16 +133,20 @@ class ChoreographCreatePixel {
|
|
|
136
133
|
"warn",
|
|
137
134
|
"This page has been translated by the browser, and won't be scraped"
|
|
138
135
|
);
|
|
139
|
-
else if (this.config.
|
|
140
|
-
const attribute = `create-${this.config.type}-${this.config.
|
|
136
|
+
else if (this.config.trigger) {
|
|
137
|
+
const attribute = `create-${this.config.type}-${this.config.trigger.event}`;
|
|
141
138
|
|
|
142
139
|
try {
|
|
143
|
-
let elements =
|
|
140
|
+
let elements =
|
|
141
|
+
typeof this.config.trigger.elements === "string"
|
|
142
|
+
? document.querySelectorAll(this.config.trigger.elements)
|
|
143
|
+
: this.config.trigger.elements();
|
|
144
|
+
|
|
144
145
|
if (!elements.forEach) elements = [elements];
|
|
145
146
|
|
|
146
147
|
elements.forEach((element) => {
|
|
147
148
|
if (!element.hasAttribute(attribute)) {
|
|
148
|
-
element.addEventListener(this.config.
|
|
149
|
+
element.addEventListener(this.config.trigger.event, () =>
|
|
149
150
|
this.scrape(element)
|
|
150
151
|
);
|
|
151
152
|
|
|
@@ -154,7 +155,7 @@ class ChoreographCreatePixel {
|
|
|
154
155
|
});
|
|
155
156
|
} catch (error) {
|
|
156
157
|
this.log("error", error.message, {
|
|
157
|
-
"
|
|
158
|
+
"trigger.elements": this.config.trigger.elements,
|
|
158
159
|
});
|
|
159
160
|
}
|
|
160
161
|
} else {
|
package/dist/bundle.esm.js
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
/*! choreograph-create-pixel v1.
|
|
2
|
-
const CONFIG = {
|
|
3
|
-
colors: { error: "red", warn: "orange", success: "green" },
|
|
4
|
-
icons: {
|
|
5
|
-
scraper: "π",
|
|
6
|
-
viewed: "π",
|
|
7
|
-
basketed: "π",
|
|
8
|
-
purchased: "π§Ύ",
|
|
9
|
-
attribution: "π",
|
|
10
|
-
conversion: "π΅",
|
|
11
|
-
},
|
|
12
|
-
};
|
|
13
|
-
|
|
1
|
+
/*! choreograph-create-pixel v1.3.1 2022/11/25 */
|
|
14
2
|
class ChoreographCreatePixel {
|
|
15
3
|
constructor(userConfig) {
|
|
16
4
|
this.previouslyScrapedHash = null;
|
|
17
5
|
this.logs = [];
|
|
18
6
|
|
|
19
7
|
this.config = {
|
|
8
|
+
colors: { error: "red", warn: "orange", success: "green" },
|
|
9
|
+
icons: {
|
|
10
|
+
scraper: "π",
|
|
11
|
+
viewed: "π",
|
|
12
|
+
basketed: "π",
|
|
13
|
+
purchased: "π§Ύ",
|
|
14
|
+
attribution: "π",
|
|
15
|
+
conversion: "π΅",
|
|
16
|
+
},
|
|
20
17
|
debug: /(pixel|lemonpi)_debug/i.test(location.href),
|
|
21
18
|
before: (data, callback) => callback(data),
|
|
22
19
|
after: () => {},
|
|
@@ -87,11 +84,11 @@ class ChoreographCreatePixel {
|
|
|
87
84
|
|
|
88
85
|
const args = [
|
|
89
86
|
`%cβΈ¬ create%c ${this.config.type} ${
|
|
90
|
-
|
|
87
|
+
this.config.icons[this.config.type]
|
|
91
88
|
} %c${message}`,
|
|
92
89
|
"background:black;color:white;border-radius:3px;padding:3px 6px",
|
|
93
90
|
"font-weight:bold",
|
|
94
|
-
`color:${
|
|
91
|
+
`color:${this.config.colors[level]}`,
|
|
95
92
|
];
|
|
96
93
|
|
|
97
94
|
if (data) args.push(data);
|
|
@@ -134,16 +131,20 @@ class ChoreographCreatePixel {
|
|
|
134
131
|
"warn",
|
|
135
132
|
"This page has been translated by the browser, and won't be scraped"
|
|
136
133
|
);
|
|
137
|
-
else if (this.config.
|
|
138
|
-
const attribute = `create-${this.config.type}-${this.config.
|
|
134
|
+
else if (this.config.trigger) {
|
|
135
|
+
const attribute = `create-${this.config.type}-${this.config.trigger.event}`;
|
|
139
136
|
|
|
140
137
|
try {
|
|
141
|
-
let elements =
|
|
138
|
+
let elements =
|
|
139
|
+
typeof this.config.trigger.elements === "string"
|
|
140
|
+
? document.querySelectorAll(this.config.trigger.elements)
|
|
141
|
+
: this.config.trigger.elements();
|
|
142
|
+
|
|
142
143
|
if (!elements.forEach) elements = [elements];
|
|
143
144
|
|
|
144
145
|
elements.forEach((element) => {
|
|
145
146
|
if (!element.hasAttribute(attribute)) {
|
|
146
|
-
element.addEventListener(this.config.
|
|
147
|
+
element.addEventListener(this.config.trigger.event, () =>
|
|
147
148
|
this.scrape(element)
|
|
148
149
|
);
|
|
149
150
|
|
|
@@ -152,7 +153,7 @@ class ChoreographCreatePixel {
|
|
|
152
153
|
});
|
|
153
154
|
} catch (error) {
|
|
154
155
|
this.log("error", error.message, {
|
|
155
|
-
"
|
|
156
|
+
"trigger.elements": this.config.trigger.elements,
|
|
156
157
|
});
|
|
157
158
|
}
|
|
158
159
|
} else {
|
package/dist/bundle.iife.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! choreograph-create-pixel v1.
|
|
2
|
-
var ChoreographCreatePixel=function(){"use strict";function e(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function t(t){for(var r=1;r<arguments.length;r++){var o=null!=arguments[r]?arguments[r]:{};r%2?e(Object(o),!0).forEach((function(e){n(t,e,o[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):e(Object(o)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))}))}return t}function r(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var o=
|
|
1
|
+
/*! choreograph-create-pixel v1.3.1 2022/11/25 */
|
|
2
|
+
var ChoreographCreatePixel=function(){"use strict";function e(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function t(t){for(var r=1;r<arguments.length;r++){var o=null!=arguments[r]?arguments[r]:{};r%2?e(Object(o),!0).forEach((function(e){n(t,e,o[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):e(Object(o)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))}))}return t}function r(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var o=function(){function e(r){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.previouslyScrapedHash=null,this.logs=[],this.config=t({colors:{error:"red",warn:"orange",success:"green"},icons:{scraper:"π",viewed:"π",basketed:"π",purchased:"π§Ύ",attribution:"π",conversion:"π΅"},debug:/(pixel|lemonpi)_debug/i.test(location.href),before:function(e,t){return t(e)},after:function(){},optional:[]},r),this.validateConfig()&&this.cycle()}var o,i,c;return o=e,i=[{key:"log",value:function(e,t){var r,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(this.config.debug&&!this.logs.includes(t)){var o=["%cβΈ¬ create%c ".concat(this.config.type," ").concat(this.config.icons[this.config.type]," %c").concat(t),"background:black;color:white;border-radius:3px;padding:3px 6px","font-weight:bold","color:".concat(this.config.colors[e])];n&&o.push(n),(r=console).info.apply(r,o),this.logs.push(t)}}},{key:"validateConfig",value:function(){if("number"!=typeof this.config.advertiser)this.log("error","Please use a number",{advertiser:this.config.advertiser});else if(["scraper","viewed","basketed","purchased"].includes(this.config.type))if(this.config.url instanceof RegExp){if(this.config.scrape)return!0;this.log("error","Please provide something to scrape",{scrape:this.config.scrape})}else this.log("error","Please use a regular expression",{url:this.config.url});else this.log("error","Please use scraper, viewed, basketed or purchased",{type:this.config.type})}},{key:"cycle",value:function(){var e=this;if(this.config.url.test(location.href))if("scraper"===this.config.type&&document.querySelector('html[class*="translated-"]'))this.log("warn","This page has been translated by the browser, and won't be scraped");else if(this.config.trigger){var t="create-".concat(this.config.type,"-").concat(this.config.trigger.event);try{var r="string"==typeof this.config.trigger.elements?document.querySelectorAll(this.config.trigger.elements):this.config.trigger.elements();r.forEach||(r=[r]),r.forEach((function(r){r.hasAttribute(t)||(r.addEventListener(e.config.trigger.event,(function(){return e.scrape(r)})),r.setAttribute(t,""))}))}catch(e){this.log("error",e.message,{"trigger.elements":this.config.trigger.elements})}}else this.scrape();else this.log("warn",'URL pattern does not match "'.concat(location.href,'"'),{url:this.config.url});setTimeout((function(){return e.cycle()}),750)}},{key:"scrape",value:function(e){var r,o=this,i=!1,c=function(t,r){var c=t;if("function"==typeof c)try{c=c(e)}catch(e){if(o.config.optional.includes(r))return null;o.log("attribution"===o.config.type?"warn":"error",e.message,n({},r?"scrape.".concat(r):"scrape",c)),i=!0}if("string"==typeof c&&(c=c.replace(/\s+/g," ").trim()),null==c||""===c){if(o.config.optional.includes(r))return null;o.log("attribution"===o.config.type?"warn":"error","Value is empty",n({},r?"scrape.".concat(r):"scrape",c)),i=!0}return c};"conversion"===this.config.type?"string"!=typeof(r={conversion:c(this.config.scrape),attribution:localStorage.getItem("create-attribution-id")}).attribution&&(this.log("warn","There's no attribution ID stored yet"),i=!0):r="scraper"!==this.config.type?c(this.config.scrape):Object.keys(this.config.scrape).reduce((function(e,r){return t(t({},e),{},n({},r,c(o.config.scrape[r],r)))}),{});var s=JSON.stringify(r);if(!i&&this.previouslyScrapedHash!==s){try{this.config.before(r,(function(e){if("attribution"===o.config.type){localStorage.setItem("create-attribution-id",r),o.log("success","Successful!",{attribution:r});try{o.config.after(r)}catch(e){o.log("error",e.message,{after:o.config.after})}}else Array.isArray(e)?e.forEach((function(e){return o.send(e)})):o.send(e)}))}catch(e){this.log("error",e.message,{before:this.config.before})}this.previouslyScrapedHash=s,this.logs.length=0}}},{key:"send",value:function(e){var r,n=this;switch(this.config.type){case"scraper":r="https://d.lemonpi.io/scrapes".concat(this.config.debug?"?validate=true":"");break;case"conversion":r="https://lemonpi.io/";break;default:r="https://d.lemonpi.io/a/".concat(this.config.advertiser,"/product/event?e=").concat(encodeURIComponent(JSON.stringify({"event-type":"product-".concat(this.config.type),sku:e})))}"scraper"===this.config.type||this.config.debug?fetch(r,"scraper"===this.config.type?{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({"advertiser-id":this.config.advertiser,sku:e.sku,fields:t(t({},e),{},{sku:void 0})})}:null).then((function(t){return t.json().then((function(r){if(t.ok){n.log("warn","Successful, with warnings. Details:",r);try{n.config.after(e)}catch(e){n.log("error",e.message,{after:n.config.after})}}else n.log("error","Failed: ".concat(t.status," (").concat(t.statusText,"). Details:"),r);n.logs.length=0})).catch((function(){if(t.ok){n.log("success","Successful!",["viewed","basketed","purchased"].includes(n.config.type)?{sku:e}:e);try{n.config.after(e)}catch(e){n.log("error",e.message,{after:n.config.after})}}else n.log("error","Failed: ".concat(t.status," (").concat(t.statusText,"). Details:"),t);n.logs.length=0}))})).catch((function(e){n.log("error","Failed: ".concat(e.message)),n.logs.length=0})):(new Image).src=r}}],c=[{key:"getUrl",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.allowedQueryParameters,r=void 0===t?[]:t,n=e.allowHash,o=void 0!==n&&n,i="".concat(location.protocol,"//").concat(location.host).concat(location.pathname),c=new URLSearchParams(location.search);return r.reduce((function(e,t){var r=e?"&":"?",n=encodeURI(t),o=c.get(t);return null!=o?(i+="".concat(r).concat(n).concat(""===o?"":"=".concat(encodeURI(o))),!0):e}),!1),o&&(i+=location.hash),i}},{key:"getAllPathSegments",value:function(){return location.pathname.split("/").filter((function(e){return e})).map((function(e){return decodeURI(e)}))}},{key:"getPathSegment",value:function(e){return this.getAllPathSegments()[e]}},{key:"getAllQueryParameters",value:function(){return location.search.replace(/^\?/,"").split("&").filter((function(e){return e})).reduce((function(e,r){return t(t({},e),{},n({},decodeURI(r.split("=")[0]),decodeURI(r.split("=")[1]||"")))}),{})}},{key:"getQueryParameter",value:function(e){return this.getAllQueryParameters()[e]}}],i&&r(o.prototype,i),c&&r(o,c),Object.defineProperty(o,"prototype",{writable:!1}),e}();return o}();
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "choreograph-create-pixel",
|
|
3
3
|
"description": "This library lets you apply best practises to Choreograph Create pixel development and implementation.",
|
|
4
|
+
"version": "1.3.1",
|
|
4
5
|
"keywords": [
|
|
5
6
|
"wpp",
|
|
6
7
|
"groupm",
|
|
@@ -8,7 +9,6 @@
|
|
|
8
9
|
"odc",
|
|
9
10
|
"opendc"
|
|
10
11
|
],
|
|
11
|
-
"version": "1.2.0",
|
|
12
12
|
"author": "Rick Stevens <rick.stevens@choreograph.com> (https://lemonpi.io)",
|
|
13
13
|
"repository": "gitlab:GreenhouseGroup/lemonpi/solutions/choreograph-create-pixel",
|
|
14
14
|
"homepage": "https://lemonpi.io",
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"prepublishOnly": "npm run build"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@babel/core": "^7.
|
|
32
|
-
"@babel/preset-env": "^7.
|
|
33
|
-
"@rollup/plugin-babel": "^
|
|
34
|
-
"@rollup/plugin-eslint": "^
|
|
35
|
-
"eslint": "^8.
|
|
31
|
+
"@babel/core": "^7.20.2",
|
|
32
|
+
"@babel/preset-env": "^7.20.2",
|
|
33
|
+
"@rollup/plugin-babel": "^6.0.3",
|
|
34
|
+
"@rollup/plugin-eslint": "^9.0.1",
|
|
35
|
+
"eslint": "^8.28.0",
|
|
36
36
|
"eslint-config-prettier": "^8.5.0",
|
|
37
37
|
"eslint-plugin-prettier": "^4.2.1",
|
|
38
38
|
"moment": "^2.29.4",
|
|
39
|
-
"prettier": "^2.
|
|
39
|
+
"prettier": "^2.8.0",
|
|
40
40
|
"rollup": "^2.79.1",
|
|
41
41
|
"rollup-plugin-terser": "^7.0.2"
|
|
42
42
|
}
|