@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/dist/feedback-sdk.js +88 -164
- package/dist/feedback-sdk.js.map +1 -1
- package/dist/feedback-sdk.min.js +1 -1
- package/dist/feedback-sdk.min.js.map +1 -1
- package/package.json +1 -1
- package/src/widgets/MessengerWidget.js +90 -164
package/dist/feedback-sdk.js
CHANGED
|
@@ -5736,10 +5736,6 @@
|
|
|
5736
5736
|
}
|
|
5737
5737
|
}
|
|
5738
5738
|
|
|
5739
|
-
/**
|
|
5740
|
-
* MessengerWidget - Full-featured Messenger/Chat widget
|
|
5741
|
-
*/
|
|
5742
|
-
|
|
5743
5739
|
class MessengerWidget extends BaseWidget {
|
|
5744
5740
|
constructor(options) {
|
|
5745
5741
|
super({ ...options, type: 'messenger' });
|
|
@@ -5755,13 +5751,11 @@
|
|
|
5755
5751
|
logoUrl: options.logoUrl || 'https://product7.io/p7logo.svg',
|
|
5756
5752
|
featuredContent: options.featuredContent || null,
|
|
5757
5753
|
primaryColor: options.primaryColor || '#1c1c1e',
|
|
5758
|
-
// Callbacks
|
|
5759
5754
|
onSendMessage: options.onSendMessage || null,
|
|
5760
5755
|
onArticleClick: options.onArticleClick || null,
|
|
5761
5756
|
onChangelogClick: options.onChangelogClick || null,
|
|
5762
5757
|
};
|
|
5763
5758
|
|
|
5764
|
-
// Create state
|
|
5765
5759
|
this.messengerState = new MessengerState({
|
|
5766
5760
|
teamName: this.messengerOptions.teamName,
|
|
5767
5761
|
teamAvatars: this.messengerOptions.teamAvatars,
|
|
@@ -5776,7 +5770,6 @@
|
|
|
5776
5770
|
this.wsService = null;
|
|
5777
5771
|
this._wsUnsubscribers = [];
|
|
5778
5772
|
|
|
5779
|
-
// Bind methods
|
|
5780
5773
|
this._handleOpenChange = this._handleOpenChange.bind(this);
|
|
5781
5774
|
this._handleWebSocketMessage = this._handleWebSocketMessage.bind(this);
|
|
5782
5775
|
this._handleTypingStarted = this._handleTypingStarted.bind(this);
|
|
@@ -5785,42 +5778,34 @@
|
|
|
5785
5778
|
}
|
|
5786
5779
|
|
|
5787
5780
|
_render() {
|
|
5788
|
-
// Create container
|
|
5789
5781
|
const container = document.createElement('div');
|
|
5790
5782
|
container.className = `messenger-widget theme-${this.messengerOptions.theme}`;
|
|
5791
5783
|
container.style.zIndex = '999999';
|
|
5792
5784
|
|
|
5793
|
-
// Create launcher
|
|
5794
5785
|
this.launcher = new MessengerLauncher(this.messengerState, {
|
|
5795
5786
|
position: this.messengerOptions.position,
|
|
5796
5787
|
primaryColor: this.messengerOptions.primaryColor,
|
|
5797
5788
|
});
|
|
5798
5789
|
container.appendChild(this.launcher.render());
|
|
5799
5790
|
|
|
5800
|
-
// Create panel with all callbacks
|
|
5801
5791
|
this.panel = new MessengerPanel(this.messengerState, {
|
|
5802
5792
|
position: this.messengerOptions.position,
|
|
5803
5793
|
theme: this.messengerOptions.theme,
|
|
5804
5794
|
primaryColor: this.messengerOptions.primaryColor,
|
|
5805
5795
|
logoUrl: this.messengerOptions.logoUrl,
|
|
5806
5796
|
featuredContent: this.messengerOptions.featuredContent,
|
|
5807
|
-
// Chat callbacks
|
|
5808
5797
|
onSendMessage:
|
|
5809
5798
|
this.messengerOptions.onSendMessage ||
|
|
5810
5799
|
this._handleSendMessage.bind(this),
|
|
5811
5800
|
onStartConversation: this._handleStartConversation.bind(this),
|
|
5812
5801
|
onTyping: this.sendTypingIndicator.bind(this),
|
|
5813
|
-
// Conversation list callbacks
|
|
5814
5802
|
onSelectConversation: this._handleSelectConversation.bind(this),
|
|
5815
5803
|
onStartNewConversation: this._handleNewConversationClick.bind(this),
|
|
5816
|
-
// Pre-chat form callbacks
|
|
5817
5804
|
onIdentifyContact: this._handleIdentifyContact.bind(this),
|
|
5818
|
-
// Article/changelog callbacks
|
|
5819
5805
|
onArticleClick: this.messengerOptions.onArticleClick,
|
|
5820
5806
|
onChangelogClick: this.messengerOptions.onChangelogClick,
|
|
5821
5807
|
});
|
|
5822
5808
|
|
|
5823
|
-
// Register views
|
|
5824
5809
|
this.panel.registerView('home', HomeView);
|
|
5825
5810
|
this.panel.registerView('messages', ConversationsView);
|
|
5826
5811
|
this.panel.registerView('chat', ChatView);
|
|
@@ -5835,13 +5820,15 @@
|
|
|
5835
5820
|
}
|
|
5836
5821
|
|
|
5837
5822
|
_attachEvents() {
|
|
5838
|
-
// Subscribe to state changes
|
|
5839
5823
|
this._stateUnsubscribe = this.messengerState.subscribe((type, data) => {
|
|
5840
5824
|
if (type === 'openChange') {
|
|
5841
5825
|
this._handleOpenChange(data.isOpen);
|
|
5842
5826
|
}
|
|
5843
5827
|
if (type === 'conversationChange') {
|
|
5844
|
-
this._handleActiveConversationChange(
|
|
5828
|
+
this._handleActiveConversationChange(
|
|
5829
|
+
data.conversationId,
|
|
5830
|
+
data.previousConversationId
|
|
5831
|
+
);
|
|
5845
5832
|
}
|
|
5846
5833
|
});
|
|
5847
5834
|
}
|
|
@@ -5857,31 +5844,38 @@
|
|
|
5857
5844
|
}
|
|
5858
5845
|
}
|
|
5859
5846
|
|
|
5860
|
-
/**
|
|
5861
|
-
* Subscribe/unsubscribe to conversation WebSocket channel
|
|
5862
|
-
*/
|
|
5863
5847
|
_handleActiveConversationChange(conversationId, previousConversationId) {
|
|
5864
5848
|
if (previousConversationId && this.wsService) {
|
|
5865
|
-
this.wsService.send('conversation:unsubscribe', {
|
|
5849
|
+
this.wsService.send('conversation:unsubscribe', {
|
|
5850
|
+
conversation_id: previousConversationId,
|
|
5851
|
+
});
|
|
5866
5852
|
}
|
|
5867
5853
|
if (conversationId && this.wsService) {
|
|
5868
|
-
this.wsService.send('conversation:subscribe', {
|
|
5854
|
+
this.wsService.send('conversation:subscribe', {
|
|
5855
|
+
conversation_id: conversationId,
|
|
5856
|
+
});
|
|
5869
5857
|
}
|
|
5870
5858
|
}
|
|
5871
5859
|
|
|
5872
|
-
/**
|
|
5873
|
-
* Handle starting a new conversation
|
|
5874
|
-
* If there's an existing open conversation, send the message there instead
|
|
5875
|
-
*/
|
|
5876
5860
|
async _handleStartConversation(messageContent, pendingAttachments) {
|
|
5877
5861
|
try {
|
|
5878
|
-
|
|
5862
|
+
const userContext = this.messengerState.userContext;
|
|
5863
|
+
const isIdentified = userContext?.email;
|
|
5864
|
+
|
|
5865
|
+
if (!isIdentified) {
|
|
5866
|
+
this.messengerState.pendingMessage = {
|
|
5867
|
+
content: messageContent,
|
|
5868
|
+
attachments: pendingAttachments,
|
|
5869
|
+
};
|
|
5870
|
+
this.messengerState.setView('prechat');
|
|
5871
|
+
return null;
|
|
5872
|
+
}
|
|
5873
|
+
|
|
5879
5874
|
const openConversation = this.messengerState.conversations.find(
|
|
5880
5875
|
(c) => c.status === 'open'
|
|
5881
5876
|
);
|
|
5882
5877
|
|
|
5883
5878
|
if (openConversation) {
|
|
5884
|
-
// Route message to existing open conversation
|
|
5885
5879
|
this.messengerState.setActiveConversation(openConversation.id);
|
|
5886
5880
|
await this._handleSendMessage(
|
|
5887
5881
|
openConversation.id,
|
|
@@ -5891,16 +5885,17 @@
|
|
|
5891
5885
|
return openConversation;
|
|
5892
5886
|
}
|
|
5893
5887
|
|
|
5894
|
-
return await this.startNewConversation(
|
|
5888
|
+
return await this.startNewConversation(
|
|
5889
|
+
messageContent,
|
|
5890
|
+
'',
|
|
5891
|
+
pendingAttachments
|
|
5892
|
+
);
|
|
5895
5893
|
} catch (error) {
|
|
5896
5894
|
console.error('[MessengerWidget] Failed to start conversation:', error);
|
|
5897
5895
|
return null;
|
|
5898
5896
|
}
|
|
5899
5897
|
}
|
|
5900
5898
|
|
|
5901
|
-
/**
|
|
5902
|
-
* Handle selecting a conversation from the list
|
|
5903
|
-
*/
|
|
5904
5899
|
async _handleSelectConversation(conversationId) {
|
|
5905
5900
|
try {
|
|
5906
5901
|
await this.fetchMessages(conversationId);
|
|
@@ -5909,34 +5904,23 @@
|
|
|
5909
5904
|
}
|
|
5910
5905
|
}
|
|
5911
5906
|
|
|
5912
|
-
/**
|
|
5913
|
-
* Handle clicking "new conversation" button
|
|
5914
|
-
* Reuses the most recent open conversation if one exists
|
|
5915
|
-
*/
|
|
5916
5907
|
_handleNewConversationClick() {
|
|
5917
|
-
// Check for an existing open conversation to reuse
|
|
5918
5908
|
const openConversation = this.messengerState.conversations.find(
|
|
5919
5909
|
(c) => c.status === 'open'
|
|
5920
5910
|
);
|
|
5921
5911
|
|
|
5922
5912
|
if (openConversation) {
|
|
5923
|
-
// Reuse existing open conversation
|
|
5924
5913
|
this.messengerState.setActiveConversation(openConversation.id);
|
|
5925
5914
|
this.messengerState.setView('chat');
|
|
5926
5915
|
this._handleSelectConversation(openConversation.id);
|
|
5927
5916
|
} else {
|
|
5928
|
-
// No open conversation — start a new one
|
|
5929
5917
|
this.messengerState.setActiveConversation(null);
|
|
5930
5918
|
this.messengerState.setView('chat');
|
|
5931
5919
|
}
|
|
5932
5920
|
}
|
|
5933
5921
|
|
|
5934
|
-
/**
|
|
5935
|
-
* Handle identifying contact from pre-chat form
|
|
5936
|
-
*/
|
|
5937
5922
|
async _handleIdentifyContact(contactData) {
|
|
5938
5923
|
try {
|
|
5939
|
-
// Call API to identify/update contact
|
|
5940
5924
|
const response = await this.apiService.identifyContact({
|
|
5941
5925
|
name: contactData.name,
|
|
5942
5926
|
email: contactData.email,
|
|
@@ -5945,12 +5929,24 @@
|
|
|
5945
5929
|
if (response.status) {
|
|
5946
5930
|
console.log('[MessengerWidget] Contact identified:', contactData.email);
|
|
5947
5931
|
|
|
5948
|
-
// Update local user context
|
|
5949
5932
|
if (!this.messengerState.userContext) {
|
|
5950
5933
|
this.messengerState.userContext = {};
|
|
5951
5934
|
}
|
|
5952
5935
|
this.messengerState.userContext.name = contactData.name;
|
|
5953
5936
|
this.messengerState.userContext.email = contactData.email;
|
|
5937
|
+
|
|
5938
|
+
const pendingMessage = this.messengerState.pendingMessage;
|
|
5939
|
+
if (pendingMessage) {
|
|
5940
|
+
this.messengerState.pendingMessage = null;
|
|
5941
|
+
|
|
5942
|
+
await this.startNewConversation(
|
|
5943
|
+
pendingMessage.content,
|
|
5944
|
+
'',
|
|
5945
|
+
pendingMessage.attachments
|
|
5946
|
+
);
|
|
5947
|
+
} else {
|
|
5948
|
+
this.messengerState.setView('chat');
|
|
5949
|
+
}
|
|
5954
5950
|
}
|
|
5955
5951
|
|
|
5956
5952
|
return response;
|
|
@@ -5986,14 +5982,17 @@
|
|
|
5986
5982
|
name: att.file.name,
|
|
5987
5983
|
});
|
|
5988
5984
|
} catch (err) {
|
|
5989
|
-
console.error(
|
|
5985
|
+
console.error(
|
|
5986
|
+
'[MessengerWidget] Skipping failed attachment upload:',
|
|
5987
|
+
att.file.name,
|
|
5988
|
+
err
|
|
5989
|
+
);
|
|
5990
5990
|
}
|
|
5991
5991
|
}
|
|
5992
5992
|
return uploaded;
|
|
5993
5993
|
}
|
|
5994
5994
|
|
|
5995
5995
|
async _handleSendMessage(conversationId, message, pendingAttachments) {
|
|
5996
|
-
// Emit event for external listeners
|
|
5997
5996
|
this.sdk.eventBus.emit('messenger:messageSent', {
|
|
5998
5997
|
widget: this,
|
|
5999
5998
|
conversationId,
|
|
@@ -6001,22 +6000,18 @@
|
|
|
6001
6000
|
});
|
|
6002
6001
|
|
|
6003
6002
|
try {
|
|
6004
|
-
|
|
6005
|
-
|
|
6003
|
+
const uploadedAttachments =
|
|
6004
|
+
await this._uploadPendingAttachments(pendingAttachments);
|
|
6006
6005
|
|
|
6007
|
-
// Send message through API
|
|
6008
6006
|
const response = await this.apiService.sendMessage(conversationId, {
|
|
6009
6007
|
content: message.content,
|
|
6010
6008
|
attachments: uploadedAttachments,
|
|
6011
6009
|
});
|
|
6012
6010
|
|
|
6013
6011
|
if (response.status && response.data) {
|
|
6014
|
-
// Update the message ID with server-assigned ID
|
|
6015
|
-
// Message is already added to state optimistically in ChatView
|
|
6016
6012
|
console.log('[MessengerWidget] Message sent:', response.data.id);
|
|
6017
6013
|
}
|
|
6018
6014
|
|
|
6019
|
-
// In mock mode, simulate an agent response after a delay
|
|
6020
6015
|
if (this.apiService?.mock) {
|
|
6021
6016
|
setTimeout(() => {
|
|
6022
6017
|
const mockResponse = {
|
|
@@ -6034,29 +6029,24 @@
|
|
|
6034
6029
|
}
|
|
6035
6030
|
} catch (error) {
|
|
6036
6031
|
console.error('[MessengerWidget] Failed to send message:', error);
|
|
6037
|
-
// Could add error handling UI here
|
|
6038
6032
|
}
|
|
6039
6033
|
}
|
|
6040
6034
|
|
|
6041
|
-
/**
|
|
6042
|
-
* Handle incoming WebSocket message
|
|
6043
|
-
*/
|
|
6044
6035
|
_handleWebSocketMessage(data) {
|
|
6045
6036
|
const { conversation_id, message } = data;
|
|
6046
6037
|
|
|
6047
|
-
// Parse attachments from server message
|
|
6048
6038
|
let attachments = [];
|
|
6049
6039
|
if (message.attachments) {
|
|
6050
6040
|
try {
|
|
6051
|
-
attachments =
|
|
6052
|
-
|
|
6053
|
-
|
|
6041
|
+
attachments =
|
|
6042
|
+
typeof message.attachments === 'string'
|
|
6043
|
+
? JSON.parse(message.attachments)
|
|
6044
|
+
: message.attachments;
|
|
6054
6045
|
} catch (e) {
|
|
6055
|
-
// ignore
|
|
6046
|
+
// ignore
|
|
6056
6047
|
}
|
|
6057
6048
|
}
|
|
6058
6049
|
|
|
6059
|
-
// Transform message to local format
|
|
6060
6050
|
const localMessage = {
|
|
6061
6051
|
id: message.id,
|
|
6062
6052
|
content: message.content,
|
|
@@ -6069,10 +6059,8 @@
|
|
|
6069
6059
|
},
|
|
6070
6060
|
};
|
|
6071
6061
|
|
|
6072
|
-
// Add message to state
|
|
6073
6062
|
this.messengerState.addMessage(conversation_id, localMessage);
|
|
6074
6063
|
|
|
6075
|
-
// Update unread count if panel is closed or viewing different conversation
|
|
6076
6064
|
if (
|
|
6077
6065
|
!this.messengerState.isOpen ||
|
|
6078
6066
|
this.messengerState.activeConversationId !== conversation_id
|
|
@@ -6081,9 +6069,6 @@
|
|
|
6081
6069
|
}
|
|
6082
6070
|
}
|
|
6083
6071
|
|
|
6084
|
-
/**
|
|
6085
|
-
* Handle typing started event
|
|
6086
|
-
*/
|
|
6087
6072
|
_handleTypingStarted(data) {
|
|
6088
6073
|
if (data.is_agent) {
|
|
6089
6074
|
this.messengerState._notify('typingStarted', {
|
|
@@ -6093,31 +6078,20 @@
|
|
|
6093
6078
|
}
|
|
6094
6079
|
}
|
|
6095
6080
|
|
|
6096
|
-
/**
|
|
6097
|
-
* Handle typing stopped event
|
|
6098
|
-
*/
|
|
6099
6081
|
_handleTypingStopped(data) {
|
|
6100
6082
|
this.messengerState._notify('typingStopped', {
|
|
6101
6083
|
conversationId: data.conversation_id,
|
|
6102
6084
|
});
|
|
6103
6085
|
}
|
|
6104
6086
|
|
|
6105
|
-
/**
|
|
6106
|
-
* Handle conversation closed event
|
|
6107
|
-
*/
|
|
6108
6087
|
_handleConversationClosed(data) {
|
|
6109
6088
|
const conversationId =
|
|
6110
|
-
data?.conversation_id ||
|
|
6111
|
-
data?.id ||
|
|
6112
|
-
data?.conversation?.id;
|
|
6089
|
+
data?.conversation_id || data?.id || data?.conversation?.id;
|
|
6113
6090
|
if (!conversationId) return;
|
|
6114
6091
|
|
|
6115
6092
|
this.messengerState.updateConversation(conversationId, { status: 'closed' });
|
|
6116
6093
|
}
|
|
6117
6094
|
|
|
6118
|
-
/**
|
|
6119
|
-
* Update unread count from API
|
|
6120
|
-
*/
|
|
6121
6095
|
async _updateUnreadCount() {
|
|
6122
6096
|
try {
|
|
6123
6097
|
const response = await this.apiService.getUnreadCount();
|
|
@@ -6132,9 +6106,6 @@
|
|
|
6132
6106
|
}
|
|
6133
6107
|
}
|
|
6134
6108
|
|
|
6135
|
-
/**
|
|
6136
|
-
* Initialize WebSocket connection
|
|
6137
|
-
*/
|
|
6138
6109
|
_initWebSocket() {
|
|
6139
6110
|
if (this.wsService) {
|
|
6140
6111
|
this.wsService.disconnect();
|
|
@@ -6147,7 +6118,6 @@
|
|
|
6147
6118
|
mock: this.apiService.mock,
|
|
6148
6119
|
});
|
|
6149
6120
|
|
|
6150
|
-
// Subscribe to WebSocket events
|
|
6151
6121
|
this._wsUnsubscribers.push(
|
|
6152
6122
|
this.wsService.on('message', this._handleWebSocketMessage)
|
|
6153
6123
|
);
|
|
@@ -6163,7 +6133,6 @@
|
|
|
6163
6133
|
this._wsUnsubscribers.push(
|
|
6164
6134
|
this.wsService.on('connected', () => {
|
|
6165
6135
|
console.log('[MessengerWidget] WebSocket connected');
|
|
6166
|
-
// Re-subscribe to active conversation on reconnect
|
|
6167
6136
|
if (this.messengerState.activeConversationId) {
|
|
6168
6137
|
this.wsService.send('conversation:subscribe', {
|
|
6169
6138
|
conversation_id: this.messengerState.activeConversationId,
|
|
@@ -6177,34 +6146,21 @@
|
|
|
6177
6146
|
})
|
|
6178
6147
|
);
|
|
6179
6148
|
|
|
6180
|
-
// Connect
|
|
6181
6149
|
this.wsService.connect();
|
|
6182
6150
|
}
|
|
6183
6151
|
|
|
6184
|
-
/**
|
|
6185
|
-
* Open the messenger panel
|
|
6186
|
-
*/
|
|
6187
6152
|
open() {
|
|
6188
6153
|
this.messengerState.setOpen(true);
|
|
6189
6154
|
}
|
|
6190
6155
|
|
|
6191
|
-
/**
|
|
6192
|
-
* Close the messenger panel
|
|
6193
|
-
*/
|
|
6194
6156
|
close() {
|
|
6195
6157
|
this.messengerState.setOpen(false);
|
|
6196
6158
|
}
|
|
6197
6159
|
|
|
6198
|
-
/**
|
|
6199
|
-
* Toggle the messenger panel
|
|
6200
|
-
*/
|
|
6201
6160
|
toggle() {
|
|
6202
6161
|
this.messengerState.setOpen(!this.messengerState.isOpen);
|
|
6203
6162
|
}
|
|
6204
6163
|
|
|
6205
|
-
/**
|
|
6206
|
-
* Navigate to a specific view
|
|
6207
|
-
*/
|
|
6208
6164
|
navigateTo(view) {
|
|
6209
6165
|
this.messengerState.setView(view);
|
|
6210
6166
|
if (!this.messengerState.isOpen) {
|
|
@@ -6212,52 +6168,31 @@
|
|
|
6212
6168
|
}
|
|
6213
6169
|
}
|
|
6214
6170
|
|
|
6215
|
-
/**
|
|
6216
|
-
* Set conversations
|
|
6217
|
-
*/
|
|
6218
6171
|
setConversations(conversations) {
|
|
6219
6172
|
this.messengerState.setConversations(conversations);
|
|
6220
6173
|
}
|
|
6221
6174
|
|
|
6222
|
-
/**
|
|
6223
|
-
* Add a message to a conversation
|
|
6224
|
-
*/
|
|
6225
6175
|
addMessage(conversationId, message) {
|
|
6226
6176
|
this.messengerState.addMessage(conversationId, message);
|
|
6227
6177
|
}
|
|
6228
6178
|
|
|
6229
|
-
/**
|
|
6230
|
-
* Set help articles
|
|
6231
|
-
*/
|
|
6232
6179
|
setHelpArticles(articles) {
|
|
6233
6180
|
this.messengerState.setHelpArticles(articles);
|
|
6234
6181
|
}
|
|
6235
6182
|
|
|
6236
|
-
/**
|
|
6237
|
-
* Set home changelog items
|
|
6238
|
-
*/
|
|
6239
6183
|
setHomeChangelogItems(items) {
|
|
6240
6184
|
this.messengerState.setHomeChangelogItems(items);
|
|
6241
6185
|
}
|
|
6242
6186
|
|
|
6243
|
-
/**
|
|
6244
|
-
* Set changelog items
|
|
6245
|
-
*/
|
|
6246
6187
|
setChangelogItems(items) {
|
|
6247
6188
|
this.messengerState.setChangelogItems(items);
|
|
6248
6189
|
}
|
|
6249
6190
|
|
|
6250
|
-
/**
|
|
6251
|
-
* Update unread count (for external updates)
|
|
6252
|
-
*/
|
|
6253
6191
|
setUnreadCount(count) {
|
|
6254
6192
|
this.messengerState.unreadCount = count;
|
|
6255
6193
|
this.messengerState._notify('unreadCountChange', { count });
|
|
6256
6194
|
}
|
|
6257
6195
|
|
|
6258
|
-
/**
|
|
6259
|
-
* Get current state
|
|
6260
|
-
*/
|
|
6261
6196
|
getState() {
|
|
6262
6197
|
return {
|
|
6263
6198
|
isOpen: this.messengerState.isOpen,
|
|
@@ -6267,11 +6202,7 @@
|
|
|
6267
6202
|
};
|
|
6268
6203
|
}
|
|
6269
6204
|
|
|
6270
|
-
/**
|
|
6271
|
-
* Load initial data (mock or API)
|
|
6272
|
-
*/
|
|
6273
6205
|
async loadInitialData() {
|
|
6274
|
-
// Load conversations
|
|
6275
6206
|
try {
|
|
6276
6207
|
const conversations = await this._fetchConversations();
|
|
6277
6208
|
this.messengerState.setConversations(conversations);
|
|
@@ -6279,7 +6210,6 @@
|
|
|
6279
6210
|
console.error('[MessengerWidget] Failed to load conversations:', error);
|
|
6280
6211
|
}
|
|
6281
6212
|
|
|
6282
|
-
// Load help articles if enabled
|
|
6283
6213
|
if (this.messengerOptions.enableHelp) {
|
|
6284
6214
|
try {
|
|
6285
6215
|
const articles = await this._fetchHelpArticles();
|
|
@@ -6289,7 +6219,6 @@
|
|
|
6289
6219
|
}
|
|
6290
6220
|
}
|
|
6291
6221
|
|
|
6292
|
-
// Load changelog if enabled
|
|
6293
6222
|
if (this.messengerOptions.enableChangelog) {
|
|
6294
6223
|
try {
|
|
6295
6224
|
const { homeItems, changelogItems } = await this._fetchChangelog();
|
|
@@ -6305,7 +6234,6 @@
|
|
|
6305
6234
|
try {
|
|
6306
6235
|
const response = await this.apiService.getConversations();
|
|
6307
6236
|
if (response.status && response.data) {
|
|
6308
|
-
// Transform API response to local format
|
|
6309
6237
|
return response.data.map((conv) => ({
|
|
6310
6238
|
id: conv.id,
|
|
6311
6239
|
title:
|
|
@@ -6336,7 +6264,6 @@
|
|
|
6336
6264
|
try {
|
|
6337
6265
|
const response = await this.apiService.getHelpCollections();
|
|
6338
6266
|
if (response.status && response.data) {
|
|
6339
|
-
// Transform API response to local format
|
|
6340
6267
|
return response.data.map((collection) => ({
|
|
6341
6268
|
id: collection.id,
|
|
6342
6269
|
title: collection.title || collection.name,
|
|
@@ -6354,9 +6281,6 @@
|
|
|
6354
6281
|
}
|
|
6355
6282
|
}
|
|
6356
6283
|
|
|
6357
|
-
/**
|
|
6358
|
-
* Fetch messages for a conversation
|
|
6359
|
-
*/
|
|
6360
6284
|
async fetchMessages(conversationId) {
|
|
6361
6285
|
try {
|
|
6362
6286
|
const response = await this.apiService.getConversation(conversationId);
|
|
@@ -6365,11 +6289,12 @@
|
|
|
6365
6289
|
let attachments;
|
|
6366
6290
|
if (msg.attachments) {
|
|
6367
6291
|
try {
|
|
6368
|
-
attachments =
|
|
6369
|
-
|
|
6370
|
-
|
|
6292
|
+
attachments =
|
|
6293
|
+
typeof msg.attachments === 'string'
|
|
6294
|
+
? JSON.parse(msg.attachments)
|
|
6295
|
+
: msg.attachments;
|
|
6371
6296
|
} catch (e) {
|
|
6372
|
-
// ignore
|
|
6297
|
+
// ignore
|
|
6373
6298
|
}
|
|
6374
6299
|
}
|
|
6375
6300
|
return {
|
|
@@ -6377,16 +6302,18 @@
|
|
|
6377
6302
|
content: msg.content,
|
|
6378
6303
|
isOwn: msg.sender_type === 'customer',
|
|
6379
6304
|
timestamp: msg.created_at,
|
|
6380
|
-
attachments:
|
|
6305
|
+
attachments:
|
|
6306
|
+
attachments && attachments.length > 0 ? attachments : undefined,
|
|
6381
6307
|
sender: {
|
|
6382
|
-
name:
|
|
6308
|
+
name:
|
|
6309
|
+
msg.sender_name ||
|
|
6310
|
+
(msg.sender_type === 'customer' ? 'You' : 'Support'),
|
|
6383
6311
|
avatarUrl: msg.sender_avatar || null,
|
|
6384
6312
|
},
|
|
6385
6313
|
};
|
|
6386
6314
|
});
|
|
6387
6315
|
this.messengerState.setMessages(conversationId, messages);
|
|
6388
6316
|
|
|
6389
|
-
// Mark as read
|
|
6390
6317
|
await this.apiService.markConversationAsRead(conversationId);
|
|
6391
6318
|
this.messengerState.markAsRead(conversationId);
|
|
6392
6319
|
|
|
@@ -6399,19 +6326,18 @@
|
|
|
6399
6326
|
}
|
|
6400
6327
|
}
|
|
6401
6328
|
|
|
6402
|
-
/**
|
|
6403
|
-
* Start a new conversation
|
|
6404
|
-
*/
|
|
6405
6329
|
async startNewConversation(message, subject = '', pendingAttachments = []) {
|
|
6406
6330
|
try {
|
|
6407
|
-
|
|
6408
|
-
|
|
6331
|
+
const uploadedAttachments =
|
|
6332
|
+
await this._uploadPendingAttachments(pendingAttachments);
|
|
6409
6333
|
|
|
6410
6334
|
console.log('[MessengerWidget] Starting conversation...', {
|
|
6411
6335
|
message,
|
|
6412
6336
|
attachmentCount: uploadedAttachments.length,
|
|
6413
6337
|
hasSession: this.apiService.isSessionValid(),
|
|
6414
|
-
sessionToken: this.apiService.sessionToken
|
|
6338
|
+
sessionToken: this.apiService.sessionToken
|
|
6339
|
+
? this.apiService.sessionToken.substring(0, 10) + '...'
|
|
6340
|
+
: null,
|
|
6415
6341
|
baseURL: this.apiService.baseURL,
|
|
6416
6342
|
mock: this.apiService.mock,
|
|
6417
6343
|
});
|
|
@@ -6436,10 +6362,8 @@
|
|
|
6436
6362
|
status: 'open',
|
|
6437
6363
|
};
|
|
6438
6364
|
|
|
6439
|
-
// Add to state
|
|
6440
6365
|
this.messengerState.addConversation(newConversation);
|
|
6441
6366
|
|
|
6442
|
-
// Set initial message in messages cache
|
|
6443
6367
|
this.messengerState.setMessages(conv.id, [
|
|
6444
6368
|
{
|
|
6445
6369
|
id: 'msg_' + Date.now(),
|
|
@@ -6449,7 +6373,6 @@
|
|
|
6449
6373
|
},
|
|
6450
6374
|
]);
|
|
6451
6375
|
|
|
6452
|
-
// Navigate to chat
|
|
6453
6376
|
this.messengerState.setActiveConversation(conv.id);
|
|
6454
6377
|
this.messengerState.setView('chat');
|
|
6455
6378
|
|
|
@@ -6462,20 +6385,14 @@
|
|
|
6462
6385
|
}
|
|
6463
6386
|
}
|
|
6464
6387
|
|
|
6465
|
-
/**
|
|
6466
|
-
* Send typing indicator
|
|
6467
|
-
*/
|
|
6468
6388
|
async sendTypingIndicator(conversationId, isTyping) {
|
|
6469
6389
|
try {
|
|
6470
6390
|
await this.apiService.sendTypingIndicator(conversationId, isTyping);
|
|
6471
6391
|
} catch (error) {
|
|
6472
|
-
//
|
|
6392
|
+
// Silent fail
|
|
6473
6393
|
}
|
|
6474
6394
|
}
|
|
6475
6395
|
|
|
6476
|
-
/**
|
|
6477
|
-
* Check agent availability
|
|
6478
|
-
*/
|
|
6479
6396
|
async checkAgentAvailability() {
|
|
6480
6397
|
try {
|
|
6481
6398
|
const response = await this.apiService.checkAgentsOnline();
|
|
@@ -6484,9 +6401,10 @@
|
|
|
6484
6401
|
this.messengerState.onlineCount = response.data.online_count || 0;
|
|
6485
6402
|
this.messengerState.responseTime = response.data.response_time || '';
|
|
6486
6403
|
|
|
6487
|
-
// Update team avatars from online agents
|
|
6488
6404
|
if (response.data.available_agents) {
|
|
6489
|
-
this.messengerState.setTeamAvatarsFromAgents(
|
|
6405
|
+
this.messengerState.setTeamAvatarsFromAgents(
|
|
6406
|
+
response.data.available_agents
|
|
6407
|
+
);
|
|
6490
6408
|
}
|
|
6491
6409
|
|
|
6492
6410
|
this.messengerState._notify('availabilityUpdate', response.data);
|
|
@@ -6578,11 +6496,9 @@
|
|
|
6578
6496
|
};
|
|
6579
6497
|
}
|
|
6580
6498
|
|
|
6581
|
-
// Fetch changelogs from API
|
|
6582
6499
|
const response = await this.apiService.getChangelogs({ limit: 20 });
|
|
6583
6500
|
const changelogs = response.data || [];
|
|
6584
6501
|
|
|
6585
|
-
// Map API response to expected format
|
|
6586
6502
|
const mappedItems = changelogs.map((item) => ({
|
|
6587
6503
|
id: item.id,
|
|
6588
6504
|
title: item.title,
|
|
@@ -6600,19 +6516,30 @@
|
|
|
6600
6516
|
};
|
|
6601
6517
|
}
|
|
6602
6518
|
|
|
6603
|
-
onMount() {
|
|
6604
|
-
|
|
6519
|
+
async onMount() {
|
|
6520
|
+
const userContext = this.messengerState.userContext;
|
|
6521
|
+
if (userContext?.email && userContext?.name) {
|
|
6522
|
+
try {
|
|
6523
|
+
await this.apiService.identifyContact({
|
|
6524
|
+
name: userContext.name,
|
|
6525
|
+
email: userContext.email,
|
|
6526
|
+
});
|
|
6527
|
+
console.log('[MessengerWidget] User identified successfully');
|
|
6528
|
+
} catch (error) {
|
|
6529
|
+
if (error?.code !== 'ALREADY_IDENTIFIED') {
|
|
6530
|
+
console.warn('[MessengerWidget] Identification failed:', error);
|
|
6531
|
+
}
|
|
6532
|
+
}
|
|
6533
|
+
}
|
|
6534
|
+
|
|
6605
6535
|
this.loadInitialData();
|
|
6606
6536
|
|
|
6607
|
-
// Initialize WebSocket for real-time updates
|
|
6608
6537
|
if (this.apiService?.sessionToken) {
|
|
6609
6538
|
this._initWebSocket();
|
|
6610
6539
|
}
|
|
6611
6540
|
|
|
6612
|
-
// Check agent availability
|
|
6613
6541
|
this.checkAgentAvailability();
|
|
6614
6542
|
|
|
6615
|
-
// Periodically check availability (every 60 seconds)
|
|
6616
6543
|
this._availabilityInterval = setInterval(() => {
|
|
6617
6544
|
this.checkAgentAvailability();
|
|
6618
6545
|
}, 60000);
|
|
@@ -6623,16 +6550,13 @@
|
|
|
6623
6550
|
this._stateUnsubscribe();
|
|
6624
6551
|
}
|
|
6625
6552
|
|
|
6626
|
-
// Clean up WebSocket
|
|
6627
6553
|
if (this.wsService) {
|
|
6628
6554
|
this.wsService.disconnect();
|
|
6629
6555
|
}
|
|
6630
6556
|
|
|
6631
|
-
// Clean up WebSocket event listeners
|
|
6632
6557
|
this._wsUnsubscribers.forEach((unsub) => unsub());
|
|
6633
6558
|
this._wsUnsubscribers = [];
|
|
6634
6559
|
|
|
6635
|
-
// Clean up availability interval
|
|
6636
6560
|
if (this._availabilityInterval) {
|
|
6637
6561
|
clearInterval(this._availabilityInterval);
|
|
6638
6562
|
}
|