@product7/feedback-sdk 1.3.1 → 1.3.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@product7/feedback-sdk",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "JavaScript SDK for integrating Product7 feedback widgets into any website",
5
5
  "main": "dist/feedback-sdk.js",
6
6
  "module": "src/index.js",
@@ -1,6 +1,4 @@
1
- /**
2
- * MessengerWidget - Full-featured Messenger/Chat widget
3
- */
1
+
4
2
  import { BaseWidget } from './BaseWidget.js';
5
3
  import { MessengerState } from './messenger/MessengerState.js';
6
4
  import { MessengerLauncher } from './messenger/components/MessengerLauncher.js';
@@ -28,13 +26,11 @@ export class MessengerWidget extends BaseWidget {
28
26
  logoUrl: options.logoUrl || 'https://product7.io/p7logo.svg',
29
27
  featuredContent: options.featuredContent || null,
30
28
  primaryColor: options.primaryColor || '#1c1c1e',
31
- // Callbacks
32
29
  onSendMessage: options.onSendMessage || null,
33
30
  onArticleClick: options.onArticleClick || null,
34
31
  onChangelogClick: options.onChangelogClick || null,
35
32
  };
36
33
 
37
- // Create state
38
34
  this.messengerState = new MessengerState({
39
35
  teamName: this.messengerOptions.teamName,
40
36
  teamAvatars: this.messengerOptions.teamAvatars,
@@ -49,7 +45,6 @@ export class MessengerWidget extends BaseWidget {
49
45
  this.wsService = null;
50
46
  this._wsUnsubscribers = [];
51
47
 
52
- // Bind methods
53
48
  this._handleOpenChange = this._handleOpenChange.bind(this);
54
49
  this._handleWebSocketMessage = this._handleWebSocketMessage.bind(this);
55
50
  this._handleTypingStarted = this._handleTypingStarted.bind(this);
@@ -58,42 +53,34 @@ export class MessengerWidget extends BaseWidget {
58
53
  }
59
54
 
60
55
  _render() {
61
- // Create container
62
56
  const container = document.createElement('div');
63
57
  container.className = `messenger-widget theme-${this.messengerOptions.theme}`;
64
58
  container.style.zIndex = '999999';
65
59
 
66
- // Create launcher
67
60
  this.launcher = new MessengerLauncher(this.messengerState, {
68
61
  position: this.messengerOptions.position,
69
62
  primaryColor: this.messengerOptions.primaryColor,
70
63
  });
71
64
  container.appendChild(this.launcher.render());
72
65
 
73
- // Create panel with all callbacks
74
66
  this.panel = new MessengerPanel(this.messengerState, {
75
67
  position: this.messengerOptions.position,
76
68
  theme: this.messengerOptions.theme,
77
69
  primaryColor: this.messengerOptions.primaryColor,
78
70
  logoUrl: this.messengerOptions.logoUrl,
79
71
  featuredContent: this.messengerOptions.featuredContent,
80
- // Chat callbacks
81
72
  onSendMessage:
82
73
  this.messengerOptions.onSendMessage ||
83
74
  this._handleSendMessage.bind(this),
84
75
  onStartConversation: this._handleStartConversation.bind(this),
85
76
  onTyping: this.sendTypingIndicator.bind(this),
86
- // Conversation list callbacks
87
77
  onSelectConversation: this._handleSelectConversation.bind(this),
88
78
  onStartNewConversation: this._handleNewConversationClick.bind(this),
89
- // Pre-chat form callbacks
90
79
  onIdentifyContact: this._handleIdentifyContact.bind(this),
91
- // Article/changelog callbacks
92
80
  onArticleClick: this.messengerOptions.onArticleClick,
93
81
  onChangelogClick: this.messengerOptions.onChangelogClick,
94
82
  });
95
83
 
96
- // Register views
97
84
  this.panel.registerView('home', HomeView);
98
85
  this.panel.registerView('messages', ConversationsView);
99
86
  this.panel.registerView('chat', ChatView);
@@ -108,13 +95,15 @@ export class MessengerWidget extends BaseWidget {
108
95
  }
109
96
 
110
97
  _attachEvents() {
111
- // Subscribe to state changes
112
98
  this._stateUnsubscribe = this.messengerState.subscribe((type, data) => {
113
99
  if (type === 'openChange') {
114
100
  this._handleOpenChange(data.isOpen);
115
101
  }
116
102
  if (type === 'conversationChange') {
117
- this._handleActiveConversationChange(data.conversationId, data.previousConversationId);
103
+ this._handleActiveConversationChange(
104
+ data.conversationId,
105
+ data.previousConversationId
106
+ );
118
107
  }
119
108
  });
120
109
  }
@@ -130,31 +119,38 @@ export class MessengerWidget extends BaseWidget {
130
119
  }
131
120
  }
132
121
 
133
- /**
134
- * Subscribe/unsubscribe to conversation WebSocket channel
135
- */
136
122
  _handleActiveConversationChange(conversationId, previousConversationId) {
137
123
  if (previousConversationId && this.wsService) {
138
- this.wsService.send('conversation:unsubscribe', { conversation_id: previousConversationId });
124
+ this.wsService.send('conversation:unsubscribe', {
125
+ conversation_id: previousConversationId,
126
+ });
139
127
  }
140
128
  if (conversationId && this.wsService) {
141
- this.wsService.send('conversation:subscribe', { conversation_id: conversationId });
129
+ this.wsService.send('conversation:subscribe', {
130
+ conversation_id: conversationId,
131
+ });
142
132
  }
143
133
  }
144
134
 
145
- /**
146
- * Handle starting a new conversation
147
- * If there's an existing open conversation, send the message there instead
148
- */
149
135
  async _handleStartConversation(messageContent, pendingAttachments) {
150
136
  try {
151
- // Check for existing open conversation first
137
+ const userContext = this.messengerState.userContext;
138
+ const isIdentified = userContext?.email;
139
+
140
+ if (!isIdentified) {
141
+ this.messengerState.pendingMessage = {
142
+ content: messageContent,
143
+ attachments: pendingAttachments,
144
+ };
145
+ this.messengerState.setView('prechat');
146
+ return null;
147
+ }
148
+
152
149
  const openConversation = this.messengerState.conversations.find(
153
150
  (c) => c.status === 'open'
154
151
  );
155
152
 
156
153
  if (openConversation) {
157
- // Route message to existing open conversation
158
154
  this.messengerState.setActiveConversation(openConversation.id);
159
155
  await this._handleSendMessage(
160
156
  openConversation.id,
@@ -164,16 +160,17 @@ export class MessengerWidget extends BaseWidget {
164
160
  return openConversation;
165
161
  }
166
162
 
167
- return await this.startNewConversation(messageContent, '', pendingAttachments);
163
+ return await this.startNewConversation(
164
+ messageContent,
165
+ '',
166
+ pendingAttachments
167
+ );
168
168
  } catch (error) {
169
169
  console.error('[MessengerWidget] Failed to start conversation:', error);
170
170
  return null;
171
171
  }
172
172
  }
173
173
 
174
- /**
175
- * Handle selecting a conversation from the list
176
- */
177
174
  async _handleSelectConversation(conversationId) {
178
175
  try {
179
176
  await this.fetchMessages(conversationId);
@@ -182,34 +179,23 @@ export class MessengerWidget extends BaseWidget {
182
179
  }
183
180
  }
184
181
 
185
- /**
186
- * Handle clicking "new conversation" button
187
- * Reuses the most recent open conversation if one exists
188
- */
189
182
  _handleNewConversationClick() {
190
- // Check for an existing open conversation to reuse
191
183
  const openConversation = this.messengerState.conversations.find(
192
184
  (c) => c.status === 'open'
193
185
  );
194
186
 
195
187
  if (openConversation) {
196
- // Reuse existing open conversation
197
188
  this.messengerState.setActiveConversation(openConversation.id);
198
189
  this.messengerState.setView('chat');
199
190
  this._handleSelectConversation(openConversation.id);
200
191
  } else {
201
- // No open conversation — start a new one
202
192
  this.messengerState.setActiveConversation(null);
203
193
  this.messengerState.setView('chat');
204
194
  }
205
195
  }
206
196
 
207
- /**
208
- * Handle identifying contact from pre-chat form
209
- */
210
197
  async _handleIdentifyContact(contactData) {
211
198
  try {
212
- // Call API to identify/update contact
213
199
  const response = await this.apiService.identifyContact({
214
200
  name: contactData.name,
215
201
  email: contactData.email,
@@ -218,12 +204,24 @@ export class MessengerWidget extends BaseWidget {
218
204
  if (response.status) {
219
205
  console.log('[MessengerWidget] Contact identified:', contactData.email);
220
206
 
221
- // Update local user context
222
207
  if (!this.messengerState.userContext) {
223
208
  this.messengerState.userContext = {};
224
209
  }
225
210
  this.messengerState.userContext.name = contactData.name;
226
211
  this.messengerState.userContext.email = contactData.email;
212
+
213
+ const pendingMessage = this.messengerState.pendingMessage;
214
+ if (pendingMessage) {
215
+ this.messengerState.pendingMessage = null;
216
+
217
+ await this.startNewConversation(
218
+ pendingMessage.content,
219
+ '',
220
+ pendingMessage.attachments
221
+ );
222
+ } else {
223
+ this.messengerState.setView('chat');
224
+ }
227
225
  }
228
226
 
229
227
  return response;
@@ -259,14 +257,17 @@ export class MessengerWidget extends BaseWidget {
259
257
  name: att.file.name,
260
258
  });
261
259
  } catch (err) {
262
- console.error('[MessengerWidget] Skipping failed attachment upload:', att.file.name, err);
260
+ console.error(
261
+ '[MessengerWidget] Skipping failed attachment upload:',
262
+ att.file.name,
263
+ err
264
+ );
263
265
  }
264
266
  }
265
267
  return uploaded;
266
268
  }
267
269
 
268
270
  async _handleSendMessage(conversationId, message, pendingAttachments) {
269
- // Emit event for external listeners
270
271
  this.sdk.eventBus.emit('messenger:messageSent', {
271
272
  widget: this,
272
273
  conversationId,
@@ -274,22 +275,18 @@ export class MessengerWidget extends BaseWidget {
274
275
  });
275
276
 
276
277
  try {
277
- // Upload attachments to CDN first
278
- const uploadedAttachments = await this._uploadPendingAttachments(pendingAttachments);
278
+ const uploadedAttachments =
279
+ await this._uploadPendingAttachments(pendingAttachments);
279
280
 
280
- // Send message through API
281
281
  const response = await this.apiService.sendMessage(conversationId, {
282
282
  content: message.content,
283
283
  attachments: uploadedAttachments,
284
284
  });
285
285
 
286
286
  if (response.status && response.data) {
287
- // Update the message ID with server-assigned ID
288
- // Message is already added to state optimistically in ChatView
289
287
  console.log('[MessengerWidget] Message sent:', response.data.id);
290
288
  }
291
289
 
292
- // In mock mode, simulate an agent response after a delay
293
290
  if (this.apiService?.mock) {
294
291
  setTimeout(() => {
295
292
  const mockResponse = {
@@ -307,29 +304,24 @@ export class MessengerWidget extends BaseWidget {
307
304
  }
308
305
  } catch (error) {
309
306
  console.error('[MessengerWidget] Failed to send message:', error);
310
- // Could add error handling UI here
311
307
  }
312
308
  }
313
309
 
314
- /**
315
- * Handle incoming WebSocket message
316
- */
317
310
  _handleWebSocketMessage(data) {
318
311
  const { conversation_id, message } = data;
319
312
 
320
- // Parse attachments from server message
321
313
  let attachments = [];
322
314
  if (message.attachments) {
323
315
  try {
324
- attachments = typeof message.attachments === 'string'
325
- ? JSON.parse(message.attachments)
326
- : message.attachments;
316
+ attachments =
317
+ typeof message.attachments === 'string'
318
+ ? JSON.parse(message.attachments)
319
+ : message.attachments;
327
320
  } catch (e) {
328
- // ignore parse errors
321
+ // ignore
329
322
  }
330
323
  }
331
324
 
332
- // Transform message to local format
333
325
  const localMessage = {
334
326
  id: message.id,
335
327
  content: message.content,
@@ -342,10 +334,8 @@ export class MessengerWidget extends BaseWidget {
342
334
  },
343
335
  };
344
336
 
345
- // Add message to state
346
337
  this.messengerState.addMessage(conversation_id, localMessage);
347
338
 
348
- // Update unread count if panel is closed or viewing different conversation
349
339
  if (
350
340
  !this.messengerState.isOpen ||
351
341
  this.messengerState.activeConversationId !== conversation_id
@@ -354,9 +344,6 @@ export class MessengerWidget extends BaseWidget {
354
344
  }
355
345
  }
356
346
 
357
- /**
358
- * Handle typing started event
359
- */
360
347
  _handleTypingStarted(data) {
361
348
  if (data.is_agent) {
362
349
  this.messengerState._notify('typingStarted', {
@@ -366,31 +353,20 @@ export class MessengerWidget extends BaseWidget {
366
353
  }
367
354
  }
368
355
 
369
- /**
370
- * Handle typing stopped event
371
- */
372
356
  _handleTypingStopped(data) {
373
357
  this.messengerState._notify('typingStopped', {
374
358
  conversationId: data.conversation_id,
375
359
  });
376
360
  }
377
361
 
378
- /**
379
- * Handle conversation closed event
380
- */
381
362
  _handleConversationClosed(data) {
382
363
  const conversationId =
383
- data?.conversation_id ||
384
- data?.id ||
385
- data?.conversation?.id;
364
+ data?.conversation_id || data?.id || data?.conversation?.id;
386
365
  if (!conversationId) return;
387
366
 
388
367
  this.messengerState.updateConversation(conversationId, { status: 'closed' });
389
368
  }
390
369
 
391
- /**
392
- * Update unread count from API
393
- */
394
370
  async _updateUnreadCount() {
395
371
  try {
396
372
  const response = await this.apiService.getUnreadCount();
@@ -405,9 +381,6 @@ export class MessengerWidget extends BaseWidget {
405
381
  }
406
382
  }
407
383
 
408
- /**
409
- * Initialize WebSocket connection
410
- */
411
384
  _initWebSocket() {
412
385
  if (this.wsService) {
413
386
  this.wsService.disconnect();
@@ -420,7 +393,6 @@ export class MessengerWidget extends BaseWidget {
420
393
  mock: this.apiService.mock,
421
394
  });
422
395
 
423
- // Subscribe to WebSocket events
424
396
  this._wsUnsubscribers.push(
425
397
  this.wsService.on('message', this._handleWebSocketMessage)
426
398
  );
@@ -436,7 +408,6 @@ export class MessengerWidget extends BaseWidget {
436
408
  this._wsUnsubscribers.push(
437
409
  this.wsService.on('connected', () => {
438
410
  console.log('[MessengerWidget] WebSocket connected');
439
- // Re-subscribe to active conversation on reconnect
440
411
  if (this.messengerState.activeConversationId) {
441
412
  this.wsService.send('conversation:subscribe', {
442
413
  conversation_id: this.messengerState.activeConversationId,
@@ -450,34 +421,21 @@ export class MessengerWidget extends BaseWidget {
450
421
  })
451
422
  );
452
423
 
453
- // Connect
454
424
  this.wsService.connect();
455
425
  }
456
426
 
457
- /**
458
- * Open the messenger panel
459
- */
460
427
  open() {
461
428
  this.messengerState.setOpen(true);
462
429
  }
463
430
 
464
- /**
465
- * Close the messenger panel
466
- */
467
431
  close() {
468
432
  this.messengerState.setOpen(false);
469
433
  }
470
434
 
471
- /**
472
- * Toggle the messenger panel
473
- */
474
435
  toggle() {
475
436
  this.messengerState.setOpen(!this.messengerState.isOpen);
476
437
  }
477
438
 
478
- /**
479
- * Navigate to a specific view
480
- */
481
439
  navigateTo(view) {
482
440
  this.messengerState.setView(view);
483
441
  if (!this.messengerState.isOpen) {
@@ -485,52 +443,31 @@ export class MessengerWidget extends BaseWidget {
485
443
  }
486
444
  }
487
445
 
488
- /**
489
- * Set conversations
490
- */
491
446
  setConversations(conversations) {
492
447
  this.messengerState.setConversations(conversations);
493
448
  }
494
449
 
495
- /**
496
- * Add a message to a conversation
497
- */
498
450
  addMessage(conversationId, message) {
499
451
  this.messengerState.addMessage(conversationId, message);
500
452
  }
501
453
 
502
- /**
503
- * Set help articles
504
- */
505
454
  setHelpArticles(articles) {
506
455
  this.messengerState.setHelpArticles(articles);
507
456
  }
508
457
 
509
- /**
510
- * Set home changelog items
511
- */
512
458
  setHomeChangelogItems(items) {
513
459
  this.messengerState.setHomeChangelogItems(items);
514
460
  }
515
461
 
516
- /**
517
- * Set changelog items
518
- */
519
462
  setChangelogItems(items) {
520
463
  this.messengerState.setChangelogItems(items);
521
464
  }
522
465
 
523
- /**
524
- * Update unread count (for external updates)
525
- */
526
466
  setUnreadCount(count) {
527
467
  this.messengerState.unreadCount = count;
528
468
  this.messengerState._notify('unreadCountChange', { count });
529
469
  }
530
470
 
531
- /**
532
- * Get current state
533
- */
534
471
  getState() {
535
472
  return {
536
473
  isOpen: this.messengerState.isOpen,
@@ -540,11 +477,7 @@ export class MessengerWidget extends BaseWidget {
540
477
  };
541
478
  }
542
479
 
543
- /**
544
- * Load initial data (mock or API)
545
- */
546
480
  async loadInitialData() {
547
- // Load conversations
548
481
  try {
549
482
  const conversations = await this._fetchConversations();
550
483
  this.messengerState.setConversations(conversations);
@@ -552,7 +485,6 @@ export class MessengerWidget extends BaseWidget {
552
485
  console.error('[MessengerWidget] Failed to load conversations:', error);
553
486
  }
554
487
 
555
- // Load help articles if enabled
556
488
  if (this.messengerOptions.enableHelp) {
557
489
  try {
558
490
  const articles = await this._fetchHelpArticles();
@@ -562,7 +494,6 @@ export class MessengerWidget extends BaseWidget {
562
494
  }
563
495
  }
564
496
 
565
- // Load changelog if enabled
566
497
  if (this.messengerOptions.enableChangelog) {
567
498
  try {
568
499
  const { homeItems, changelogItems } = await this._fetchChangelog();
@@ -578,7 +509,6 @@ export class MessengerWidget extends BaseWidget {
578
509
  try {
579
510
  const response = await this.apiService.getConversations();
580
511
  if (response.status && response.data) {
581
- // Transform API response to local format
582
512
  return response.data.map((conv) => ({
583
513
  id: conv.id,
584
514
  title:
@@ -609,7 +539,6 @@ export class MessengerWidget extends BaseWidget {
609
539
  try {
610
540
  const response = await this.apiService.getHelpCollections();
611
541
  if (response.status && response.data) {
612
- // Transform API response to local format
613
542
  return response.data.map((collection) => ({
614
543
  id: collection.id,
615
544
  title: collection.title || collection.name,
@@ -627,9 +556,6 @@ export class MessengerWidget extends BaseWidget {
627
556
  }
628
557
  }
629
558
 
630
- /**
631
- * Fetch messages for a conversation
632
- */
633
559
  async fetchMessages(conversationId) {
634
560
  try {
635
561
  const response = await this.apiService.getConversation(conversationId);
@@ -638,11 +564,12 @@ export class MessengerWidget extends BaseWidget {
638
564
  let attachments;
639
565
  if (msg.attachments) {
640
566
  try {
641
- attachments = typeof msg.attachments === 'string'
642
- ? JSON.parse(msg.attachments)
643
- : msg.attachments;
567
+ attachments =
568
+ typeof msg.attachments === 'string'
569
+ ? JSON.parse(msg.attachments)
570
+ : msg.attachments;
644
571
  } catch (e) {
645
- // ignore parse errors
572
+ // ignore
646
573
  }
647
574
  }
648
575
  return {
@@ -650,16 +577,18 @@ export class MessengerWidget extends BaseWidget {
650
577
  content: msg.content,
651
578
  isOwn: msg.sender_type === 'customer',
652
579
  timestamp: msg.created_at,
653
- attachments: attachments && attachments.length > 0 ? attachments : undefined,
580
+ attachments:
581
+ attachments && attachments.length > 0 ? attachments : undefined,
654
582
  sender: {
655
- name: msg.sender_name || (msg.sender_type === 'customer' ? 'You' : 'Support'),
583
+ name:
584
+ msg.sender_name ||
585
+ (msg.sender_type === 'customer' ? 'You' : 'Support'),
656
586
  avatarUrl: msg.sender_avatar || null,
657
587
  },
658
588
  };
659
589
  });
660
590
  this.messengerState.setMessages(conversationId, messages);
661
591
 
662
- // Mark as read
663
592
  await this.apiService.markConversationAsRead(conversationId);
664
593
  this.messengerState.markAsRead(conversationId);
665
594
 
@@ -672,19 +601,18 @@ export class MessengerWidget extends BaseWidget {
672
601
  }
673
602
  }
674
603
 
675
- /**
676
- * Start a new conversation
677
- */
678
604
  async startNewConversation(message, subject = '', pendingAttachments = []) {
679
605
  try {
680
- // Upload attachments to CDN first
681
- const uploadedAttachments = await this._uploadPendingAttachments(pendingAttachments);
606
+ const uploadedAttachments =
607
+ await this._uploadPendingAttachments(pendingAttachments);
682
608
 
683
609
  console.log('[MessengerWidget] Starting conversation...', {
684
610
  message,
685
611
  attachmentCount: uploadedAttachments.length,
686
612
  hasSession: this.apiService.isSessionValid(),
687
- sessionToken: this.apiService.sessionToken ? this.apiService.sessionToken.substring(0, 10) + '...' : null,
613
+ sessionToken: this.apiService.sessionToken
614
+ ? this.apiService.sessionToken.substring(0, 10) + '...'
615
+ : null,
688
616
  baseURL: this.apiService.baseURL,
689
617
  mock: this.apiService.mock,
690
618
  });
@@ -709,10 +637,8 @@ export class MessengerWidget extends BaseWidget {
709
637
  status: 'open',
710
638
  };
711
639
 
712
- // Add to state
713
640
  this.messengerState.addConversation(newConversation);
714
641
 
715
- // Set initial message in messages cache
716
642
  this.messengerState.setMessages(conv.id, [
717
643
  {
718
644
  id: 'msg_' + Date.now(),
@@ -722,7 +648,6 @@ export class MessengerWidget extends BaseWidget {
722
648
  },
723
649
  ]);
724
650
 
725
- // Navigate to chat
726
651
  this.messengerState.setActiveConversation(conv.id);
727
652
  this.messengerState.setView('chat');
728
653
 
@@ -735,20 +660,14 @@ export class MessengerWidget extends BaseWidget {
735
660
  }
736
661
  }
737
662
 
738
- /**
739
- * Send typing indicator
740
- */
741
663
  async sendTypingIndicator(conversationId, isTyping) {
742
664
  try {
743
665
  await this.apiService.sendTypingIndicator(conversationId, isTyping);
744
666
  } catch (error) {
745
- // Silently fail - typing indicators are not critical
667
+ // Silent fail
746
668
  }
747
669
  }
748
670
 
749
- /**
750
- * Check agent availability
751
- */
752
671
  async checkAgentAvailability() {
753
672
  try {
754
673
  const response = await this.apiService.checkAgentsOnline();
@@ -757,9 +676,10 @@ export class MessengerWidget extends BaseWidget {
757
676
  this.messengerState.onlineCount = response.data.online_count || 0;
758
677
  this.messengerState.responseTime = response.data.response_time || '';
759
678
 
760
- // Update team avatars from online agents
761
679
  if (response.data.available_agents) {
762
- this.messengerState.setTeamAvatarsFromAgents(response.data.available_agents);
680
+ this.messengerState.setTeamAvatarsFromAgents(
681
+ response.data.available_agents
682
+ );
763
683
  }
764
684
 
765
685
  this.messengerState._notify('availabilityUpdate', response.data);
@@ -851,11 +771,9 @@ export class MessengerWidget extends BaseWidget {
851
771
  };
852
772
  }
853
773
 
854
- // Fetch changelogs from API
855
774
  const response = await this.apiService.getChangelogs({ limit: 20 });
856
775
  const changelogs = response.data || [];
857
776
 
858
- // Map API response to expected format
859
777
  const mappedItems = changelogs.map((item) => ({
860
778
  id: item.id,
861
779
  title: item.title,
@@ -873,19 +791,30 @@ export class MessengerWidget extends BaseWidget {
873
791
  };
874
792
  }
875
793
 
876
- onMount() {
877
- // Load initial data after mounting
794
+ async onMount() {
795
+ const userContext = this.messengerState.userContext;
796
+ if (userContext?.email && userContext?.name) {
797
+ try {
798
+ await this.apiService.identifyContact({
799
+ name: userContext.name,
800
+ email: userContext.email,
801
+ });
802
+ console.log('[MessengerWidget] User identified successfully');
803
+ } catch (error) {
804
+ if (error?.code !== 'ALREADY_IDENTIFIED') {
805
+ console.warn('[MessengerWidget] Identification failed:', error);
806
+ }
807
+ }
808
+ }
809
+
878
810
  this.loadInitialData();
879
811
 
880
- // Initialize WebSocket for real-time updates
881
812
  if (this.apiService?.sessionToken) {
882
813
  this._initWebSocket();
883
814
  }
884
815
 
885
- // Check agent availability
886
816
  this.checkAgentAvailability();
887
817
 
888
- // Periodically check availability (every 60 seconds)
889
818
  this._availabilityInterval = setInterval(() => {
890
819
  this.checkAgentAvailability();
891
820
  }, 60000);
@@ -896,16 +825,13 @@ export class MessengerWidget extends BaseWidget {
896
825
  this._stateUnsubscribe();
897
826
  }
898
827
 
899
- // Clean up WebSocket
900
828
  if (this.wsService) {
901
829
  this.wsService.disconnect();
902
830
  }
903
831
 
904
- // Clean up WebSocket event listeners
905
832
  this._wsUnsubscribers.forEach((unsub) => unsub());
906
833
  this._wsUnsubscribers = [];
907
834
 
908
- // Clean up availability interval
909
835
  if (this._availabilityInterval) {
910
836
  clearInterval(this._availabilityInterval);
911
837
  }
@@ -921,4 +847,4 @@ export class MessengerWidget extends BaseWidget {
921
847
  this.onDestroy();
922
848
  super.destroy();
923
849
  }
924
- }
850
+ }