posthog-js 1.347.2 → 1.348.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/array.full.es5.js +1 -1
- package/dist/array.full.js +1 -1
- package/dist/array.full.no-external.js +1 -1
- package/dist/array.js +1 -1
- package/dist/array.no-external.js +1 -1
- package/dist/conversations.js +1 -1
- package/dist/conversations.js.map +1 -1
- package/dist/customizations.full.js +1 -1
- package/dist/lazy-recorder.js +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/module.d.ts +43 -1
- package/dist/module.full.d.ts +43 -1
- package/dist/module.full.js +1 -1
- package/dist/module.full.js.map +1 -1
- package/dist/module.full.no-external.d.ts +43 -1
- package/dist/module.full.no-external.js +1 -1
- package/dist/module.full.no-external.js.map +1 -1
- package/dist/module.js +1 -1
- package/dist/module.js.map +1 -1
- package/dist/module.no-external.d.ts +43 -1
- package/dist/module.no-external.js +1 -1
- package/dist/module.no-external.js.map +1 -1
- package/dist/posthog-recorder.js +1 -1
- package/dist/product-tours-preview.d.ts +2 -0
- package/dist/product-tours-preview.js +1 -1
- package/dist/product-tours-preview.js.map +1 -1
- package/dist/product-tours.js +1 -1
- package/dist/product-tours.js.map +1 -1
- package/dist/src/extensions/conversations/external/components/ConversationsWidget.d.ts +43 -2
- package/dist/src/extensions/conversations/external/components/TicketListItem.d.ts +13 -0
- package/dist/src/extensions/conversations/external/components/TicketListView.d.ts +15 -0
- package/dist/src/extensions/conversations/external/components/styles.d.ts +184 -0
- package/dist/src/extensions/conversations/external/components/utils.d.ts +8 -0
- package/dist/src/extensions/conversations/external/index.d.ts +39 -1
- package/dist/src/extensions/product-tours/product-tours.d.ts +2 -0
- package/dist/src/posthog-product-tours-types.d.ts +42 -0
- package/dist/surveys-preview.d.ts +2 -0
- package/lib/package.json +1 -1
- package/lib/src/extensions/conversations/external/components/ConversationsWidget.d.ts +43 -2
- package/lib/src/extensions/conversations/external/components/ConversationsWidget.js +96 -28
- package/lib/src/extensions/conversations/external/components/ConversationsWidget.js.map +1 -1
- package/lib/src/extensions/conversations/external/components/TicketListItem.d.ts +13 -0
- package/lib/src/extensions/conversations/external/components/TicketListItem.js +47 -0
- package/lib/src/extensions/conversations/external/components/TicketListItem.js.map +1 -0
- package/lib/src/extensions/conversations/external/components/TicketListView.d.ts +15 -0
- package/lib/src/extensions/conversations/external/components/TicketListView.js +75 -0
- package/lib/src/extensions/conversations/external/components/TicketListView.js.map +1 -0
- package/lib/src/extensions/conversations/external/components/styles.d.ts +184 -0
- package/lib/src/extensions/conversations/external/components/styles.js +189 -0
- package/lib/src/extensions/conversations/external/components/styles.js.map +1 -1
- package/lib/src/extensions/conversations/external/components/utils.d.ts +8 -0
- package/lib/src/extensions/conversations/external/components/utils.js +49 -0
- package/lib/src/extensions/conversations/external/components/utils.js.map +1 -0
- package/lib/src/extensions/conversations/external/index.d.ts +39 -1
- package/lib/src/extensions/conversations/external/index.js +253 -31
- package/lib/src/extensions/conversations/external/index.js.map +1 -1
- package/lib/src/extensions/product-tours/components/ProductTourSurveyStepInner.js +1 -1
- package/lib/src/extensions/product-tours/components/ProductTourSurveyStepInner.js.map +1 -1
- package/lib/src/extensions/product-tours/product-tours.d.ts +2 -0
- package/lib/src/extensions/product-tours/product-tours.js +78 -71
- package/lib/src/extensions/product-tours/product-tours.js.map +1 -1
- package/lib/src/posthog-product-tours-types.d.ts +42 -0
- package/lib/src/posthog-product-tours-types.js +43 -1
- package/lib/src/posthog-product-tours-types.js.map +1 -1
- package/lib/src/utils/product-tour-event-receiver.js +2 -1
- package/lib/src/utils/product-tour-event-receiver.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/react/dist/esm/index.js +25 -1
- package/react/dist/esm/index.js.map +1 -1
- package/react/dist/types/index.d.ts +4 -2
- package/react/dist/umd/index.js +25 -0
- package/react/dist/umd/index.js.map +1 -1
|
@@ -104,6 +104,11 @@ var ConversationsManager = /** @class */ (function () {
|
|
|
104
104
|
this._unsubscribeIdentifyListener = null;
|
|
105
105
|
this._unreadCount = 0;
|
|
106
106
|
this._isWidgetRendered = false;
|
|
107
|
+
this._initializeWidgetPromise = null;
|
|
108
|
+
// View state management for ticket list vs message view
|
|
109
|
+
this._currentView = 'messages';
|
|
110
|
+
this._tickets = [];
|
|
111
|
+
this._hasMultipleTickets = false;
|
|
107
112
|
/**
|
|
108
113
|
* Handle user identification from the widget form
|
|
109
114
|
*/
|
|
@@ -152,17 +157,18 @@ var ConversationsManager = /** @class */ (function () {
|
|
|
152
157
|
* Handle widget state changes
|
|
153
158
|
*/
|
|
154
159
|
this._handleStateChange = function (state) {
|
|
155
|
-
logger.info('Widget state changed', { state: state });
|
|
160
|
+
logger.info('Widget state changed', { state: state, view: _this._currentView });
|
|
156
161
|
// Track state changes
|
|
157
162
|
_this._posthog.capture('$conversations_widget_state_changed', {
|
|
158
163
|
state: state,
|
|
164
|
+
view: _this._currentView,
|
|
159
165
|
ticketId: _this._currentTicketId,
|
|
160
166
|
});
|
|
161
167
|
// Save state to localStorage
|
|
162
168
|
_this._persistence.saveWidgetState(state);
|
|
163
|
-
// Mark messages as read when widget opens
|
|
169
|
+
// Mark messages as read when widget opens (only if in message view with a ticket)
|
|
164
170
|
if (state === 'open') {
|
|
165
|
-
if (_this._unreadCount > 0 && _this._currentTicketId) {
|
|
171
|
+
if (_this._currentView === 'messages' && _this._unreadCount > 0 && _this._currentTicketId) {
|
|
166
172
|
_this._markMessagesAsRead();
|
|
167
173
|
}
|
|
168
174
|
}
|
|
@@ -192,6 +198,131 @@ var ConversationsManager = /** @class */ (function () {
|
|
|
192
198
|
}
|
|
193
199
|
});
|
|
194
200
|
}); };
|
|
201
|
+
/**
|
|
202
|
+
* Poll for tickets list
|
|
203
|
+
*/
|
|
204
|
+
this._pollTickets = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
205
|
+
return __generator(this, function (_a) {
|
|
206
|
+
switch (_a.label) {
|
|
207
|
+
case 0:
|
|
208
|
+
if (this._isPolling) {
|
|
209
|
+
return [2 /*return*/];
|
|
210
|
+
}
|
|
211
|
+
this._isPolling = true;
|
|
212
|
+
_a.label = 1;
|
|
213
|
+
case 1:
|
|
214
|
+
_a.trys.push([1, , 3, 4]);
|
|
215
|
+
return [4 /*yield*/, this._loadTickets()];
|
|
216
|
+
case 2:
|
|
217
|
+
_a.sent();
|
|
218
|
+
return [3 /*break*/, 4];
|
|
219
|
+
case 3:
|
|
220
|
+
this._isPolling = false;
|
|
221
|
+
return [7 /*endfinally*/];
|
|
222
|
+
case 4: return [2 /*return*/];
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}); };
|
|
226
|
+
/**
|
|
227
|
+
* Main poll function that polls based on current view
|
|
228
|
+
*/
|
|
229
|
+
this._poll = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
230
|
+
return __generator(this, function (_a) {
|
|
231
|
+
switch (_a.label) {
|
|
232
|
+
case 0:
|
|
233
|
+
if (!(this._currentView === 'tickets')) return [3 /*break*/, 2];
|
|
234
|
+
return [4 /*yield*/, this._pollTickets()];
|
|
235
|
+
case 1:
|
|
236
|
+
_a.sent();
|
|
237
|
+
return [3 /*break*/, 4];
|
|
238
|
+
case 2: return [4 /*yield*/, this._pollMessages()];
|
|
239
|
+
case 3:
|
|
240
|
+
_a.sent();
|
|
241
|
+
_a.label = 4;
|
|
242
|
+
case 4: return [2 /*return*/];
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}); };
|
|
246
|
+
/**
|
|
247
|
+
* Handle view changes from the widget
|
|
248
|
+
*/
|
|
249
|
+
this._handleViewChange = function (view) {
|
|
250
|
+
logger.info('View changed', { from: _this._currentView, to: view });
|
|
251
|
+
_this._currentView = view;
|
|
252
|
+
};
|
|
253
|
+
/**
|
|
254
|
+
* Handle ticket selection from the list
|
|
255
|
+
*/
|
|
256
|
+
this._handleSelectTicket = function (ticketId) { return __awaiter(_this, void 0, void 0, function () {
|
|
257
|
+
var _a, _b;
|
|
258
|
+
return __generator(this, function (_c) {
|
|
259
|
+
switch (_c.label) {
|
|
260
|
+
case 0:
|
|
261
|
+
// Switch to this ticket
|
|
262
|
+
this._switchToTicketIfNeeded(ticketId);
|
|
263
|
+
// Clear messages and reset timestamp
|
|
264
|
+
this._lastMessageTimestamp = null;
|
|
265
|
+
(_a = this._widgetRef) === null || _a === void 0 ? void 0 : _a.clearMessages();
|
|
266
|
+
// Switch view to messages
|
|
267
|
+
this._currentView = 'messages';
|
|
268
|
+
(_b = this._widgetRef) === null || _b === void 0 ? void 0 : _b.setView('messages');
|
|
269
|
+
// Load messages for the selected ticket
|
|
270
|
+
return [4 /*yield*/, this._loadMessages()
|
|
271
|
+
// Mark as read if widget is open
|
|
272
|
+
];
|
|
273
|
+
case 1:
|
|
274
|
+
// Load messages for the selected ticket
|
|
275
|
+
_c.sent();
|
|
276
|
+
// Mark as read if widget is open
|
|
277
|
+
if (this._isWidgetOpen() && this._unreadCount > 0) {
|
|
278
|
+
this._markMessagesAsRead();
|
|
279
|
+
}
|
|
280
|
+
return [2 /*return*/];
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
}); };
|
|
284
|
+
/**
|
|
285
|
+
* Handle new conversation request
|
|
286
|
+
*/
|
|
287
|
+
this._handleNewConversation = function () {
|
|
288
|
+
var _a, _b;
|
|
289
|
+
logger.info('New conversation requested');
|
|
290
|
+
// Clear current ticket
|
|
291
|
+
_this._currentTicketId = null;
|
|
292
|
+
_this._persistence.clearTicketId();
|
|
293
|
+
// Reset timestamp
|
|
294
|
+
_this._lastMessageTimestamp = null;
|
|
295
|
+
// Switch view to messages
|
|
296
|
+
_this._currentView = 'messages';
|
|
297
|
+
(_a = _this._widgetRef) === null || _a === void 0 ? void 0 : _a.setView('messages');
|
|
298
|
+
// Clear messages and add greeting
|
|
299
|
+
(_b = _this._widgetRef) === null || _b === void 0 ? void 0 : _b.clearMessages(true);
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* Handle back to tickets request
|
|
303
|
+
*/
|
|
304
|
+
this._handleBackToTickets = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
305
|
+
var _a, _b;
|
|
306
|
+
return __generator(this, function (_c) {
|
|
307
|
+
switch (_c.label) {
|
|
308
|
+
case 0:
|
|
309
|
+
logger.info('Back to tickets requested');
|
|
310
|
+
// Switch view to tickets
|
|
311
|
+
this._currentView = 'tickets';
|
|
312
|
+
(_a = this._widgetRef) === null || _a === void 0 ? void 0 : _a.setView('tickets');
|
|
313
|
+
// Load tickets
|
|
314
|
+
(_b = this._widgetRef) === null || _b === void 0 ? void 0 : _b.setTicketsLoading(true);
|
|
315
|
+
return [4 /*yield*/, this._loadTickets()
|
|
316
|
+
// Track back to tickets
|
|
317
|
+
];
|
|
318
|
+
case 1:
|
|
319
|
+
_c.sent();
|
|
320
|
+
// Track back to tickets
|
|
321
|
+
this._posthog.capture('$conversations_back_to_tickets');
|
|
322
|
+
return [2 /*return*/];
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
}); };
|
|
195
326
|
this._config = config;
|
|
196
327
|
this._persistence = new persistence_1.ConversationsPersistence(_posthog);
|
|
197
328
|
// Get or create widget_session_id - this stays the same even when user identifies
|
|
@@ -467,34 +598,55 @@ var ConversationsManager = /** @class */ (function () {
|
|
|
467
598
|
};
|
|
468
599
|
/**
|
|
469
600
|
* Initialize and render the widget UI
|
|
601
|
+
* Uses a promise guard to prevent race conditions from concurrent calls
|
|
470
602
|
*/
|
|
471
603
|
ConversationsManager.prototype._initializeWidget = function () {
|
|
472
604
|
if (this._isWidgetRendered) {
|
|
473
|
-
return;
|
|
605
|
+
return Promise.resolve();
|
|
474
606
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
if (savedState === 'open') {
|
|
478
|
-
initialState = 'open';
|
|
607
|
+
if (this._initializeWidgetPromise) {
|
|
608
|
+
return this._initializeWidgetPromise;
|
|
479
609
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
this
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
610
|
+
this._initializeWidgetPromise = this._doInitializeWidget();
|
|
611
|
+
return this._initializeWidgetPromise;
|
|
612
|
+
};
|
|
613
|
+
ConversationsManager.prototype._doInitializeWidget = function () {
|
|
614
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
615
|
+
var savedState, initialState, initialUserTraits, _a, initialView, tickets;
|
|
616
|
+
return __generator(this, function (_b) {
|
|
617
|
+
switch (_b.label) {
|
|
618
|
+
case 0:
|
|
619
|
+
savedState = this._persistence.loadWidgetState();
|
|
620
|
+
initialState = 'closed';
|
|
621
|
+
if (savedState === 'open') {
|
|
622
|
+
initialState = 'open';
|
|
623
|
+
}
|
|
624
|
+
initialUserTraits = this._getInitialUserTraits();
|
|
625
|
+
return [4 /*yield*/, this._determineInitialView()];
|
|
626
|
+
case 1:
|
|
627
|
+
_a = _b.sent(), initialView = _a.view, tickets = _a.tickets;
|
|
628
|
+
this._currentView = initialView;
|
|
629
|
+
// Render the widget with initial view
|
|
630
|
+
this._renderWidget(initialState, initialUserTraits, initialView, tickets);
|
|
631
|
+
this._isWidgetRendered = true;
|
|
632
|
+
// Track widget initialization
|
|
633
|
+
this._posthog.capture('$conversations_widget_loaded', {
|
|
634
|
+
hasExistingTicket: !!this._currentTicketId,
|
|
635
|
+
initialState: initialState,
|
|
636
|
+
initialView: initialView,
|
|
637
|
+
ticketCount: tickets.length,
|
|
638
|
+
hasUserTraits: !!initialUserTraits,
|
|
639
|
+
});
|
|
640
|
+
// Load messages if in message view and have a ticket
|
|
641
|
+
if (initialView === 'messages' && this._currentTicketId) {
|
|
642
|
+
this._loadMessages();
|
|
643
|
+
}
|
|
644
|
+
// Start polling based on current view
|
|
645
|
+
this._startPolling();
|
|
646
|
+
return [2 /*return*/];
|
|
647
|
+
}
|
|
648
|
+
});
|
|
490
649
|
});
|
|
491
|
-
// Set up polling and load messages only when widget is rendered
|
|
492
|
-
// If we have a ticket, load its messages
|
|
493
|
-
if (this._currentTicketId) {
|
|
494
|
-
this._loadMessages();
|
|
495
|
-
}
|
|
496
|
-
// Start polling for messages to keep widget UI updated
|
|
497
|
-
this._startPolling();
|
|
498
650
|
};
|
|
499
651
|
/**
|
|
500
652
|
* Get initial user traits from PostHog or localStorage
|
|
@@ -604,7 +756,74 @@ var ConversationsManager = /** @class */ (function () {
|
|
|
604
756
|
return this._persistence.loadWidgetState() === 'open';
|
|
605
757
|
};
|
|
606
758
|
/**
|
|
607
|
-
*
|
|
759
|
+
* Load tickets list from API
|
|
760
|
+
*/
|
|
761
|
+
ConversationsManager.prototype._loadTickets = function () {
|
|
762
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
763
|
+
var response, totalUnread, error_4;
|
|
764
|
+
var _a, _b;
|
|
765
|
+
return __generator(this, function (_c) {
|
|
766
|
+
switch (_c.label) {
|
|
767
|
+
case 0:
|
|
768
|
+
_c.trys.push([0, 2, , 3]);
|
|
769
|
+
return [4 /*yield*/, this.getTickets()];
|
|
770
|
+
case 1:
|
|
771
|
+
response = _c.sent();
|
|
772
|
+
this._tickets = response.results;
|
|
773
|
+
this._hasMultipleTickets = response.results.length > 1;
|
|
774
|
+
(_a = this._widgetRef) === null || _a === void 0 ? void 0 : _a.updateTickets(response.results);
|
|
775
|
+
totalUnread = response.results.reduce(function (sum, t) { return sum + (t.unread_count || 0); }, 0);
|
|
776
|
+
this._unreadCount = totalUnread;
|
|
777
|
+
(_b = this._widgetRef) === null || _b === void 0 ? void 0 : _b.setUnreadCount(totalUnread);
|
|
778
|
+
logger.info('Tickets loaded', { count: response.results.length, totalUnread: totalUnread });
|
|
779
|
+
return [3 /*break*/, 3];
|
|
780
|
+
case 2:
|
|
781
|
+
error_4 = _c.sent();
|
|
782
|
+
logger.error('Failed to load tickets', error_4);
|
|
783
|
+
return [3 /*break*/, 3];
|
|
784
|
+
case 3: return [2 /*return*/];
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
});
|
|
788
|
+
};
|
|
789
|
+
/**
|
|
790
|
+
* Determine initial view based on ticket count
|
|
791
|
+
*/
|
|
792
|
+
ConversationsManager.prototype._determineInitialView = function () {
|
|
793
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
794
|
+
var response, totalUnread, error_5;
|
|
795
|
+
return __generator(this, function (_a) {
|
|
796
|
+
switch (_a.label) {
|
|
797
|
+
case 0:
|
|
798
|
+
_a.trys.push([0, 2, , 3]);
|
|
799
|
+
return [4 /*yield*/, this.getTickets()];
|
|
800
|
+
case 1:
|
|
801
|
+
response = _a.sent();
|
|
802
|
+
this._tickets = response.results;
|
|
803
|
+
this._hasMultipleTickets = response.results.length > 1;
|
|
804
|
+
totalUnread = response.results.reduce(function (sum, t) { return sum + (t.unread_count || 0); }, 0);
|
|
805
|
+
this._unreadCount = totalUnread;
|
|
806
|
+
// If 2+ tickets, show ticket list; otherwise show messages
|
|
807
|
+
if (response.results.length >= 2) {
|
|
808
|
+
return [2 /*return*/, { view: 'tickets', tickets: response.results }];
|
|
809
|
+
}
|
|
810
|
+
// If exactly 1 ticket, set it as current
|
|
811
|
+
if (response.results.length === 1) {
|
|
812
|
+
this._currentTicketId = response.results[0].id;
|
|
813
|
+
this._persistence.saveTicketId(response.results[0].id);
|
|
814
|
+
}
|
|
815
|
+
return [2 /*return*/, { view: 'messages', tickets: response.results }];
|
|
816
|
+
case 2:
|
|
817
|
+
error_5 = _a.sent();
|
|
818
|
+
logger.error('Failed to determine initial view', error_5);
|
|
819
|
+
return [2 /*return*/, { view: 'messages', tickets: [] }];
|
|
820
|
+
case 3: return [2 /*return*/];
|
|
821
|
+
}
|
|
822
|
+
});
|
|
823
|
+
});
|
|
824
|
+
};
|
|
825
|
+
/**
|
|
826
|
+
* Start polling based on current view
|
|
608
827
|
*/
|
|
609
828
|
ConversationsManager.prototype._startPolling = function () {
|
|
610
829
|
var _this = this;
|
|
@@ -612,12 +831,12 @@ var ConversationsManager = /** @class */ (function () {
|
|
|
612
831
|
return; // Already polling
|
|
613
832
|
}
|
|
614
833
|
// Poll immediately
|
|
615
|
-
this.
|
|
834
|
+
this._poll();
|
|
616
835
|
// Set up interval
|
|
617
836
|
this._pollIntervalId = globals_1.window === null || globals_1.window === void 0 ? void 0 : globals_1.window.setInterval(function () {
|
|
618
|
-
_this.
|
|
837
|
+
_this._poll();
|
|
619
838
|
}, POLL_INTERVAL_MS);
|
|
620
|
-
logger.info('Started polling
|
|
839
|
+
logger.info('Started polling', { view: this._currentView });
|
|
621
840
|
};
|
|
622
841
|
/**
|
|
623
842
|
* Stop polling for new messages
|
|
@@ -674,6 +893,7 @@ var ConversationsManager = /** @class */ (function () {
|
|
|
674
893
|
}
|
|
675
894
|
this._widgetRef = null;
|
|
676
895
|
this._isWidgetRendered = false;
|
|
896
|
+
this._initializeWidgetPromise = null;
|
|
677
897
|
// Reset timestamp so show() will re-fetch all messages
|
|
678
898
|
this._lastMessageTimestamp = null;
|
|
679
899
|
};
|
|
@@ -781,8 +1001,10 @@ var ConversationsManager = /** @class */ (function () {
|
|
|
781
1001
|
/**
|
|
782
1002
|
* Render the widget to the DOM
|
|
783
1003
|
*/
|
|
784
|
-
ConversationsManager.prototype._renderWidget = function (initialState, initialUserTraits) {
|
|
1004
|
+
ConversationsManager.prototype._renderWidget = function (initialState, initialUserTraits, initialView, initialTickets) {
|
|
785
1005
|
var _this = this;
|
|
1006
|
+
if (initialView === void 0) { initialView = 'messages'; }
|
|
1007
|
+
if (initialTickets === void 0) { initialTickets = []; }
|
|
786
1008
|
if (!globals_1.document) {
|
|
787
1009
|
logger.info('Conversations widget not rendered: Document not available');
|
|
788
1010
|
return;
|
|
@@ -802,7 +1024,7 @@ var ConversationsManager = /** @class */ (function () {
|
|
|
802
1024
|
// Render widget with ref
|
|
803
1025
|
(0, preact_1.render)((0, jsx_runtime_1.jsx)(ConversationsWidget_1.ConversationsWidget, { ref: function (ref) {
|
|
804
1026
|
_this._widgetRef = ref;
|
|
805
|
-
}, config: this._config, initialState: initialState, initialUserTraits: initialUserTraits, isUserIdentified: this._posthog._isIdentified(), onSendMessage: this._handleSendMessage, onStateChange: this._handleStateChange, onIdentify: this._handleIdentify }), container);
|
|
1027
|
+
}, config: this._config, initialState: initialState, initialUserTraits: initialUserTraits, isUserIdentified: this._posthog._isIdentified(), initialView: initialView, initialTickets: initialTickets, hasMultipleTickets: this._hasMultipleTickets, onSendMessage: this._handleSendMessage, onStateChange: this._handleStateChange, onIdentify: this._handleIdentify, onSelectTicket: this._handleSelectTicket, onNewConversation: this._handleNewConversation, onBackToTickets: this._handleBackToTickets, onViewChange: this._handleViewChange }), container);
|
|
806
1028
|
};
|
|
807
1029
|
return ConversationsManager;
|
|
808
1030
|
}());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/extensions/conversations/external/index.tsx"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { render, h } from 'preact'\nimport { isNumber } from '@posthog/core'\nimport {\n ConversationsRemoteConfig,\n ConversationsWidgetState,\n UserProvidedTraits,\n SendMessageResponse,\n SendMessagePayload,\n GetMessagesResponse,\n MarkAsReadResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n} from '../../../posthog-conversations-types'\nimport { PostHog } from '../../../posthog-core'\nimport { ConversationsManager as ConversationsManagerInterface } from '../posthog-conversations'\nimport { ConversationsPersistence } from './persistence'\nimport { ConversationsWidget } from './components/ConversationsWidget'\nimport { createLogger } from '../../../utils/logger'\nimport { document, window } from '../../../utils/globals'\nimport { formDataToQuery } from '../../../utils/request-utils'\n\nconst logger = createLogger('[ConversationsManager]')\n\nconst WIDGET_CONTAINER_ID = 'ph-conversations-widget-container'\nconst POLL_INTERVAL_MS = 5000 // 5 seconds\n\n/**\n * Extract hostname from a domain string (handles URLs and plain hostnames)\n */\nfunction extractHostname(domain: string): string | null {\n // Remove protocol if present\n let hostname = domain.replace(/^https?:\\/\\//, '')\n // Remove path, query, port if present\n hostname = hostname.split('/')[0].split('?')[0].split(':')[0]\n return hostname || null\n}\n\n/**\n * Check if the current domain matches the allowed domains list.\n * Returns true if:\n * - domains is empty or not present (no restriction)\n * - current hostname matches any allowed domain\n */\nfunction isCurrentDomainAllowed(domains: string[] | undefined): boolean {\n // No domain restriction - allow all\n if (!domains || domains.length === 0) {\n return true\n }\n\n const currentHostname = window?.location?.hostname\n if (!currentHostname) {\n // Can't determine hostname (SSR, etc.) - allow by default\n return true\n }\n\n return domains.some((domain) => {\n const allowedHostname = extractHostname(domain)\n if (!allowedHostname) {\n return false\n }\n\n if (allowedHostname.startsWith('*.')) {\n // Wildcard match: *.example.com matches foo.example.com and example.com\n const pattern = allowedHostname.slice(2) // Remove \"*.\"\n return currentHostname.endsWith(`.${pattern}`) || currentHostname === pattern\n }\n\n // Exact match\n return currentHostname === allowedHostname\n })\n}\n\nexport class ConversationsManager implements ConversationsManagerInterface {\n private _config: ConversationsRemoteConfig\n private _persistence: ConversationsPersistence\n private _widgetRef: ConversationsWidget | null = null\n private _containerElement: HTMLDivElement | null = null\n private _currentTicketId: string | null = null\n private _pollIntervalId: number | null = null\n private _lastMessageTimestamp: string | null = null\n private _isPolling: boolean = false\n private _unsubscribeIdentifyListener: (() => void) | null = null\n private _unreadCount: number = 0\n // SECURITY: widget_session_id is the key for access control\n // This is a random UUID that only this browser knows\n private _widgetSessionId: string\n private _isWidgetEnabled: boolean\n private _isDomainAllowed: boolean\n private _isWidgetRendered: boolean = false\n\n constructor(\n config: ConversationsRemoteConfig,\n private readonly _posthog: PostHog\n ) {\n this._config = config\n this._persistence = new ConversationsPersistence(_posthog)\n // Get or create widget_session_id - this stays the same even when user identifies\n this._widgetSessionId = this._persistence.getOrCreateWidgetSessionId()\n\n // Determine if widget should be shown based on config and domain\n this._isWidgetEnabled = config.widgetEnabled === true\n this._isDomainAllowed = isCurrentDomainAllowed(config.domains)\n\n logger.info('ConversationsManager initialized', {\n config,\n widgetSessionId: this._widgetSessionId,\n isWidgetEnabled: this._isWidgetEnabled,\n isDomainAllowed: this._isDomainAllowed,\n })\n\n this._initialize()\n }\n\n /**\n * Send a message programmatically via the API\n * Creates a new ticket if none exists or if newTicket is true\n *\n * @param message - The message text to send\n * @param userTraits - Optional user identification data (name, email)\n * @param newTicket - If true, forces creation of a new ticket (ignores current ticket)\n * @returns Promise with the response including ticket_id and message_id\n */\n async sendMessage(\n message: string,\n userTraits?: UserProvidedTraits,\n newTicket?: boolean\n ): Promise<SendMessageResponse> {\n // Determine which ticket to use\n // If newTicket is true, force creation of new ticket by sending null\n // Otherwise use current ticket ID (which may be null if no ticket exists yet)\n const ticketId = newTicket ? null : this._currentTicketId\n\n // Track if this is creating a new ticket\n const isNewTicket = !ticketId\n\n const token = this._config.token\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n const distinctId = this._posthog.get_distinct_id()\n const personProperties = this._posthog.persistence?.props || {}\n\n // Priority for traits:\n // 1. User-provided traits from the widget form\n // 2. PostHog person properties\n const name = userTraits?.name || personProperties.$name || personProperties.name || null\n const email = userTraits?.email || personProperties.$email || personProperties.email || null\n\n const payload: Partial<SendMessagePayload> = {\n widget_session_id: this._widgetSessionId,\n // distinct_id is only used for Person linking, not access control\n distinct_id: distinctId,\n message: message.trim(),\n traits: {\n name,\n email,\n },\n ticket_id: ticketId,\n }\n\n try {\n // Capture session ID - sent with every message\n const capturedSessionId = this._posthog.get_session_id()\n if (capturedSessionId) {\n payload.session_id = capturedSessionId\n }\n\n // Capture session replay URL with timestamp - sent with every message\n const replayUrl = this._posthog.get_session_replay_url({\n withTimestamp: true,\n timestampLookBack: 30,\n })\n\n // Capture current URL - only for new tickets to record where user started\n const currentUrl = isNewTicket ? window?.location?.href : undefined\n\n if (replayUrl || currentUrl) {\n payload.session_context = {\n session_replay_url: replayUrl || undefined,\n current_url: currentUrl || undefined,\n }\n }\n } catch (error) {\n // Log error but don't fail message sending\n logger.warn('Failed to capture session context', error)\n }\n\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor('api', '/api/conversations/v1/widget/message'),\n method: 'POST',\n data: payload,\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200 && response.statusCode !== 201) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to send message'\n logger.error('Failed to send message', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as SendMessageResponse\n\n // Update current ticket ID if this was a new ticket\n // This happens when: 1) No ticket existed, or 2) User forced new ticket creation\n if (isNewTicket && data.ticket_id) {\n this._currentTicketId = data.ticket_id\n this._persistence.saveTicketId(data.ticket_id)\n logger.info('New ticket created', {\n ticketId: data.ticket_id,\n forced: newTicket === true,\n })\n }\n\n // Track message sent\n this._posthog.capture('$conversations_message_sent', {\n ticketId: data.ticket_id,\n isNewTicket: isNewTicket,\n messageLength: message.length,\n })\n\n // Update last message timestamp\n this._lastMessageTimestamp = data.created_at\n\n resolve(data)\n },\n })\n })\n }\n\n /**\n * Switch to a different ticket if an explicit ticketId is provided\n * This ensures subsequent operations (sendMessage, etc.) use the correct ticket\n */\n private _switchToTicketIfNeeded(ticketId: string | undefined): void {\n if (ticketId && ticketId !== this._currentTicketId) {\n this._currentTicketId = ticketId\n this._persistence.saveTicketId(ticketId)\n // Reset last message timestamp when switching tickets\n this._lastMessageTimestamp = null\n }\n }\n\n /** Fetch messages via the API */\n async getMessages(ticketId?: string, after?: string): Promise<GetMessagesResponse> {\n // Use provided ticketId or fall back to current ticket\n const targetTicketId = ticketId || this._currentTicketId\n\n if (!targetTicketId) {\n throw new Error('No ticket ID provided and no active conversation')\n }\n\n // Switch to this ticket if explicitly provided\n this._switchToTicketIfNeeded(ticketId)\n\n const token = this._config.token\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n // SECURITY: widget_session_id is required for access control\n // distinct_id is NOT sent for getMessages - access is controlled by widget_session_id only\n const queryParams: Record<string, string> = {\n widget_session_id: this._widgetSessionId,\n limit: '50',\n }\n\n if (after) {\n queryParams.after = after\n }\n\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/messages/${targetTicketId}?${formDataToQuery(queryParams)}`\n ),\n method: 'GET',\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to fetch messages'\n logger.error('Failed to fetch messages', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as GetMessagesResponse\n resolve(data)\n },\n })\n })\n }\n\n /** Mark messages as read via the API */\n async markAsRead(ticketId?: string): Promise<MarkAsReadResponse> {\n // Use provided ticketId or fall back to current ticket\n const targetTicketId = ticketId || this._currentTicketId\n\n if (!targetTicketId) {\n throw new Error('No ticket ID provided and no active conversation')\n }\n\n // Switch to this ticket if explicitly provided\n this._switchToTicketIfNeeded(ticketId)\n\n const token = this._config.token\n\n logger.info('Marking messages as read', { ticketId: targetTicketId })\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/messages/${targetTicketId}/read`\n ),\n method: 'POST',\n data: {\n widget_session_id: this._widgetSessionId,\n },\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg =\n response.json?.detail || response.json?.message || 'Failed to mark messages as read'\n logger.error('Failed to mark messages as read', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as MarkAsReadResponse\n resolve(data)\n },\n })\n })\n }\n\n /**\n * Initialize the conversations manager.\n * Always initializes persistence and event listeners for API usage.\n * Only renders the widget if widgetEnabled is true AND domain is allowed.\n */\n private _initialize(): void {\n if (!document || !window) {\n logger.info('Conversations not available: Document or window not available')\n return\n }\n\n // Load any existing ticket ID from localStorage\n this._currentTicketId = this._persistence.loadTicketId()\n logger.info('Loaded ticket ID from storage', { ticketId: this._currentTicketId })\n\n // Track conversations API loaded (separate from widget loaded)\n this._posthog.capture('$conversations_loaded', {\n hasExistingTicket: !!this._currentTicketId,\n widgetEnabled: this._isWidgetEnabled,\n domainAllowed: this._isDomainAllowed,\n })\n\n // Only render widget if both widgetEnabled and domain is allowed\n if (this._isWidgetEnabled && this._isDomainAllowed) {\n this._initializeWidget()\n } else {\n logger.info('Widget not rendered', {\n widgetEnabled: this._isWidgetEnabled,\n domainAllowed: this._isDomainAllowed,\n })\n }\n\n // Listen for identify events to hide identification form when user identifies\n this._setupIdentifyListener()\n }\n\n /**\n * Initialize and render the widget UI\n */\n private _initializeWidget(): void {\n if (this._isWidgetRendered) {\n return // Already rendered\n }\n\n const savedState = this._persistence.loadWidgetState()\n let initialState: ConversationsWidgetState = 'closed'\n if (savedState === 'open') {\n initialState = 'open'\n }\n\n // Get initial user traits (from PostHog person properties or saved)\n const initialUserTraits = this._getInitialUserTraits()\n\n // Render the widget\n this._renderWidget(initialState, initialUserTraits)\n this._isWidgetRendered = true\n\n // Track widget initialization\n this._posthog.capture('$conversations_widget_loaded', {\n hasExistingTicket: !!this._currentTicketId,\n initialState: initialState,\n hasUserTraits: !!initialUserTraits,\n })\n\n // Set up polling and load messages only when widget is rendered\n // If we have a ticket, load its messages\n if (this._currentTicketId) {\n this._loadMessages()\n }\n\n // Start polling for messages to keep widget UI updated\n this._startPolling()\n }\n\n /**\n * Get initial user traits from PostHog or localStorage\n */\n private _getInitialUserTraits(): UserProvidedTraits | null {\n // First, check PostHog's person properties\n const personProperties = this._posthog.persistence?.props || {}\n const posthogName = personProperties.$name || personProperties.name\n const posthogEmail = personProperties.$email || personProperties.email\n\n // If we have traits from PostHog, use those\n if (posthogName || posthogEmail) {\n return {\n name: posthogName || undefined,\n email: posthogEmail || undefined,\n }\n }\n\n // Otherwise, check localStorage for previously saved traits\n const savedTraits = this._persistence.loadUserTraits()\n if (savedTraits && (savedTraits.name || savedTraits.email)) {\n return savedTraits\n }\n\n return null\n }\n\n /**\n * Handle user identification from the widget form\n */\n private _handleIdentify = (traits: UserProvidedTraits): void => {\n // Save traits to localStorage\n this._persistence.saveUserTraits(traits)\n\n // Track identification\n this._posthog.capture('$conversations_user_identified', {\n hasName: !!traits.name,\n hasEmail: !!traits.email,\n })\n }\n\n /**\n * Handle sending a message from the widget\n */\n private _handleSendMessage = async (message: string): Promise<void> => {\n // Get user traits from the widget\n const userTraits = this._widgetRef?.getUserTraits() || undefined\n\n try {\n // Call the public API method (which handles tracking and state updates)\n await this.sendMessage(message, userTraits)\n\n // Poll for response immediately\n setTimeout(() => this._pollMessages(), 1000)\n } catch (error) {\n logger.error('Failed to send message', error)\n throw error\n }\n }\n\n /**\n * Handle widget state changes\n */\n private _handleStateChange = (state: ConversationsWidgetState): void => {\n logger.info('Widget state changed', { state })\n\n // Track state changes\n this._posthog.capture('$conversations_widget_state_changed', {\n state: state,\n ticketId: this._currentTicketId,\n })\n\n // Save state to localStorage\n this._persistence.saveWidgetState(state)\n\n // Mark messages as read when widget opens\n if (state === 'open') {\n if (this._unreadCount > 0 && this._currentTicketId) {\n this._markMessagesAsRead()\n }\n }\n }\n\n /**\n * Mark messages as read\n */\n private async _markMessagesAsRead(): Promise<void> {\n if (!this._currentTicketId) {\n return\n }\n\n try {\n const response = await this.markAsRead(this._currentTicketId || undefined)\n this._unreadCount = response.unread_count\n // Update the widget to reflect the new unread count\n this._widgetRef?.setUnreadCount(0)\n logger.info('Messages marked as read', { unreadCount: response.unread_count })\n } catch (error) {\n logger.error('Failed to mark messages as read', error)\n }\n }\n\n /**\n * Load messages for the current ticket\n */\n private async _loadMessages(): Promise<void> {\n if (!this._currentTicketId) {\n return\n }\n\n try {\n const response = await this.getMessages(\n this._currentTicketId || undefined,\n this._lastMessageTimestamp || undefined\n )\n\n // Update unread count from response\n if (isNumber(response.unread_count)) {\n this._unreadCount = response.unread_count\n this._widgetRef?.setUnreadCount(response.unread_count)\n\n // If widget is open and there are unread messages, mark them as read\n if (response.unread_count > 0 && this._isWidgetOpen()) {\n this._markMessagesAsRead()\n }\n }\n\n if (response.messages.length > 0) {\n this._widgetRef?.addMessages(response.messages)\n // Update last message timestamp\n const lastMessage = response.messages[response.messages.length - 1]\n this._lastMessageTimestamp = lastMessage.created_at\n }\n } catch (error) {\n logger.error('Failed to load messages', error)\n }\n }\n\n /**\n * Check if the widget is currently open\n */\n private _isWidgetOpen(): boolean {\n return this._persistence.loadWidgetState() === 'open'\n }\n\n /**\n * Poll for new messages\n */\n private _pollMessages = async (): Promise<void> => {\n if (this._isPolling || !this._currentTicketId) {\n return\n }\n\n this._isPolling = true\n try {\n await this._loadMessages()\n } finally {\n this._isPolling = false\n }\n }\n\n /**\n * Start polling for new messages\n */\n private _startPolling(): void {\n if (this._pollIntervalId) {\n return // Already polling\n }\n\n // Poll immediately\n this._pollMessages()\n\n // Set up interval\n this._pollIntervalId = window?.setInterval(() => {\n this._pollMessages()\n }, POLL_INTERVAL_MS) as unknown as number\n\n logger.info('Started polling for messages')\n }\n\n /**\n * Stop polling for new messages\n */\n private _stopPolling(): void {\n if (this._pollIntervalId) {\n window?.clearInterval(this._pollIntervalId)\n this._pollIntervalId = null\n logger.info('Stopped polling for messages')\n }\n }\n\n /**\n * Setup listener for identify events.\n * When user calls posthog.identify(), hide the identification form\n * since we now know who they are.\n */\n private _setupIdentifyListener(): void {\n this._unsubscribeIdentifyListener = this._posthog.on('eventCaptured', (event: any) => {\n if (event.event === '$identify') {\n // User just identified - hide the identification form if it's showing\n this._widgetRef?.setUserIdentified()\n }\n })\n }\n\n /**\n * Show the widget (render it to DOM).\n * The widget respects its saved state (open/closed).\n * Note: Domain restrictions still apply - widget won't render on disallowed domains.\n */\n show(): void {\n // Check domain restrictions - don't render on disallowed domains\n if (!this._isDomainAllowed) {\n logger.warn('Cannot show widget: current domain is not allowed')\n return\n }\n\n // If widget isn't rendered yet, render it now\n if (!this._isWidgetRendered) {\n this._initializeWidget()\n }\n }\n\n /**\n * Hide and remove the widget from the DOM.\n * Conversation data is preserved - call show() to re-render.\n */\n hide(): void {\n // Stop polling when widget is hidden (save resources)\n this._stopPolling()\n\n if (this._containerElement) {\n render(null, this._containerElement)\n this._containerElement.remove()\n this._containerElement = null\n }\n this._widgetRef = null\n this._isWidgetRendered = false\n\n // Reset timestamp so show() will re-fetch all messages\n this._lastMessageTimestamp = null\n }\n\n /**\n * Check if the widget is currently visible (rendered in DOM)\n */\n isVisible(): boolean {\n return this._isWidgetRendered\n }\n\n /** Get tickets list for the current widget session */\n async getTickets(options?: GetTicketsOptions): Promise<GetTicketsResponse> {\n const token = this._config.token\n\n const queryParams: Record<string, string> = {\n widget_session_id: this._widgetSessionId,\n limit: String(options?.limit ?? 20),\n offset: String(options?.offset ?? 0),\n }\n\n if (options?.status) {\n queryParams.status = options.status\n }\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/tickets?${formDataToQuery(queryParams)}`\n ),\n method: 'GET',\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to fetch tickets'\n logger.error('Failed to fetch tickets', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as GetTicketsResponse\n resolve(data)\n },\n })\n })\n }\n\n /**\n * Get the current active ticket ID\n * Returns null if no conversation has been started yet\n */\n getCurrentTicketId(): string | null {\n return this._currentTicketId\n }\n\n /**\n * Get the widget session ID (persistent browser identifier)\n * This ID is used for access control and stays the same across page loads\n */\n getWidgetSessionId(): string {\n return this._widgetSessionId\n }\n\n /**\n * Clean up the widget\n */\n destroy(): void {\n this._stopPolling()\n\n // Unsubscribe from identify events\n if (this._unsubscribeIdentifyListener) {\n this._unsubscribeIdentifyListener()\n this._unsubscribeIdentifyListener = null\n }\n\n if (this._containerElement) {\n render(null, this._containerElement)\n this._containerElement.remove()\n this._containerElement = null\n }\n\n this._widgetRef = null\n logger.info('Widget destroyed')\n }\n\n /**\n * Reset all conversation data and destroy the widget.\n * Called on posthog.reset() to start fresh.\n */\n reset(): void {\n // Clear all persisted conversation data\n this._persistence.clearAll()\n\n // Reset local state\n this._currentTicketId = null\n this._lastMessageTimestamp = null\n this._unreadCount = 0\n\n // Destroy the widget\n this.destroy()\n\n logger.info('Conversations reset')\n }\n\n /**\n * Render the widget to the DOM\n */\n private _renderWidget(initialState: ConversationsWidgetState, initialUserTraits: UserProvidedTraits | null): void {\n if (!document) {\n logger.info('Conversations widget not rendered: Document not available')\n return\n }\n\n // Create container if it doesn't exist\n let container = document.getElementById(WIDGET_CONTAINER_ID) as HTMLDivElement\n if (!container) {\n if (!document.body) {\n logger.info('Conversations widget not rendered: Document body not available yet')\n return\n }\n container = document.createElement('div')\n container.id = WIDGET_CONTAINER_ID\n document.body.appendChild(container)\n }\n this._containerElement = container\n\n // Render widget with ref\n render(\n <ConversationsWidget\n ref={(ref: ConversationsWidget | null) => {\n this._widgetRef = ref\n }}\n config={this._config}\n initialState={initialState}\n initialUserTraits={initialUserTraits}\n isUserIdentified={this._posthog._isIdentified()}\n onSendMessage={this._handleSendMessage}\n onStateChange={this._handleStateChange}\n onIdentify={this._handleIdentify}\n />,\n container\n )\n }\n}\n\n/**\n * Initialize the conversations widget\n * This is the entry point called from the lazy-loaded bundle\n */\nexport function initConversations(config: ConversationsRemoteConfig, posthog: PostHog): ConversationsManager {\n logger.info('initConversations called', { hasConfig: !!config, hasPosthog: !!posthog })\n return new ConversationsManager(config, posthog)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/extensions/conversations/external/index.tsx"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { render, h } from 'preact'\nimport { isNumber } from '@posthog/core'\nimport {\n ConversationsRemoteConfig,\n ConversationsWidgetState,\n UserProvidedTraits,\n SendMessageResponse,\n SendMessagePayload,\n GetMessagesResponse,\n MarkAsReadResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n Ticket,\n} from '../../../posthog-conversations-types'\nimport { PostHog } from '../../../posthog-core'\nimport { ConversationsManager as ConversationsManagerInterface } from '../posthog-conversations'\nimport { ConversationsPersistence } from './persistence'\nimport { ConversationsWidget, WidgetView } from './components/ConversationsWidget'\nimport { createLogger } from '../../../utils/logger'\nimport { document, window } from '../../../utils/globals'\nimport { formDataToQuery } from '../../../utils/request-utils'\n\nconst logger = createLogger('[ConversationsManager]')\n\nconst WIDGET_CONTAINER_ID = 'ph-conversations-widget-container'\nconst POLL_INTERVAL_MS = 5000 // 5 seconds\n\n/**\n * Extract hostname from a domain string (handles URLs and plain hostnames)\n */\nfunction extractHostname(domain: string): string | null {\n // Remove protocol if present\n let hostname = domain.replace(/^https?:\\/\\//, '')\n // Remove path, query, port if present\n hostname = hostname.split('/')[0].split('?')[0].split(':')[0]\n return hostname || null\n}\n\n/**\n * Check if the current domain matches the allowed domains list.\n * Returns true if:\n * - domains is empty or not present (no restriction)\n * - current hostname matches any allowed domain\n */\nfunction isCurrentDomainAllowed(domains: string[] | undefined): boolean {\n // No domain restriction - allow all\n if (!domains || domains.length === 0) {\n return true\n }\n\n const currentHostname = window?.location?.hostname\n if (!currentHostname) {\n // Can't determine hostname (SSR, etc.) - allow by default\n return true\n }\n\n return domains.some((domain) => {\n const allowedHostname = extractHostname(domain)\n if (!allowedHostname) {\n return false\n }\n\n if (allowedHostname.startsWith('*.')) {\n // Wildcard match: *.example.com matches foo.example.com and example.com\n const pattern = allowedHostname.slice(2) // Remove \"*.\"\n return currentHostname.endsWith(`.${pattern}`) || currentHostname === pattern\n }\n\n // Exact match\n return currentHostname === allowedHostname\n })\n}\n\nexport class ConversationsManager implements ConversationsManagerInterface {\n private _config: ConversationsRemoteConfig\n private _persistence: ConversationsPersistence\n private _widgetRef: ConversationsWidget | null = null\n private _containerElement: HTMLDivElement | null = null\n private _currentTicketId: string | null = null\n private _pollIntervalId: number | null = null\n private _lastMessageTimestamp: string | null = null\n private _isPolling: boolean = false\n private _unsubscribeIdentifyListener: (() => void) | null = null\n private _unreadCount: number = 0\n // SECURITY: widget_session_id is the key for access control\n // This is a random UUID that only this browser knows\n private _widgetSessionId: string\n private _isWidgetEnabled: boolean\n private _isDomainAllowed: boolean\n private _isWidgetRendered: boolean = false\n private _initializeWidgetPromise: Promise<void> | null = null\n // View state management for ticket list vs message view\n private _currentView: WidgetView = 'messages'\n private _tickets: Ticket[] = []\n private _hasMultipleTickets: boolean = false\n\n constructor(\n config: ConversationsRemoteConfig,\n private readonly _posthog: PostHog\n ) {\n this._config = config\n this._persistence = new ConversationsPersistence(_posthog)\n // Get or create widget_session_id - this stays the same even when user identifies\n this._widgetSessionId = this._persistence.getOrCreateWidgetSessionId()\n\n // Determine if widget should be shown based on config and domain\n this._isWidgetEnabled = config.widgetEnabled === true\n this._isDomainAllowed = isCurrentDomainAllowed(config.domains)\n\n logger.info('ConversationsManager initialized', {\n config,\n widgetSessionId: this._widgetSessionId,\n isWidgetEnabled: this._isWidgetEnabled,\n isDomainAllowed: this._isDomainAllowed,\n })\n\n this._initialize()\n }\n\n /**\n * Send a message programmatically via the API\n * Creates a new ticket if none exists or if newTicket is true\n *\n * @param message - The message text to send\n * @param userTraits - Optional user identification data (name, email)\n * @param newTicket - If true, forces creation of a new ticket (ignores current ticket)\n * @returns Promise with the response including ticket_id and message_id\n */\n async sendMessage(\n message: string,\n userTraits?: UserProvidedTraits,\n newTicket?: boolean\n ): Promise<SendMessageResponse> {\n // Determine which ticket to use\n // If newTicket is true, force creation of new ticket by sending null\n // Otherwise use current ticket ID (which may be null if no ticket exists yet)\n const ticketId = newTicket ? null : this._currentTicketId\n\n // Track if this is creating a new ticket\n const isNewTicket = !ticketId\n\n const token = this._config.token\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n const distinctId = this._posthog.get_distinct_id()\n const personProperties = this._posthog.persistence?.props || {}\n\n // Priority for traits:\n // 1. User-provided traits from the widget form\n // 2. PostHog person properties\n const name = userTraits?.name || personProperties.$name || personProperties.name || null\n const email = userTraits?.email || personProperties.$email || personProperties.email || null\n\n const payload: Partial<SendMessagePayload> = {\n widget_session_id: this._widgetSessionId,\n // distinct_id is only used for Person linking, not access control\n distinct_id: distinctId,\n message: message.trim(),\n traits: {\n name,\n email,\n },\n ticket_id: ticketId,\n }\n\n try {\n // Capture session ID - sent with every message\n const capturedSessionId = this._posthog.get_session_id()\n if (capturedSessionId) {\n payload.session_id = capturedSessionId\n }\n\n // Capture session replay URL with timestamp - sent with every message\n const replayUrl = this._posthog.get_session_replay_url({\n withTimestamp: true,\n timestampLookBack: 30,\n })\n\n // Capture current URL - only for new tickets to record where user started\n const currentUrl = isNewTicket ? window?.location?.href : undefined\n\n if (replayUrl || currentUrl) {\n payload.session_context = {\n session_replay_url: replayUrl || undefined,\n current_url: currentUrl || undefined,\n }\n }\n } catch (error) {\n // Log error but don't fail message sending\n logger.warn('Failed to capture session context', error)\n }\n\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor('api', '/api/conversations/v1/widget/message'),\n method: 'POST',\n data: payload,\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200 && response.statusCode !== 201) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to send message'\n logger.error('Failed to send message', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as SendMessageResponse\n\n // Update current ticket ID if this was a new ticket\n // This happens when: 1) No ticket existed, or 2) User forced new ticket creation\n if (isNewTicket && data.ticket_id) {\n this._currentTicketId = data.ticket_id\n this._persistence.saveTicketId(data.ticket_id)\n logger.info('New ticket created', {\n ticketId: data.ticket_id,\n forced: newTicket === true,\n })\n }\n\n // Track message sent\n this._posthog.capture('$conversations_message_sent', {\n ticketId: data.ticket_id,\n isNewTicket: isNewTicket,\n messageLength: message.length,\n })\n\n // Update last message timestamp\n this._lastMessageTimestamp = data.created_at\n\n resolve(data)\n },\n })\n })\n }\n\n /**\n * Switch to a different ticket if an explicit ticketId is provided\n * This ensures subsequent operations (sendMessage, etc.) use the correct ticket\n */\n private _switchToTicketIfNeeded(ticketId: string | undefined): void {\n if (ticketId && ticketId !== this._currentTicketId) {\n this._currentTicketId = ticketId\n this._persistence.saveTicketId(ticketId)\n // Reset last message timestamp when switching tickets\n this._lastMessageTimestamp = null\n }\n }\n\n /** Fetch messages via the API */\n async getMessages(ticketId?: string, after?: string): Promise<GetMessagesResponse> {\n // Use provided ticketId or fall back to current ticket\n const targetTicketId = ticketId || this._currentTicketId\n\n if (!targetTicketId) {\n throw new Error('No ticket ID provided and no active conversation')\n }\n\n // Switch to this ticket if explicitly provided\n this._switchToTicketIfNeeded(ticketId)\n\n const token = this._config.token\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n // SECURITY: widget_session_id is required for access control\n // distinct_id is NOT sent for getMessages - access is controlled by widget_session_id only\n const queryParams: Record<string, string> = {\n widget_session_id: this._widgetSessionId,\n limit: '50',\n }\n\n if (after) {\n queryParams.after = after\n }\n\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/messages/${targetTicketId}?${formDataToQuery(queryParams)}`\n ),\n method: 'GET',\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to fetch messages'\n logger.error('Failed to fetch messages', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as GetMessagesResponse\n resolve(data)\n },\n })\n })\n }\n\n /** Mark messages as read via the API */\n async markAsRead(ticketId?: string): Promise<MarkAsReadResponse> {\n // Use provided ticketId or fall back to current ticket\n const targetTicketId = ticketId || this._currentTicketId\n\n if (!targetTicketId) {\n throw new Error('No ticket ID provided and no active conversation')\n }\n\n // Switch to this ticket if explicitly provided\n this._switchToTicketIfNeeded(ticketId)\n\n const token = this._config.token\n\n logger.info('Marking messages as read', { ticketId: targetTicketId })\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/messages/${targetTicketId}/read`\n ),\n method: 'POST',\n data: {\n widget_session_id: this._widgetSessionId,\n },\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg =\n response.json?.detail || response.json?.message || 'Failed to mark messages as read'\n logger.error('Failed to mark messages as read', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as MarkAsReadResponse\n resolve(data)\n },\n })\n })\n }\n\n /**\n * Initialize the conversations manager.\n * Always initializes persistence and event listeners for API usage.\n * Only renders the widget if widgetEnabled is true AND domain is allowed.\n */\n private _initialize(): void {\n if (!document || !window) {\n logger.info('Conversations not available: Document or window not available')\n return\n }\n\n // Load any existing ticket ID from localStorage\n this._currentTicketId = this._persistence.loadTicketId()\n logger.info('Loaded ticket ID from storage', { ticketId: this._currentTicketId })\n\n // Track conversations API loaded (separate from widget loaded)\n this._posthog.capture('$conversations_loaded', {\n hasExistingTicket: !!this._currentTicketId,\n widgetEnabled: this._isWidgetEnabled,\n domainAllowed: this._isDomainAllowed,\n })\n\n // Only render widget if both widgetEnabled and domain is allowed\n if (this._isWidgetEnabled && this._isDomainAllowed) {\n this._initializeWidget()\n } else {\n logger.info('Widget not rendered', {\n widgetEnabled: this._isWidgetEnabled,\n domainAllowed: this._isDomainAllowed,\n })\n }\n\n // Listen for identify events to hide identification form when user identifies\n this._setupIdentifyListener()\n }\n\n /**\n * Initialize and render the widget UI\n * Uses a promise guard to prevent race conditions from concurrent calls\n */\n private _initializeWidget(): Promise<void> {\n if (this._isWidgetRendered) {\n return Promise.resolve()\n }\n if (this._initializeWidgetPromise) {\n return this._initializeWidgetPromise\n }\n this._initializeWidgetPromise = this._doInitializeWidget()\n return this._initializeWidgetPromise\n }\n\n private async _doInitializeWidget(): Promise<void> {\n const savedState = this._persistence.loadWidgetState()\n let initialState: ConversationsWidgetState = 'closed'\n if (savedState === 'open') {\n initialState = 'open'\n }\n\n // Get initial user traits (from PostHog person properties or saved)\n const initialUserTraits = this._getInitialUserTraits()\n\n // Determine initial view based on ticket count\n const { view: initialView, tickets } = await this._determineInitialView()\n this._currentView = initialView\n\n // Render the widget with initial view\n this._renderWidget(initialState, initialUserTraits, initialView, tickets)\n this._isWidgetRendered = true\n\n // Track widget initialization\n this._posthog.capture('$conversations_widget_loaded', {\n hasExistingTicket: !!this._currentTicketId,\n initialState: initialState,\n initialView: initialView,\n ticketCount: tickets.length,\n hasUserTraits: !!initialUserTraits,\n })\n\n // Load messages if in message view and have a ticket\n if (initialView === 'messages' && this._currentTicketId) {\n this._loadMessages()\n }\n\n // Start polling based on current view\n this._startPolling()\n }\n\n /**\n * Get initial user traits from PostHog or localStorage\n */\n private _getInitialUserTraits(): UserProvidedTraits | null {\n // First, check PostHog's person properties\n const personProperties = this._posthog.persistence?.props || {}\n const posthogName = personProperties.$name || personProperties.name\n const posthogEmail = personProperties.$email || personProperties.email\n\n // If we have traits from PostHog, use those\n if (posthogName || posthogEmail) {\n return {\n name: posthogName || undefined,\n email: posthogEmail || undefined,\n }\n }\n\n // Otherwise, check localStorage for previously saved traits\n const savedTraits = this._persistence.loadUserTraits()\n if (savedTraits && (savedTraits.name || savedTraits.email)) {\n return savedTraits\n }\n\n return null\n }\n\n /**\n * Handle user identification from the widget form\n */\n private _handleIdentify = (traits: UserProvidedTraits): void => {\n // Save traits to localStorage\n this._persistence.saveUserTraits(traits)\n\n // Track identification\n this._posthog.capture('$conversations_user_identified', {\n hasName: !!traits.name,\n hasEmail: !!traits.email,\n })\n }\n\n /**\n * Handle sending a message from the widget\n */\n private _handleSendMessage = async (message: string): Promise<void> => {\n // Get user traits from the widget\n const userTraits = this._widgetRef?.getUserTraits() || undefined\n\n try {\n // Call the public API method (which handles tracking and state updates)\n await this.sendMessage(message, userTraits)\n\n // Poll for response immediately\n setTimeout(() => this._pollMessages(), 1000)\n } catch (error) {\n logger.error('Failed to send message', error)\n throw error\n }\n }\n\n /**\n * Handle widget state changes\n */\n private _handleStateChange = (state: ConversationsWidgetState): void => {\n logger.info('Widget state changed', { state, view: this._currentView })\n\n // Track state changes\n this._posthog.capture('$conversations_widget_state_changed', {\n state: state,\n view: this._currentView,\n ticketId: this._currentTicketId,\n })\n\n // Save state to localStorage\n this._persistence.saveWidgetState(state)\n\n // Mark messages as read when widget opens (only if in message view with a ticket)\n if (state === 'open') {\n if (this._currentView === 'messages' && this._unreadCount > 0 && this._currentTicketId) {\n this._markMessagesAsRead()\n }\n }\n }\n\n /**\n * Mark messages as read\n */\n private async _markMessagesAsRead(): Promise<void> {\n if (!this._currentTicketId) {\n return\n }\n\n try {\n const response = await this.markAsRead(this._currentTicketId || undefined)\n this._unreadCount = response.unread_count\n // Update the widget to reflect the new unread count\n this._widgetRef?.setUnreadCount(0)\n logger.info('Messages marked as read', { unreadCount: response.unread_count })\n } catch (error) {\n logger.error('Failed to mark messages as read', error)\n }\n }\n\n /**\n * Load messages for the current ticket\n */\n private async _loadMessages(): Promise<void> {\n if (!this._currentTicketId) {\n return\n }\n\n try {\n const response = await this.getMessages(\n this._currentTicketId || undefined,\n this._lastMessageTimestamp || undefined\n )\n\n // Update unread count from response\n if (isNumber(response.unread_count)) {\n this._unreadCount = response.unread_count\n this._widgetRef?.setUnreadCount(response.unread_count)\n\n // If widget is open and there are unread messages, mark them as read\n if (response.unread_count > 0 && this._isWidgetOpen()) {\n this._markMessagesAsRead()\n }\n }\n\n if (response.messages.length > 0) {\n this._widgetRef?.addMessages(response.messages)\n // Update last message timestamp\n const lastMessage = response.messages[response.messages.length - 1]\n this._lastMessageTimestamp = lastMessage.created_at\n }\n } catch (error) {\n logger.error('Failed to load messages', error)\n }\n }\n\n /**\n * Check if the widget is currently open\n */\n private _isWidgetOpen(): boolean {\n return this._persistence.loadWidgetState() === 'open'\n }\n\n /**\n * Poll for new messages\n */\n private _pollMessages = async (): Promise<void> => {\n if (this._isPolling || !this._currentTicketId) {\n return\n }\n\n this._isPolling = true\n try {\n await this._loadMessages()\n } finally {\n this._isPolling = false\n }\n }\n\n /**\n * Poll for tickets list\n */\n private _pollTickets = async (): Promise<void> => {\n if (this._isPolling) {\n return\n }\n\n this._isPolling = true\n try {\n await this._loadTickets()\n } finally {\n this._isPolling = false\n }\n }\n\n /**\n * Load tickets list from API\n */\n private async _loadTickets(): Promise<void> {\n try {\n const response = await this.getTickets()\n this._tickets = response.results\n this._hasMultipleTickets = response.results.length > 1\n this._widgetRef?.updateTickets(response.results)\n\n // Calculate total unread across all tickets\n const totalUnread = response.results.reduce((sum, t) => sum + (t.unread_count || 0), 0)\n this._unreadCount = totalUnread\n this._widgetRef?.setUnreadCount(totalUnread)\n\n logger.info('Tickets loaded', { count: response.results.length, totalUnread })\n } catch (error) {\n logger.error('Failed to load tickets', error)\n }\n }\n\n /**\n * Main poll function that polls based on current view\n */\n private _poll = async (): Promise<void> => {\n if (this._currentView === 'tickets') {\n await this._pollTickets()\n } else {\n await this._pollMessages()\n }\n }\n\n /**\n * Handle view changes from the widget\n */\n private _handleViewChange = (view: WidgetView): void => {\n logger.info('View changed', { from: this._currentView, to: view })\n this._currentView = view\n }\n\n /**\n * Handle ticket selection from the list\n */\n private _handleSelectTicket = async (ticketId: string): Promise<void> => {\n // Switch to this ticket\n this._switchToTicketIfNeeded(ticketId)\n\n // Clear messages and reset timestamp\n this._lastMessageTimestamp = null\n this._widgetRef?.clearMessages()\n\n // Switch view to messages\n this._currentView = 'messages'\n this._widgetRef?.setView('messages')\n\n // Load messages for the selected ticket\n await this._loadMessages()\n\n // Mark as read if widget is open\n if (this._isWidgetOpen() && this._unreadCount > 0) {\n this._markMessagesAsRead()\n }\n }\n\n /**\n * Handle new conversation request\n */\n private _handleNewConversation = (): void => {\n logger.info('New conversation requested')\n\n // Clear current ticket\n this._currentTicketId = null\n this._persistence.clearTicketId()\n\n // Reset timestamp\n this._lastMessageTimestamp = null\n\n // Switch view to messages\n this._currentView = 'messages'\n this._widgetRef?.setView('messages')\n\n // Clear messages and add greeting\n this._widgetRef?.clearMessages(true)\n }\n\n /**\n * Handle back to tickets request\n */\n private _handleBackToTickets = async (): Promise<void> => {\n logger.info('Back to tickets requested')\n\n // Switch view to tickets\n this._currentView = 'tickets'\n this._widgetRef?.setView('tickets')\n\n // Load tickets\n this._widgetRef?.setTicketsLoading(true)\n await this._loadTickets()\n\n // Track back to tickets\n this._posthog.capture('$conversations_back_to_tickets')\n }\n\n /**\n * Determine initial view based on ticket count\n */\n private async _determineInitialView(): Promise<{ view: WidgetView; tickets: Ticket[] }> {\n try {\n const response = await this.getTickets()\n this._tickets = response.results\n this._hasMultipleTickets = response.results.length > 1\n\n // Calculate total unread\n const totalUnread = response.results.reduce((sum, t) => sum + (t.unread_count || 0), 0)\n this._unreadCount = totalUnread\n\n // If 2+ tickets, show ticket list; otherwise show messages\n if (response.results.length >= 2) {\n return { view: 'tickets', tickets: response.results }\n }\n\n // If exactly 1 ticket, set it as current\n if (response.results.length === 1) {\n this._currentTicketId = response.results[0].id\n this._persistence.saveTicketId(response.results[0].id)\n }\n\n return { view: 'messages', tickets: response.results }\n } catch (error) {\n logger.error('Failed to determine initial view', error)\n return { view: 'messages', tickets: [] }\n }\n }\n\n /**\n * Start polling based on current view\n */\n private _startPolling(): void {\n if (this._pollIntervalId) {\n return // Already polling\n }\n\n // Poll immediately\n this._poll()\n\n // Set up interval\n this._pollIntervalId = window?.setInterval(() => {\n this._poll()\n }, POLL_INTERVAL_MS) as unknown as number\n\n logger.info('Started polling', { view: this._currentView })\n }\n\n /**\n * Stop polling for new messages\n */\n private _stopPolling(): void {\n if (this._pollIntervalId) {\n window?.clearInterval(this._pollIntervalId)\n this._pollIntervalId = null\n logger.info('Stopped polling for messages')\n }\n }\n\n /**\n * Setup listener for identify events.\n * When user calls posthog.identify(), hide the identification form\n * since we now know who they are.\n */\n private _setupIdentifyListener(): void {\n this._unsubscribeIdentifyListener = this._posthog.on('eventCaptured', (event: any) => {\n if (event.event === '$identify') {\n // User just identified - hide the identification form if it's showing\n this._widgetRef?.setUserIdentified()\n }\n })\n }\n\n /**\n * Show the widget (render it to DOM).\n * The widget respects its saved state (open/closed).\n * Note: Domain restrictions still apply - widget won't render on disallowed domains.\n */\n show(): void {\n // Check domain restrictions - don't render on disallowed domains\n if (!this._isDomainAllowed) {\n logger.warn('Cannot show widget: current domain is not allowed')\n return\n }\n\n // If widget isn't rendered yet, render it now\n if (!this._isWidgetRendered) {\n this._initializeWidget()\n }\n }\n\n /**\n * Hide and remove the widget from the DOM.\n * Conversation data is preserved - call show() to re-render.\n */\n hide(): void {\n // Stop polling when widget is hidden (save resources)\n this._stopPolling()\n\n if (this._containerElement) {\n render(null, this._containerElement)\n this._containerElement.remove()\n this._containerElement = null\n }\n this._widgetRef = null\n this._isWidgetRendered = false\n this._initializeWidgetPromise = null\n\n // Reset timestamp so show() will re-fetch all messages\n this._lastMessageTimestamp = null\n }\n\n /**\n * Check if the widget is currently visible (rendered in DOM)\n */\n isVisible(): boolean {\n return this._isWidgetRendered\n }\n\n /** Get tickets list for the current widget session */\n async getTickets(options?: GetTicketsOptions): Promise<GetTicketsResponse> {\n const token = this._config.token\n\n const queryParams: Record<string, string> = {\n widget_session_id: this._widgetSessionId,\n limit: String(options?.limit ?? 20),\n offset: String(options?.offset ?? 0),\n }\n\n if (options?.status) {\n queryParams.status = options.status\n }\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/tickets?${formDataToQuery(queryParams)}`\n ),\n method: 'GET',\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to fetch tickets'\n logger.error('Failed to fetch tickets', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as GetTicketsResponse\n resolve(data)\n },\n })\n })\n }\n\n /**\n * Get the current active ticket ID\n * Returns null if no conversation has been started yet\n */\n getCurrentTicketId(): string | null {\n return this._currentTicketId\n }\n\n /**\n * Get the widget session ID (persistent browser identifier)\n * This ID is used for access control and stays the same across page loads\n */\n getWidgetSessionId(): string {\n return this._widgetSessionId\n }\n\n /**\n * Clean up the widget\n */\n destroy(): void {\n this._stopPolling()\n\n // Unsubscribe from identify events\n if (this._unsubscribeIdentifyListener) {\n this._unsubscribeIdentifyListener()\n this._unsubscribeIdentifyListener = null\n }\n\n if (this._containerElement) {\n render(null, this._containerElement)\n this._containerElement.remove()\n this._containerElement = null\n }\n\n this._widgetRef = null\n logger.info('Widget destroyed')\n }\n\n /**\n * Reset all conversation data and destroy the widget.\n * Called on posthog.reset() to start fresh.\n */\n reset(): void {\n // Clear all persisted conversation data\n this._persistence.clearAll()\n\n // Reset local state\n this._currentTicketId = null\n this._lastMessageTimestamp = null\n this._unreadCount = 0\n\n // Destroy the widget\n this.destroy()\n\n logger.info('Conversations reset')\n }\n\n /**\n * Render the widget to the DOM\n */\n private _renderWidget(\n initialState: ConversationsWidgetState,\n initialUserTraits: UserProvidedTraits | null,\n initialView: WidgetView = 'messages',\n initialTickets: Ticket[] = []\n ): void {\n if (!document) {\n logger.info('Conversations widget not rendered: Document not available')\n return\n }\n\n // Create container if it doesn't exist\n let container = document.getElementById(WIDGET_CONTAINER_ID) as HTMLDivElement\n if (!container) {\n if (!document.body) {\n logger.info('Conversations widget not rendered: Document body not available yet')\n return\n }\n container = document.createElement('div')\n container.id = WIDGET_CONTAINER_ID\n document.body.appendChild(container)\n }\n this._containerElement = container\n\n // Render widget with ref\n render(\n <ConversationsWidget\n ref={(ref: ConversationsWidget | null) => {\n this._widgetRef = ref\n }}\n config={this._config}\n initialState={initialState}\n initialUserTraits={initialUserTraits}\n isUserIdentified={this._posthog._isIdentified()}\n initialView={initialView}\n initialTickets={initialTickets}\n hasMultipleTickets={this._hasMultipleTickets}\n onSendMessage={this._handleSendMessage}\n onStateChange={this._handleStateChange}\n onIdentify={this._handleIdentify}\n onSelectTicket={this._handleSelectTicket}\n onNewConversation={this._handleNewConversation}\n onBackToTickets={this._handleBackToTickets}\n onViewChange={this._handleViewChange}\n />,\n container\n )\n }\n}\n\n/**\n * Initialize the conversations widget\n * This is the entry point called from the lazy-loaded bundle\n */\nexport function initConversations(config: ConversationsRemoteConfig, posthog: PostHog): ConversationsManager {\n logger.info('initConversations called', { hasConfig: !!config, hasPosthog: !!posthog })\n return new ConversationsManager(config, posthog)\n}\n"]}
|