@mhubcloud/tms_core 3.6.0-beta.1 → 3.7.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +191 -14
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -43,7 +43,8 @@ var broker_exports = {};
|
|
|
43
43
|
__export(broker_exports, {
|
|
44
44
|
dispatchEvent: () => dispatchEvent,
|
|
45
45
|
logToCosmosDb: () => logToCosmosDb,
|
|
46
|
-
resolveEvent: () => resolveEvent
|
|
46
|
+
resolveEvent: () => resolveEvent,
|
|
47
|
+
scheduleEvent: () => scheduleEvent
|
|
47
48
|
});
|
|
48
49
|
var import_cosmos = require("@azure/cosmos");
|
|
49
50
|
var import_service_bus = require("@azure/service-bus");
|
|
@@ -105,7 +106,19 @@ function logMessage(level, message, properties) {
|
|
|
105
106
|
function logEvent(publisher2, event, region, status, payload, id) {
|
|
106
107
|
let message = "";
|
|
107
108
|
if (status || status === 0) {
|
|
108
|
-
|
|
109
|
+
if (status >= 200 && status < 300) {
|
|
110
|
+
aiClient?.trackMetric({
|
|
111
|
+
name: `Dispatched/${publisher2}-${event}-${region}`,
|
|
112
|
+
value: 1
|
|
113
|
+
});
|
|
114
|
+
message = "Event dispatched to platform";
|
|
115
|
+
} else {
|
|
116
|
+
aiClient?.trackMetric({
|
|
117
|
+
name: `Failed/${publisher2}-${event}-${region}`,
|
|
118
|
+
value: 1
|
|
119
|
+
});
|
|
120
|
+
message = "Event dispatch failed";
|
|
121
|
+
}
|
|
109
122
|
} else {
|
|
110
123
|
message = "Event dispatched to platform";
|
|
111
124
|
}
|
|
@@ -275,7 +288,7 @@ async function handlePlatformRequest({
|
|
|
275
288
|
event.event,
|
|
276
289
|
event.region,
|
|
277
290
|
0,
|
|
278
|
-
requestOptions.
|
|
291
|
+
requestOptions.method === "POST" ? JSON.stringify(requestOptions.body) : query,
|
|
279
292
|
event.id
|
|
280
293
|
);
|
|
281
294
|
throw e;
|
|
@@ -294,7 +307,7 @@ async function handlePlatformRequest({
|
|
|
294
307
|
event.event,
|
|
295
308
|
event.region,
|
|
296
309
|
rawPlatformResponse.status,
|
|
297
|
-
requestOptions.
|
|
310
|
+
requestOptions.method === "POST" ? JSON.stringify(requestOptions.body) : query,
|
|
298
311
|
event.id
|
|
299
312
|
);
|
|
300
313
|
if (!rawPlatformResponse.ok) {
|
|
@@ -458,6 +471,66 @@ async function logToCosmosDb(message) {
|
|
|
458
471
|
logException(e);
|
|
459
472
|
}
|
|
460
473
|
}
|
|
474
|
+
async function scheduleEvent(message, queue, options) {
|
|
475
|
+
if (!serviceBusClient) {
|
|
476
|
+
if (!serviceBusConnectionString) {
|
|
477
|
+
throw new Error("Service Bus connection string is missing.");
|
|
478
|
+
}
|
|
479
|
+
serviceBusClient = new import_service_bus.ServiceBusClient(serviceBusConnectionString);
|
|
480
|
+
}
|
|
481
|
+
try {
|
|
482
|
+
let sender;
|
|
483
|
+
if (senders[queue]) {
|
|
484
|
+
sender = senders[queue];
|
|
485
|
+
} else {
|
|
486
|
+
senders[queue] = serviceBusClient.createSender(queue);
|
|
487
|
+
sender = senders[queue];
|
|
488
|
+
}
|
|
489
|
+
let dispatchTime;
|
|
490
|
+
const now = /* @__PURE__ */ new Date();
|
|
491
|
+
if ("timestamp" in options) {
|
|
492
|
+
dispatchTime = new Date(options.timestamp);
|
|
493
|
+
} else if ("scheduleHour" in options) {
|
|
494
|
+
dispatchTime = new Date(
|
|
495
|
+
now.getFullYear(),
|
|
496
|
+
now.getMonth(),
|
|
497
|
+
now.getDate() + (options.dayOffset ?? 0),
|
|
498
|
+
options.scheduleHour,
|
|
499
|
+
options.scheduleMinute ?? 0,
|
|
500
|
+
0,
|
|
501
|
+
0
|
|
502
|
+
);
|
|
503
|
+
} else if ("scheduleInterval" in options && "startHour" in options) {
|
|
504
|
+
const hour = now.getHours();
|
|
505
|
+
const nextHour = Math.ceil(hour / options.scheduleInterval) * options.scheduleInterval;
|
|
506
|
+
dispatchTime = new Date(
|
|
507
|
+
now.getFullYear(),
|
|
508
|
+
now.getMonth(),
|
|
509
|
+
now.getDate() + (options.dayOffset ?? 0),
|
|
510
|
+
nextHour,
|
|
511
|
+
options.startMinute ?? 0,
|
|
512
|
+
0,
|
|
513
|
+
0
|
|
514
|
+
);
|
|
515
|
+
if (nextHour >= 24) {
|
|
516
|
+
dispatchTime.setDate(dispatchTime.getDate() + 1);
|
|
517
|
+
dispatchTime.setHours(options.startHour, options.startMinute);
|
|
518
|
+
}
|
|
519
|
+
} else {
|
|
520
|
+
throw new Error("Invalid scheduling configuration");
|
|
521
|
+
}
|
|
522
|
+
const serviceBusMessage = {
|
|
523
|
+
body: message,
|
|
524
|
+
scheduledEnqueueTimeUtc: dispatchTime
|
|
525
|
+
};
|
|
526
|
+
await sender.sendMessages(serviceBusMessage);
|
|
527
|
+
return dispatchTime;
|
|
528
|
+
} catch (e) {
|
|
529
|
+
console.log(
|
|
530
|
+
`Scheduling message to queue ${queue} failed. Cause: ${e instanceof Error ? e.message : ""}`
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
461
534
|
|
|
462
535
|
// src/defaultPublisher.ts
|
|
463
536
|
async function defaultPublisher(azureFunctionContext, serviceBusMessage, source, platformPublisher, trigger) {
|
|
@@ -839,6 +912,114 @@ var googleAnalytics4 = {
|
|
|
839
912
|
}
|
|
840
913
|
};
|
|
841
914
|
|
|
915
|
+
// src/publishers/microsoftAds.ts
|
|
916
|
+
var tokenCache2;
|
|
917
|
+
var tokenPromise2;
|
|
918
|
+
var microsoftAds = {
|
|
919
|
+
source: "MicrosoftAds",
|
|
920
|
+
/**
|
|
921
|
+
*Publishes data to Microsoft Ads
|
|
922
|
+
* @param log Azure Function context.log
|
|
923
|
+
* @param config Publisher configuration
|
|
924
|
+
* @param data Data in publisher-friendly format to be published
|
|
925
|
+
* @param event Event for which the function is triggered
|
|
926
|
+
*/
|
|
927
|
+
async publish(log2, config, data, event) {
|
|
928
|
+
if (typeof config.customerAccountId === "string" && typeof config.customerId === "string" && typeof config.developerToken === "string") {
|
|
929
|
+
if (!(data.ConversionName || data.ConversionTime || data.MicrosoftClickId)) {
|
|
930
|
+
logMessage(
|
|
931
|
+
1,
|
|
932
|
+
`MicrosoftAds: excluded ${event.event} as one or more mandatory parameters were missing`
|
|
933
|
+
);
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
const { token } = await this.getToken(config);
|
|
937
|
+
const body = {
|
|
938
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
939
|
+
OfflineConversions: [data]
|
|
940
|
+
};
|
|
941
|
+
const requestOptions = {
|
|
942
|
+
method: "POST",
|
|
943
|
+
body: JSON.stringify(body),
|
|
944
|
+
headers: {
|
|
945
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
946
|
+
Authorization: `Bearer ${token}`,
|
|
947
|
+
CustomerAccountId: config.customerAccountId,
|
|
948
|
+
CustomerId: config.customerId,
|
|
949
|
+
DeveloperToken: config.developerToken,
|
|
950
|
+
"Content-Type": "application/json"
|
|
951
|
+
/* eslint-enable */
|
|
952
|
+
}
|
|
953
|
+
};
|
|
954
|
+
const baseUrl = "https://campaign.api.bingads.microsoft.com/CampaignManagement/v13/OfflineConversions/Apply";
|
|
955
|
+
const response = await fetch(baseUrl, requestOptions);
|
|
956
|
+
const responseJson = await response.json();
|
|
957
|
+
let status = 0;
|
|
958
|
+
let error;
|
|
959
|
+
if (responseJson.PartialErrors || responseJson.Errors) {
|
|
960
|
+
const apiErrors = responseJson.Errors ?? responseJson.PartialErrors ?? [];
|
|
961
|
+
status = 500;
|
|
962
|
+
const message = apiErrors.reduce((acc, curr) => {
|
|
963
|
+
acc += curr.Message + " ";
|
|
964
|
+
return acc;
|
|
965
|
+
}, "Microsoft Ads: Error(s) processing event: ");
|
|
966
|
+
error = message;
|
|
967
|
+
} else {
|
|
968
|
+
status = 200;
|
|
969
|
+
}
|
|
970
|
+
logEvent(
|
|
971
|
+
this.source,
|
|
972
|
+
event.event,
|
|
973
|
+
event.region,
|
|
974
|
+
status,
|
|
975
|
+
requestOptions.body,
|
|
976
|
+
event.id
|
|
977
|
+
);
|
|
978
|
+
if (error) {
|
|
979
|
+
throw new Error(error);
|
|
980
|
+
}
|
|
981
|
+
} else {
|
|
982
|
+
throw new Error("Invalid config for platform " + this.source);
|
|
983
|
+
}
|
|
984
|
+
},
|
|
985
|
+
async getToken(config) {
|
|
986
|
+
if (tokenCache2 && tokenCache2.createdAt + 3500 * 1e3 > Date.now()) {
|
|
987
|
+
return tokenCache2;
|
|
988
|
+
}
|
|
989
|
+
if (!tokenPromise2) {
|
|
990
|
+
tokenPromise2 = (async () => {
|
|
991
|
+
const tokenResponse = await fetch(
|
|
992
|
+
`https://login.microsoftonline.com/${config.tenantId}/oauth2/v2.0/token`,
|
|
993
|
+
{
|
|
994
|
+
method: "POST",
|
|
995
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
996
|
+
headers: {
|
|
997
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
998
|
+
},
|
|
999
|
+
body: new URLSearchParams({
|
|
1000
|
+
client_id: config.client.id,
|
|
1001
|
+
client_secret: config.client.secret,
|
|
1002
|
+
refresh_token: config.refreshToken,
|
|
1003
|
+
grant_type: "refresh_token",
|
|
1004
|
+
scope: "https://ads.microsoft.com/msads.manage"
|
|
1005
|
+
})
|
|
1006
|
+
/* eslint-enable */
|
|
1007
|
+
}
|
|
1008
|
+
);
|
|
1009
|
+
if (!tokenResponse.ok) {
|
|
1010
|
+
throw new Error("Access token fetch failed");
|
|
1011
|
+
}
|
|
1012
|
+
const parsedTokenResponse = await tokenResponse.json();
|
|
1013
|
+
const createdAt = Date.now();
|
|
1014
|
+
tokenCache2 = { token: parsedTokenResponse.access_token, createdAt };
|
|
1015
|
+
tokenPromise2 = null;
|
|
1016
|
+
return tokenCache2;
|
|
1017
|
+
})();
|
|
1018
|
+
}
|
|
1019
|
+
return tokenPromise2;
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
|
|
842
1023
|
// src/publishers/piano.ts
|
|
843
1024
|
var piano = {
|
|
844
1025
|
source: "Piano",
|
|
@@ -951,20 +1132,16 @@ context.log.warn = function warn(str) {
|
|
|
951
1132
|
|
|
952
1133
|
// src/index.ts
|
|
953
1134
|
var publisher = {
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1135
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
1136
|
+
AffiliatePort: affiliatePort,
|
|
957
1137
|
CJ: cj,
|
|
958
|
-
|
|
1138
|
+
Facebook: facebook,
|
|
959
1139
|
GoogleAds: googleAds,
|
|
960
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
961
1140
|
GoogleAnalytics4: googleAnalytics4,
|
|
962
|
-
|
|
963
|
-
UniversalAnalytics: universalAnalytics,
|
|
964
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1141
|
+
MicrosoftAds: microsoftAds,
|
|
965
1142
|
Piano: piano,
|
|
966
|
-
|
|
967
|
-
|
|
1143
|
+
UniversalAnalytics: universalAnalytics
|
|
1144
|
+
/* eslint-enable */
|
|
968
1145
|
};
|
|
969
1146
|
// Annotate the CommonJS export names for ESM import in node:
|
|
970
1147
|
0 && (module.exports = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mhubcloud/tms_core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0-beta.0",
|
|
4
4
|
"description": "Core function for mHub Cloud TMS publishers",
|
|
5
5
|
"homepage": "https://mhubcloud.com/",
|
|
6
6
|
"license": "Apache 2.0",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"build": "tsup ./src/index.ts --format cjs --target node22"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@azure/cosmos": "^4.
|
|
24
|
+
"@azure/cosmos": "^4.7.0",
|
|
25
25
|
"@azure/data-tables": "^13.2.2",
|
|
26
26
|
"@azure/service-bus": "^7.9.5",
|
|
27
27
|
"ajv": "^8.12.0",
|