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