@mhubcloud/tms_core 1.7.5 → 1.7.6
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/index.js +2 -1
- package/package.json +2 -2
- package/publishers/AffiliatePort.js +61 -0
- package/tests/AffiliatePort.js +116 -0
package/index.js
CHANGED
|
@@ -9,6 +9,7 @@ module.exports = {
|
|
|
9
9
|
Facebook : require('./publishers/Facebook'),
|
|
10
10
|
GoogleAnalytics4 : require('./publishers/GoogleAnalytics4'),
|
|
11
11
|
CJ : require('./publishers/CJ'),
|
|
12
|
-
UniversalAnalytics : require('./publishers/UniversalAnalytics')
|
|
12
|
+
UniversalAnalytics : require('./publishers/UniversalAnalytics'),
|
|
13
|
+
AffiliatePort : require('./publishers/AffiliatePort')
|
|
13
14
|
}
|
|
14
15
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mhubcloud/tms_core",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.6",
|
|
4
4
|
"description": "Core function for mHub Cloud TMS publishers",
|
|
5
5
|
"homepage": "https://mhubcloud.com/",
|
|
6
6
|
"license": "Apache 2.0",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"conversion API"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
|
-
"test": "mocha ./tests/*.js"
|
|
19
|
+
"test": "mocha ./tests/*.js --timeout 10000 "
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"ajv": "^8.8.2",
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const fetch = require('node-fetch');
|
|
2
|
+
const utils = require("../lib/utils");
|
|
3
|
+
const SOURCE = "f_AffiliatePort";
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
/**
|
|
7
|
+
* Processed data comming from EventHub to data for further processing
|
|
8
|
+
* @param {Object} data The data comming from EventHub
|
|
9
|
+
* @returns {Object} Data for further processing
|
|
10
|
+
*/
|
|
11
|
+
parse: function parse(data, context) {
|
|
12
|
+
//ConsumerBase.cs:ConsumeOneEventAsync
|
|
13
|
+
data.enqueuedAt = context.test ? 1600000000000 : Date.now();
|
|
14
|
+
return data;
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Publishes data to AffiliatePort
|
|
19
|
+
* @param {{id: string, access_token: string}} config Publisher configuration
|
|
20
|
+
* @param {Object} data Data in publisher-friendly format to be published
|
|
21
|
+
* @param {string} event for which is it triggered
|
|
22
|
+
*/
|
|
23
|
+
publish: async function publish(config, data, event) {
|
|
24
|
+
data = utils.removeUndefined(data);
|
|
25
|
+
const reqOpts = {
|
|
26
|
+
method: "get"
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
for(let product of data.products){
|
|
30
|
+
|
|
31
|
+
//https://tracking.affiliateclub.cz/aff_lsr?offer_id=OFFER_ID&adv_sub=TID_SUB_ID&amount=AMOUNT&transaction_id=TRANSACTION_ID&adv_sub2=CATEGORY&adv_sub3=MASTER_TYPE
|
|
32
|
+
const url = "https://tracking.affiliateclub.cz/aff_lsr?offer_id=" + encodeURIComponent(config.offerId) + "&adv_sub=TID_" + data.orderId + "&amount=" + product.quantity * product.price + "&transaction_id=" + data.transactionID + "&adv_sub2=" + product.category + "&adv_sub3=" + product.masterType;
|
|
33
|
+
const resp = await fetch(url, reqOpts);
|
|
34
|
+
|
|
35
|
+
if (process.env.PUBLISHER_TESTURL) {
|
|
36
|
+
try {
|
|
37
|
+
utils.prepareTestRequestHeaders(reqOpts.headers, url, reqOpts, resp);
|
|
38
|
+
await fetch(process.env.PUBLISHER_TESTURL + query, reqOpts);
|
|
39
|
+
} catch { }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
await utils.handleResponse(resp, event);
|
|
43
|
+
|
|
44
|
+
console.log(`AffiliatePort - ${event} - sent`);
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Validates an object against given schema
|
|
51
|
+
* @param {Object} data An object to validate.
|
|
52
|
+
* @param {string} schema Name of the schema. That's name of a file with `.schema.json` extension in `customizable/schemas` subfolder of current publisher folder
|
|
53
|
+
* @returns {boolean} Validation result, true if successful, false if unsuccessfull (in which case more info is written to console)
|
|
54
|
+
*/
|
|
55
|
+
validate: function validate(data, schema) {
|
|
56
|
+
if (!schema) throw new Error("Schema parameters not provided");
|
|
57
|
+
if (schema.indexOf("/") >= 0) throw new Error("Schema must be provided as schema name, not schema path");
|
|
58
|
+
//More validation done by utils.validate
|
|
59
|
+
return utils.validate(data, SOURCE, schema);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
const publisher = require("../index.js").publisher.AffiliatePort;
|
|
2
|
+
const defaultPublisher = require("../index.js").DefaultPublisher;
|
|
3
|
+
const utils = require("../index.js").utils;
|
|
4
|
+
var assert = require('assert');
|
|
5
|
+
|
|
6
|
+
describe('test AffiliatePort publisher', function () {
|
|
7
|
+
it('purchase', async function () {
|
|
8
|
+
var eventHubMessages = [
|
|
9
|
+
{
|
|
10
|
+
"event": {
|
|
11
|
+
"region": "smarty.cz",
|
|
12
|
+
"id": "825333270-1011.1659006863812",
|
|
13
|
+
"code": "purchase"
|
|
14
|
+
},
|
|
15
|
+
"user": {
|
|
16
|
+
"ts": "customer.HL",
|
|
17
|
+
"email": "jan.brzobohaty@crossmasters.com",
|
|
18
|
+
"id": "a2992fb8-40ac-4b88-9cf5-7fba02f1f611"
|
|
19
|
+
},
|
|
20
|
+
"session": {
|
|
21
|
+
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15",
|
|
22
|
+
"ip": "217.195.174.253"
|
|
23
|
+
},
|
|
24
|
+
"permissions": [],
|
|
25
|
+
"currencyCode": "CZK",
|
|
26
|
+
"publisher": {
|
|
27
|
+
"code": "www.smarty.cz",
|
|
28
|
+
"tm": "GTM-NVNTFG",
|
|
29
|
+
"tmv": "193"
|
|
30
|
+
},
|
|
31
|
+
"$schema": "https://schema.measurementhub.net/mhub/2021-12-27/purchase",
|
|
32
|
+
"id": "3511111111",
|
|
33
|
+
"revenue": 10,
|
|
34
|
+
"products": [
|
|
35
|
+
{
|
|
36
|
+
"id": "67137",
|
|
37
|
+
"price": 10,
|
|
38
|
+
"quantity": 1,
|
|
39
|
+
"category": "Playstation",
|
|
40
|
+
"masterType": "Konzole"
|
|
41
|
+
},{
|
|
42
|
+
"id": "67137",
|
|
43
|
+
"price": 20,
|
|
44
|
+
"quantity": 1,
|
|
45
|
+
"category": "Monitor",
|
|
46
|
+
"masterType": "Video"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"location": "https://www.smarty.cz/checkoutSuccess",
|
|
50
|
+
"referrer": "https://www.smarty.cz/Order/AddReservation?productId=57873&shopAddressId=24798",
|
|
51
|
+
"enqueuedAt": 1659006864038,
|
|
52
|
+
"ads": [{"adPlatform":"affiliateport","adCodes":{"transaction_id":"816f5670dbf52c3dc27a7e849903c327d705ef643993fbab3"},"visitAt":1658392668000}],
|
|
53
|
+
"EventProcessedUtcTime": "2022-07-28T11:54:50.2528883Z",
|
|
54
|
+
"PartitionId": 0,
|
|
55
|
+
"EventEnqueuedUtcTime": "2022-07-28T11:14:24.1170000Z"
|
|
56
|
+
}
|
|
57
|
+
];
|
|
58
|
+
await test(eventHubMessages);
|
|
59
|
+
});
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Test function
|
|
65
|
+
* @param [object] object obsahující nastavení testovací parametry
|
|
66
|
+
*/
|
|
67
|
+
async function test(eventHubMessages) {
|
|
68
|
+
try{
|
|
69
|
+
await defaultPublisher(console, eventHubMessages, "AffiliatePort", publisher, trigger);
|
|
70
|
+
}catch(err){
|
|
71
|
+
console.log(err);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function trigger(data) {
|
|
76
|
+
const publishers = [];
|
|
77
|
+
let publisher;
|
|
78
|
+
|
|
79
|
+
//Dummy config, replace with your own
|
|
80
|
+
const config = {
|
|
81
|
+
offerId: 123,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
switch (data.event?.code) {
|
|
85
|
+
case "purchase":
|
|
86
|
+
publisher = AffiliatePortPurchasePublisher;
|
|
87
|
+
publisher.register(publishers, config);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
return publishers;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Implements Purchase event publisher for Facebook
|
|
95
|
+
* @implements {EventPublisher<{id: string, access_token: string}>}
|
|
96
|
+
*/
|
|
97
|
+
class AffiliatePortPurchasePublisher extends utils.EventPublisherBase {
|
|
98
|
+
/**
|
|
99
|
+
* Maps `purchase` event data to AffiliatePort payload
|
|
100
|
+
* @param {Object} data `purchase` event data
|
|
101
|
+
* @returns {Object} Data mapped from incomming Event Hub message to platform payload
|
|
102
|
+
*/
|
|
103
|
+
map(data) {
|
|
104
|
+
return {
|
|
105
|
+
orderId: data.id,
|
|
106
|
+
revenue: data.revenue, //should be without VAT and shipping, payment fees
|
|
107
|
+
products: data.products.map(pr => ({
|
|
108
|
+
quantity: pr.quantity, // e.g. 1
|
|
109
|
+
price: pr.price, // e.g. 109
|
|
110
|
+
category: pr.category.replace(/ /g, "-"), // e.g. Playstation
|
|
111
|
+
masterType: pr.masterType // e.g. Konzole
|
|
112
|
+
})),
|
|
113
|
+
transactionID: utils.extractAdCode(data, 'affiliateport', 'transaction_id')?.code // AffiliatePort identificator taken automatically from URL
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
};
|