humanbehavior-js 0.1.2 → 0.1.4
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/cjs/index.js +235 -37
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +235 -37
- package/dist/esm/index.js.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/types/index.d.ts +29 -0
- package/package.json +1 -1
- package/src/api.ts +84 -21
- package/src/tracker.ts +203 -20
package/dist/cjs/index.js
CHANGED
|
@@ -4201,28 +4201,39 @@ class HumanBehaviorAPI {
|
|
|
4201
4201
|
entryURL = window.location.href;
|
|
4202
4202
|
referrer = document.referrer;
|
|
4203
4203
|
}
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4204
|
+
console.log('API init called with:', { sessionId, userId, entryURL, referrer, baseUrl: this.baseUrl });
|
|
4205
|
+
try {
|
|
4206
|
+
const response = yield fetch(`${this.baseUrl}/api/ingestion/init`, {
|
|
4207
|
+
method: 'POST',
|
|
4208
|
+
headers: {
|
|
4209
|
+
'Content-Type': 'application/json',
|
|
4210
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
4211
|
+
'Referer': referrer || ''
|
|
4212
|
+
},
|
|
4213
|
+
body: JSON.stringify({
|
|
4214
|
+
sessionId: sessionId,
|
|
4215
|
+
endUserId: userId,
|
|
4216
|
+
entryURL: entryURL,
|
|
4217
|
+
referrer: referrer
|
|
4218
|
+
})
|
|
4219
|
+
});
|
|
4220
|
+
console.log('API init response status:', response.status);
|
|
4221
|
+
if (!response.ok) {
|
|
4222
|
+
const errorText = yield response.text();
|
|
4223
|
+
console.error('API init failed:', response.status, errorText);
|
|
4224
|
+
throw new Error(`Failed to initialize ingestion: ${response.statusText} - ${errorText}`);
|
|
4225
|
+
}
|
|
4226
|
+
const responseJson = yield response.json();
|
|
4227
|
+
console.log('API init success:', responseJson);
|
|
4228
|
+
return {
|
|
4229
|
+
sessionId: responseJson.sessionId,
|
|
4230
|
+
endUserId: responseJson.endUserId
|
|
4231
|
+
};
|
|
4232
|
+
}
|
|
4233
|
+
catch (error) {
|
|
4234
|
+
console.error('API init error:', error);
|
|
4235
|
+
throw error;
|
|
4220
4236
|
}
|
|
4221
|
-
const responseJson = yield response.json();
|
|
4222
|
-
return {
|
|
4223
|
-
sessionId: responseJson.sessionId,
|
|
4224
|
-
endUserId: responseJson.endUserId
|
|
4225
|
-
};
|
|
4226
4237
|
});
|
|
4227
4238
|
}
|
|
4228
4239
|
sendEvents(events, sessionId, userId) {
|
|
@@ -4368,6 +4379,57 @@ class HumanBehaviorAPI {
|
|
|
4368
4379
|
data.append('apiKey', encodeURIComponent(this.apiKey));
|
|
4369
4380
|
navigator.sendBeacon(`${this.baseUrl}/api/ingestion/events`, data);
|
|
4370
4381
|
}
|
|
4382
|
+
sendCustomEvent(sessionId, eventName, eventProperties) {
|
|
4383
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4384
|
+
try {
|
|
4385
|
+
const response = yield fetch(`${this.baseUrl}/api/ingestion/customEvent`, {
|
|
4386
|
+
method: 'POST',
|
|
4387
|
+
headers: {
|
|
4388
|
+
'Content-Type': 'application/json',
|
|
4389
|
+
'Authorization': `Bearer ${this.apiKey}`
|
|
4390
|
+
},
|
|
4391
|
+
body: JSON.stringify({
|
|
4392
|
+
sessionId: sessionId,
|
|
4393
|
+
eventName: eventName,
|
|
4394
|
+
eventProperties: eventProperties || {}
|
|
4395
|
+
})
|
|
4396
|
+
});
|
|
4397
|
+
if (!response.ok) {
|
|
4398
|
+
throw new Error(`Failed to send custom event: ${response.statusText}`);
|
|
4399
|
+
}
|
|
4400
|
+
return yield response.json();
|
|
4401
|
+
}
|
|
4402
|
+
catch (error) {
|
|
4403
|
+
logError('Error sending custom event:', error);
|
|
4404
|
+
throw error;
|
|
4405
|
+
}
|
|
4406
|
+
});
|
|
4407
|
+
}
|
|
4408
|
+
sendCustomEventBatch(sessionId, events) {
|
|
4409
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4410
|
+
try {
|
|
4411
|
+
const response = yield fetch(`${this.baseUrl}/api/ingestion/customEvent/batch`, {
|
|
4412
|
+
method: 'POST',
|
|
4413
|
+
headers: {
|
|
4414
|
+
'Content-Type': 'application/json',
|
|
4415
|
+
'Authorization': `Bearer ${this.apiKey}`
|
|
4416
|
+
},
|
|
4417
|
+
body: JSON.stringify({
|
|
4418
|
+
sessionId: sessionId,
|
|
4419
|
+
events: events
|
|
4420
|
+
})
|
|
4421
|
+
});
|
|
4422
|
+
if (!response.ok) {
|
|
4423
|
+
throw new Error(`Failed to send custom event batch: ${response.statusText}`);
|
|
4424
|
+
}
|
|
4425
|
+
return yield response.json();
|
|
4426
|
+
}
|
|
4427
|
+
catch (error) {
|
|
4428
|
+
logError('Error sending custom event batch:', error);
|
|
4429
|
+
throw error;
|
|
4430
|
+
}
|
|
4431
|
+
});
|
|
4432
|
+
}
|
|
4371
4433
|
}
|
|
4372
4434
|
|
|
4373
4435
|
// Redaction functionality for sensitive input fields
|
|
@@ -4806,6 +4868,10 @@ class HumanBehaviorTracker {
|
|
|
4806
4868
|
if (options === null || options === void 0 ? void 0 : options.redactFields) {
|
|
4807
4869
|
tracker.setRedactedFields(options.redactFields);
|
|
4808
4870
|
}
|
|
4871
|
+
// Setup automatic tracking if enabled
|
|
4872
|
+
if ((options === null || options === void 0 ? void 0 : options.enableAutomaticTracking) !== false) {
|
|
4873
|
+
tracker.setupAutomaticTracking(options === null || options === void 0 ? void 0 : options.automaticTrackingOptions);
|
|
4874
|
+
}
|
|
4809
4875
|
// Test connection (non-blocking)
|
|
4810
4876
|
if (isBrowser) {
|
|
4811
4877
|
const testUrl = tracker.api['baseUrl'] + '/api/health';
|
|
@@ -4847,7 +4913,8 @@ class HumanBehaviorTracker {
|
|
|
4847
4913
|
throw new Error('Human Behavior API Key is required');
|
|
4848
4914
|
}
|
|
4849
4915
|
// Initialize API
|
|
4850
|
-
const defaultIngestionUrl = 'http://3.137.217.33:3000'; // AWS Development Server
|
|
4916
|
+
//const defaultIngestionUrl = 'http://3.137.217.33:3000'; // AWS Development Server
|
|
4917
|
+
const defaultIngestionUrl = 'http://ingestion-server-alb-1823866402.us-east-2.elb.amazonaws.com'; // ALB
|
|
4851
4918
|
this.api = new HumanBehaviorAPI({
|
|
4852
4919
|
apiKey: apiKey,
|
|
4853
4920
|
ingestionUrl: ingestionUrl || defaultIngestionUrl
|
|
@@ -5054,28 +5121,159 @@ class HumanBehaviorTracker {
|
|
|
5054
5121
|
if (!this.initialized)
|
|
5055
5122
|
return;
|
|
5056
5123
|
try {
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
properties: properties || {},
|
|
5060
|
-
timestamp: new Date().toISOString(),
|
|
5061
|
-
url: window.location.href,
|
|
5062
|
-
pathname: window.location.pathname
|
|
5063
|
-
};
|
|
5064
|
-
// Add custom event to the main event stream
|
|
5065
|
-
yield this.addEvent({
|
|
5066
|
-
type: 5, // Custom event type
|
|
5067
|
-
data: {
|
|
5068
|
-
payload: Object.assign({ eventType: 'custom' }, customEventData)
|
|
5069
|
-
},
|
|
5070
|
-
timestamp: Date.now()
|
|
5071
|
-
});
|
|
5124
|
+
// Send custom event directly to the API
|
|
5125
|
+
yield this.api.sendCustomEvent(this.sessionId, eventName, properties);
|
|
5072
5126
|
logDebug(`Custom event tracked: ${eventName}`, properties);
|
|
5073
5127
|
}
|
|
5074
5128
|
catch (error) {
|
|
5075
5129
|
logError('Failed to track custom event:', error);
|
|
5130
|
+
// Fallback: add to event stream if direct API call fails
|
|
5131
|
+
try {
|
|
5132
|
+
const customEventData = {
|
|
5133
|
+
eventName: eventName,
|
|
5134
|
+
properties: properties || {},
|
|
5135
|
+
timestamp: new Date().toISOString(),
|
|
5136
|
+
url: window.location.href,
|
|
5137
|
+
pathname: window.location.pathname
|
|
5138
|
+
};
|
|
5139
|
+
yield this.addEvent({
|
|
5140
|
+
type: 5, // Custom event type
|
|
5141
|
+
data: {
|
|
5142
|
+
payload: Object.assign({ eventType: 'custom' }, customEventData)
|
|
5143
|
+
},
|
|
5144
|
+
timestamp: Date.now()
|
|
5145
|
+
});
|
|
5146
|
+
logDebug(`Custom event added to event stream as fallback: ${eventName}`);
|
|
5147
|
+
}
|
|
5148
|
+
catch (fallbackError) {
|
|
5149
|
+
logError('Failed to add custom event to event stream as fallback:', fallbackError);
|
|
5150
|
+
}
|
|
5076
5151
|
}
|
|
5077
5152
|
});
|
|
5078
5153
|
}
|
|
5154
|
+
/**
|
|
5155
|
+
* Setup automatic tracking for buttons, links, and forms
|
|
5156
|
+
*/
|
|
5157
|
+
setupAutomaticTracking(options) {
|
|
5158
|
+
if (!isBrowser)
|
|
5159
|
+
return;
|
|
5160
|
+
const config = {
|
|
5161
|
+
trackButtons: (options === null || options === void 0 ? void 0 : options.trackButtons) !== false,
|
|
5162
|
+
trackLinks: (options === null || options === void 0 ? void 0 : options.trackLinks) !== false,
|
|
5163
|
+
trackForms: (options === null || options === void 0 ? void 0 : options.trackForms) !== false,
|
|
5164
|
+
includeText: (options === null || options === void 0 ? void 0 : options.includeText) !== false,
|
|
5165
|
+
includeClasses: (options === null || options === void 0 ? void 0 : options.includeClasses) || false
|
|
5166
|
+
};
|
|
5167
|
+
logDebug('Setting up automatic tracking with config:', config);
|
|
5168
|
+
// Setup button tracking
|
|
5169
|
+
if (config.trackButtons) {
|
|
5170
|
+
this.setupAutomaticButtonTracking(config);
|
|
5171
|
+
}
|
|
5172
|
+
// Setup link tracking
|
|
5173
|
+
if (config.trackLinks) {
|
|
5174
|
+
this.setupAutomaticLinkTracking(config);
|
|
5175
|
+
}
|
|
5176
|
+
// Setup form tracking
|
|
5177
|
+
if (config.trackForms) {
|
|
5178
|
+
this.setupAutomaticFormTracking(config);
|
|
5179
|
+
}
|
|
5180
|
+
}
|
|
5181
|
+
/**
|
|
5182
|
+
* Setup automatic button tracking
|
|
5183
|
+
*/
|
|
5184
|
+
setupAutomaticButtonTracking(config) {
|
|
5185
|
+
document.addEventListener('click', (event) => __awaiter$1(this, void 0, void 0, function* () {
|
|
5186
|
+
var _a;
|
|
5187
|
+
const target = event.target;
|
|
5188
|
+
// Track button clicks
|
|
5189
|
+
if (target.tagName === 'BUTTON' || target.closest('button')) {
|
|
5190
|
+
const button = target.tagName === 'BUTTON'
|
|
5191
|
+
? target
|
|
5192
|
+
: target.closest('button');
|
|
5193
|
+
const properties = {
|
|
5194
|
+
buttonId: button.id || null,
|
|
5195
|
+
buttonType: button.type || 'button',
|
|
5196
|
+
page: window.location.pathname,
|
|
5197
|
+
timestamp: Date.now()
|
|
5198
|
+
};
|
|
5199
|
+
if (config.includeText) {
|
|
5200
|
+
properties.buttonText = ((_a = button.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || null;
|
|
5201
|
+
}
|
|
5202
|
+
if (config.includeClasses) {
|
|
5203
|
+
properties.buttonClass = button.className || null;
|
|
5204
|
+
}
|
|
5205
|
+
// Remove null values
|
|
5206
|
+
Object.keys(properties).forEach(key => {
|
|
5207
|
+
if (properties[key] === null) {
|
|
5208
|
+
delete properties[key];
|
|
5209
|
+
}
|
|
5210
|
+
});
|
|
5211
|
+
yield this.customEvent('button_clicked', properties);
|
|
5212
|
+
}
|
|
5213
|
+
}));
|
|
5214
|
+
}
|
|
5215
|
+
/**
|
|
5216
|
+
* Setup automatic link tracking
|
|
5217
|
+
*/
|
|
5218
|
+
setupAutomaticLinkTracking(config) {
|
|
5219
|
+
document.addEventListener('click', (event) => __awaiter$1(this, void 0, void 0, function* () {
|
|
5220
|
+
var _a;
|
|
5221
|
+
const target = event.target;
|
|
5222
|
+
// Track link clicks
|
|
5223
|
+
if (target.tagName === 'A' || target.closest('a')) {
|
|
5224
|
+
const link = target.tagName === 'A'
|
|
5225
|
+
? target
|
|
5226
|
+
: target.closest('a');
|
|
5227
|
+
const properties = {
|
|
5228
|
+
linkUrl: link.href || null,
|
|
5229
|
+
linkId: link.id || null,
|
|
5230
|
+
linkTarget: link.target || null,
|
|
5231
|
+
page: window.location.pathname,
|
|
5232
|
+
timestamp: Date.now()
|
|
5233
|
+
};
|
|
5234
|
+
if (config.includeText) {
|
|
5235
|
+
properties.linkText = ((_a = link.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || null;
|
|
5236
|
+
}
|
|
5237
|
+
if (config.includeClasses) {
|
|
5238
|
+
properties.linkClass = link.className || null;
|
|
5239
|
+
}
|
|
5240
|
+
// Remove null values
|
|
5241
|
+
Object.keys(properties).forEach(key => {
|
|
5242
|
+
if (properties[key] === null) {
|
|
5243
|
+
delete properties[key];
|
|
5244
|
+
}
|
|
5245
|
+
});
|
|
5246
|
+
yield this.customEvent('link_clicked', properties);
|
|
5247
|
+
}
|
|
5248
|
+
}));
|
|
5249
|
+
}
|
|
5250
|
+
/**
|
|
5251
|
+
* Setup automatic form tracking
|
|
5252
|
+
*/
|
|
5253
|
+
setupAutomaticFormTracking(config) {
|
|
5254
|
+
document.addEventListener('submit', (event) => __awaiter$1(this, void 0, void 0, function* () {
|
|
5255
|
+
const form = event.target;
|
|
5256
|
+
const formData = new FormData(form);
|
|
5257
|
+
const properties = {
|
|
5258
|
+
formId: form.id || null,
|
|
5259
|
+
formAction: form.action || null,
|
|
5260
|
+
formMethod: form.method || 'get',
|
|
5261
|
+
fields: Array.from(formData.keys()),
|
|
5262
|
+
page: window.location.pathname,
|
|
5263
|
+
timestamp: Date.now()
|
|
5264
|
+
};
|
|
5265
|
+
if (config.includeClasses) {
|
|
5266
|
+
properties.formClass = form.className || null;
|
|
5267
|
+
}
|
|
5268
|
+
// Remove null values
|
|
5269
|
+
Object.keys(properties).forEach(key => {
|
|
5270
|
+
if (properties[key] === null) {
|
|
5271
|
+
delete properties[key];
|
|
5272
|
+
}
|
|
5273
|
+
});
|
|
5274
|
+
yield this.customEvent('form_submitted', properties);
|
|
5275
|
+
}));
|
|
5276
|
+
}
|
|
5079
5277
|
/**
|
|
5080
5278
|
* Cleanup navigation tracking
|
|
5081
5279
|
*/
|