podchat-browser
Version:
Javascript SDK to use POD's Chat Service - Browser Only
1,194 lines (1,062 loc) • 379 kB
JavaScript
'use strict';
import App from "./lib/app";
import Async from "podasync-ws-only"
import Utility from "./utility/utility"
import ChatCall from "./call.module"
import ChatMessaging from "./messaging.module"
import buildConfig from "./buildConfig.json"
import {deprecatedString, printIsDeprecate} from "./deprecateMethods";
import xss from "xss"
import ThreadParticipantsMethods from "./lib/chat/threadParticipantsMethods"
import {
chatMessageVOTypes,
inviteeVOidTypes,
createThreadTypes,
chatMessageTypes,
assistantActionTypes,
systemMessageTypes,
imageMimeTypes,
imageExtentions,
callStickerTypes,
chatStickerTypes,
customizeReactionTypes,
CHAT_ERRORS,
podspace,
restrictableCallActions
} from "./lib/constants";
import ReactionsMethods from "./lib/chat/reactionsMethods";
import ThreadMethods from "./lib/chat/threadMethods";
import {errorList} from "./lib/errorHandler"
import TypeCodes from "./lib/store/typecodes";
import ContactsMethods from "./lib/chat/contactsMethods";
import ContactsV2 from "./lib/chat/contacts/contactsV2";
import {
formatDataToMakeConversation,
formatDataToMakeAssistanthistoryItem,
formatDataToMakeInvitee,
formatDataToMakeMessage,
formatDataToMakeBlockedUser,
formatDataToMakeContact,
formatDataToMakeReplyInfo,
formatDataToMakeAssistantHistoryList,
formatDataToMakeUser,
formatDataToMakeForwardInfo,
formatDataToMakeParticipant,
reformatThreadHistory,
formatDataToMakeLinkedUser,
formatDataToMakePinMessage
} from './lib/helpers/dataFormatters';
import {initSdkParams} from "./lib/sdkParams";
import threadMethods from "./lib/chat/threadMethods";
function Chat(params) {
/*******************************************************
* P R I V A T E V A R I A B L E S *
*******************************************************/
const app = new App();
initSdkParams(app, params);
const publicized = {};
if (params.loggerConfig)
app.logger.processInitConfig(params.loggerConfig)
const typeCodes = new TypeCodes({
app,
whiteList: params.typeCodesList,
current: {
typeCode: params.typeCode || 'default',
ownerId: params.typeCodeOwnerId || undefined
}
});
app.typeCodes = typeCodes;
app.contact = new ContactsV2(app);
publicized.contact = {
add: app.contact.add,
remove: app.contact.remove,
get: app.contact.get,
update: app.contact.update
};
const reactionsMethods = new ReactionsMethods(app);
const contactsMethods = new ContactsMethods(app);
const threadParticipantsMethods = new ThreadParticipantsMethods(app);
var asyncClient,
peerId,
oldPeerId,
localDeviceId,
cacheInMemory = app.sdkParams.forceWaitQueueInMemory ? true : false,//!hasCache,
cacheSecret = 'VjaaS9YxNdVVAd3cAsRPcU5FyxRcyyV6tG6bFGjjK5RV8JJjLrXNbS5zZxnqUT6Y',
queueHost = params.queueHost,
queuePort = params.queuePort,
queueUsername = params.queueUsername,
queuePassword = params.queuePassword,
queueReceive = params.queueReceive,
queueSend = params.queueSend,
queueConnectionTimeout = params.queueConnectionTimeout,
config = {
getHistoryCount: 25
},
getUserInfoRetry = 5,
getUserInfoRetryCount = 0,
chatFullStateObject = {},
httpRequestObject = {},
minIntegerValue = Number.MAX_SAFE_INTEGER * -1,
maxIntegerValue = Number.MAX_SAFE_INTEGER,
chatWaitQueue = [],
protocolSwitching = params.protocolSwitching,
protocolManager = new ProtocolManager({protocol: app.sdkParams.protocol}),
asyncLogCallback = typeof params.asyncLogCallback == "function" ? params.asyncLogCallback : null,
msgLogCallback = typeof params.msgLogCallback == "function" ? params.msgLogCallback : null;
/**
* Minimum value for messageTtl is 2000
*/
if (app.sdkParams.messageTtl < 2000) {
app.sdkParams.messageTtl = 2000;
console.warn("[SDK] messageTtl can not be less than 2000, we changed it to 2000")
}
app.messenger = new ChatMessaging(app, Object.assign(params, {
asyncClient: asyncClient
}));
let callModule = new ChatCall(app, Object.assign(params, {
asyncClient: asyncClient
}));
function ProtocolManager({protocol = 'auto'}) {
const config = {
switchingEnabled: (protocol == "auto"),
currentProtocol: (protocol == "auto" ? 'websocket' : protocol),
failOverProtocol: (protocol == "auto" || protocol == "websocket" ? 'webrtc' : 'websocket'),
retries: 0,
allowedRetries: {
websocket: (protocolSwitching && typeof protocolSwitching.websocket !== "undefined" ? protocolSwitching.websocket : 1),
webrtc: (protocolSwitching && typeof protocolSwitching.webrtc !== "undefined" ? protocolSwitching.webrtc : 1)
},
currentWaitTime: 0
};
function canRetry() {
return config.retries <= config.allowedRetries[config.currentProtocol];
}
function switchProtocol(protocol, canResetRetries = true) {
asyncClient.logout().then(() => {
let current;
if (protocol) {
current = protocol.toLowerCase();
config.failOverProtocol = (current == "webrtc" ? "websocket" : "webrtc")
config.currentProtocol = current;
} else {
current = config.currentProtocol;
config.currentProtocol = config.failOverProtocol;
config.failOverProtocol = current;
}
app.sdkParams.consoleLogging && console.log("[SDK]|/| switchProtocol: ", "config.currentProtocol: ", config.currentProtocol, "config.currentWaitTime: ", config.currentWaitTime)
app.chatEvents.fireEvent("autoSwitchAsyncProtocol", {
current: config.currentProtocol,
previous: config.failOverProtocol
});
if (canResetRetries)
config.retries = 1;
initAsync();
})
}
function resetRetries() {
config.retries = 0;
}
const publics = {
switchProtocol(protocol) {
if (protocol == 'auto') {
config.switchingEnabled = true;
switchProtocol("websocket")
} else {
config.switchingEnabled = false;
switchProtocol(protocol)
}
},
increaseRetries() {
config.retries += 1;
},
canRetry,
getCurrentProtocol() {
return config.currentProtocol;
},
resetRetries() {
resetRetries();
},
resetTimerTime(time) {
config.currentWaitTime = (typeof time != "undefined" ? time : 0);
},
onAsyncIsReconnecting(event) {
app.sdkParams.consoleLogging && console.log("[SDK]|/| onAsyncIsReconnecting: ", "config.currentProtocol: ", config.currentProtocol, "config.currentWaitTime: ", config.currentWaitTime);
publics.increaseRetries();
if (config.currentWaitTime < 64) {
config.currentWaitTime += 3;
}
if (!canRetry() && config.switchingEnabled) {
switchProtocol();
}
},
getRetryStepTimerTime() {
return config.currentWaitTime;
},
reconnectAsync() {
publics.resetTimerTime();
if (config.switchingEnabled) {
if (canRetry()) {
publics.increaseRetries();
switchProtocol(config.currentProtocol, false);
// asyncClient.reconnectSocket();
} else {
switchProtocol();
}
} else {
// switchProtocol(config.currentProtocol);
asyncClient.reconnectSocket()
}
}
};
return publics;
}
/*******************************************************
* P R I V A T E M E T H O D S *
*******************************************************/
function onAsyncStateChange(state) {
app.chatEvents.fireEvent('chatState', state);
chatFullStateObject = state;
switch (state.socketState) {
case 1: // CONNECTED
protocolManager.resetRetries();
protocolManager.resetTimerTime();
if (state.deviceRegister && state.serverRegister) {
// app.messenger.chatState = true;
// app.messenger.ping();
app.messenger.startChatPing();
}
break;
case 0: // CONNECTING
app.messenger.chatState = false;
app.messenger.stopChatPing();
break;
case 2: // CLOSING
app.messenger.chatState = false;
app.messenger.stopChatPing();
break;
case 3: // CLOSED
app.store.reactionSummaries.removeAllMessages();
app.store.reactionsList.removeAllMessages();
// store.reactionsList.invalidateCache();
app.messenger.chatState = false;
app.messenger.stopChatPing();
if(app.call.currentCall() && app.call.currentCall().callServerController().isJanus()) {
app.call.currentCall().sendCallStatusEvent();
}
// TODO: Check if this is OK or not?!
//app.messenger.sendPingTimeout && clearTimeout(app.messenger.sendPingTimeout);
break;
}
}
var init = function () {
/**
* Initialize Cache Databases
*/
//startCacheDatabases(function () {
if (app.sdkParams.grantDeviceIdFromSSO) {
var getDeviceIdWithTokenTime = new Date().getTime();
getDeviceIdWithToken(function (retrievedDeviceId) {
if (app.sdkParams.actualTimingLog) {
Utility.chatStepLogger('Get Device ID ', new Date().getTime() - getDeviceIdWithTokenTime);
}
localDeviceId = retrievedDeviceId;
initAsync();
});
} else {
initAsync();
}
//});
},
/**
* Initialize Async
*
* Initializes Async module and sets proper callbacks
*
* @access private
*
* @return {undefined}
* @return {undefined}
*/
initAsync = function () {
var asyncGetReadyTime = new Date().getTime();
if (typeof app.sdkParams.appId == "number") {
app.sdkParams.appId = app.sdkParams.appId.toString()
}
if (typeof app.sdkParams.appId != "string" || app.sdkParams.appId.length > 30) {
app.errorHandler.raiseError(errorList.INVALID_APP_ID, null, true, {});
return;
}
asyncClient = new Async({
appId: app.sdkParams.appId,
protocol: protocolManager.getCurrentProtocol(),
queueHost: queueHost,
queuePort: queuePort,
queueUsername: queueUsername,
queuePassword: queuePassword,
queueReceive: queueReceive,
queueSend: queueSend,
queueConnectionTimeout: queueConnectionTimeout,
socketAddress: app.sdkParams.socketAddress,
serverName: app.sdkParams.serverName,
deviceId: app.store.asyncInfo.deviceId,
wsConnectionWaitTime: app.sdkParams.wsConnectionWaitTime,
connectionRetryInterval: app.sdkParams.connectionRetryInterval,
connectionCheckTimeout: app.sdkParams.connectionCheckTimeout,
connectionCheckTimeoutThreshold: app.sdkParams.connectionCheckTimeoutThreshold,
messageTtl: app.sdkParams.messageTtl,
reconnectOnClose: app.sdkParams.reconnectOnClose,
asyncLogging: app.sdkParams.asyncLogging,
logLevel: (app.sdkParams.consoleLogging ? 3 : 1),
webrtcConfig: app.sdkParams.webrtcConfig,
retryStepTimerTime: protocolManager.getRetryStepTimerTime(),
onStartWithRetryStepGreaterThanZero: onAsyncStateChange,
msgLogCallback: msgLogCallback || null,
asyncLogCallback: asyncLogCallback || null,
onDeviceId
});
function onDeviceId(deviceId) {
if (!app.store.asyncInfo.deviceId) {
app.store.asyncInfo.deviceId = deviceId;
}
asyncClient.registerDevice(app.store.asyncInfo.deviceId);
}
callModule.asyncInitialized(asyncClient);
app.messenger.asyncInitialized(asyncClient);
asyncClient.on('asyncReady', function () {
app.store.history.reset();
app.store.contacts.removeAll()
app.store.thread.removeAll()
if (app.sdkParams.actualTimingLog) {
Utility.chatStepLogger('Async Connection ', new Date().getTime() - asyncGetReadyTime);
}
// peerId = asyncClient.getPeerId();
app.store.asyncInfo.peerId = asyncClient.getPeerId();
// store.reactionSummaries.removeAllMessages();
if (!app.store.user.get()) {
getUserAndUpdateSDKState();
} else if (app.store.user.get().id > 0) {
app.messenger.chatState = true;
app.chatEvents.fireEvent('chatReady');
if(app.call.currentCall() && app.call.currentCall().callServerController().isJanus()) {
app.call.currentCall().sendCallStatusEvent();
}
chatSendQueueHandler();
}
app.sdkParams.seenInterval && clearInterval(app.sdkParams.seenInterval);
app.sdkParams.seenInterval = setInterval(function () {
if (Object.keys(app.sdkParams.messagesSeen).length) {
messagesSeenQueueHandler();
}
}, app.sdkParams.seenIntervalPitch);
//shouldReconnectCall();
});
asyncClient.on('stateChange', onAsyncStateChange);
asyncClient.on('connect', function (newPeerId) {
asyncGetReadyTime = new Date().getTime();
// peerId = newPeerId;
app.store.asyncInfo.peerId = newPeerId;
app.chatEvents.fireEvent('connect');
app.messenger.ping();
});
asyncClient.on('disconnect', function (event) {
// oldPeerId = peerId;
app.store.asyncInfo.oldPeerId = app.store.asyncInfo.peerId;
app.store.asyncInfo.peerId = undefined;
// peerId = undefined;
app.chatEvents.fireEvent('disconnect', event);
// app.chatEvents.fireEvent('callEvents', {
// type: 'CALL_ERROR',
// code: 7000,
// message: 'Call Socket is closed!',
// error: event
// });
});
asyncClient.on('reconnect', function (newPeerId) {
// peerId = newPeerId;
app.store.asyncInfo.peerId = newPeerId;
app.chatEvents.fireEvent('reconnect');
});
asyncClient.on('reconnecting', function (event) {
app.sdkParams.consoleLogging && console.log("[SDK][event: asyncClient.reconnecting]")
protocolManager.onAsyncIsReconnecting(event);
});
asyncClient.on('message', function (params, ack) {
receivedAsyncMessageHandler(params);
ack && ack();
});
asyncClient.on('error', function (error) {
app.chatEvents.fireEvent('error', {
code: error.errorCode,
message: error.errorMessage,
error: error.errorEvent
});
});
},
getUserAndUpdateSDKState = function () {
var getUserInfoTime = new Date().getTime();
getUserInfo(function (userInfoResult) {
if (app.sdkParams.actualTimingLog) {
Utility.chatStepLogger('Get User Info ', new Date().getTime() - getUserInfoTime);
}
if (!userInfoResult.hasError) {
app.store.user.setUser(userInfoResult.result.user);
// setSDKUser(userInfoResult.result.user);
// app.messenger.userInfo = userInfoResult.result.user;
// getAllThreads({
// summary: true,
// cache: false
// });
app.messenger.chatState = true;
app.chatEvents.fireEvent('chatReady');
if(app.call.currentCall() && app.call.currentCall().callServerController().isJanus()) {
app.call.currentCall().sendCallStatusEvent();
}
chatSendQueueHandler();
}
});
},
/**
* Deprecated
* Get Device Id With Token
*
* If ssoGrantDevicesAddress set as TRUE, chat agent gets Device ID
* from SSO server and passes it to Async Module
*
* @access private
*
* @param {function} callback The callback function to run after getting Device Id
*
* @return {undefined}
*/
getDeviceIdWithToken = function (callback) {
var deviceId;
var params = {
url: app.sdkParams.SERVICE_ADDRESSES.SSO_ADDRESS + app.sdkParams.SERVICES_PATH.SSO_DEVICES,
method: 'GET',
headers: {
'Authorization': 'Bearer ' + app.sdkParams.token
}
};
app.httpRequest.httpRequest(params, function (result) {
if (!result.hasError) {
var devices = JSON.parse(result.result.responseText).devices;
if (devices && devices.length > 0) {
for (var i = 0; i < devices.length; i++) {
if (devices[i].current) {
deviceId = devices[i].uid;
break;
}
}
if (!deviceId) {
app.chatEvents.fireEvent('error', {
code: 6000,
message: CHAT_ERRORS[6000],
error: null
});
} else {
callback(deviceId);
}
} else {
app.chatEvents.fireEvent('error', {
code: 6001,
message: CHAT_ERRORS[6001],
error: null
});
}
} else {
app.chatEvents.fireEvent('error', {
code: result.errorCode,
message: result.errorMessage,
error: result
});
}
});
},
/**
* Get User Info
*
* This functions gets user info from chat serverName.
* If info is not retrived the function will attemp
* 5 more times to get info from erver
*
* @recursive
* @access private
*
* @param {function} callback The callback function to call after
*
* @return {object} Instant function return
*/
getUserInfo = function getUserInfoRecursive(callback) {
getUserInfoRetryCount++;
if (getUserInfoRetryCount > getUserInfoRetry) {
app.sdkParams.getUserInfoTimeout && clearTimeout(app.sdkParams.getUserInfoTimeout);
getUserInfoRetryCount = 0;
app.chatEvents.fireEvent('error', {
code: 6101,
message: CHAT_ERRORS[6101],
error: null
});
} else {
app.sdkParams.getUserInfoTimeout && clearTimeout(app.sdkParams.getUserInfoTimeout);
app.sdkParams.getUserInfoTimeout = setTimeout(function () {
getUserInfoRecursive(callback);
}, getUserInfoRetryCount * 10000);
return app.messenger.sendMessage({
chatMessageVOType: chatMessageVOTypes.USER_INFO,
typeCode: params.typeCode//params.typeCode
}, {
onResult: function (result) {
var returnData = {
typeCode: result.typeCode,
ownerId: result.ownerId,
hasError: result.hasError,
cache: false,
errorMessage: result.errorMessage,
errorCode: result.errorCode
};
if (!returnData.hasError) {
app.sdkParams.getUserInfoTimeout && clearTimeout(app.sdkParams.getUserInfoTimeout);
var messageContent = result.result;
var currentUser = formatDataToMakeUser(messageContent);
returnData.result = {
user: currentUser
};
getUserInfoRetryCount = 0;
callback && callback(returnData);
/**
* Delete callback so if server pushes response
* before cache, cache won't send data again
*/
callback = undefined;
}
}
});
}
},
sendSystemMessage = function (params) {
return app.messenger.sendMessage({
chatMessageVOType: chatMessageVOTypes.SYSTEM_MESSAGE,
subjectId: params.threadId,
content: params.content,
uniqueId: params.uniqueId,
pushMsgType: 3
});
},
/**
* Chat Send Message Queue Handler
*
* Whenever something pushes into cahtSendQueue
* this function invokes and does the message
* sending progress throught async
*
* @access private
*
* @return {undefined}
*/
chatSendQueueHandler = function () {
if (app.store.chatSendQueue.length) {
var messageToBeSend = app.store.chatSendQueue[0];
app.store.history.remove(messageToBeSend.threadId);
/**
* Getting chatSendQueue from either cache or
* memory and scrolling through the send queue
* to send all the messages which are waiting
* for app.messenger.chatState to become TRUE
*
* There is a small possibility that a Message
* wouldn't make it through network, so it Will
* not reach chat server. To avoid losing those
* messages, we put a clone of every message
* in waitQ, and when ack of the message comes,
* we delete that message from waitQ. otherwise
* we assume that these messages have been failed to
* send and keep them to be either canceled or resent
* by user later. When user calls getHistory(), they
* will have failed messages alongside with typical
* messages history.
*/
if (app.messenger.chatState) {
app.messageQueues.getChatSendQueue(0, function (chatSendQueue) {
app.messageQueues.deleteFromChatSentQueue(messageToBeSend,
function () {
app.messenger.sendMessage(messageToBeSend.message, messageToBeSend.callbacks, function () {
if (app.store.chatSendQueue.length) {
chatSendQueueHandler();
}
});
});
});
}
}
},
/**
* Messages Seen Queue Handler
*
* Whenever something pushes into messagesSeen
* this function invokes and does the message
* seen progress throught async
*
* @access private
*
* @return {undefined}
*/
messagesSeenQueueHandler = function () {
if (Object.keys(app.sdkParams.messagesSeen).length) {
if (app.messenger.chatState) {
for (var key in app.sdkParams.messagesSeen) {
seen({
messageId: app.sdkParams.messagesSeen[key].messageId,
typeCode: app.sdkParams.messagesSeen[key].typeCode
});
delete app.sdkParams.messagesSeen[key];
}
}
}
},
/**
* Clear Cache
*
* Clears Async queue so that all the remained messages will be
* ignored
*
* @access private
*
* @return {undefined}
*/
clearChatServerCaches = function () {
app.messenger.sendMessage({
chatMessageVOType: chatMessageVOTypes.LOGOUT,
pushMsgType: 3
});
},
/**
* Received Async Message Handler
*
* This functions parses received message from async
*
* @access private
*
* @param {object} asyncMessage Received Message from Async
*
* @return {undefined}
*/
receivedAsyncMessageHandler = function (asyncMessage) {
/**
* + Message Received From Async {object}
* - id {int}
* - senderMessageId {int}
* - senderName {string}
* - senderId {int}
* - type {int}
* - content {string}
*/
if (asyncMessage.senderName === app.sdkParams.serverName) {
var content = JSON.parse(asyncMessage.content);
if (!content.typeCode || app.typeCodes.isAllowed(content.typeCode))
chatMessageHandler(content);
} else {
callModule.callMessageHandler(asyncMessage);
}
},
/**
* Chat Message Handler
*
* Manages received chat messages and do the job
*
* @access private
*
* @param {object} chatMessage Content of Async Message which is considered as Chat Message
*
* @return {undefined}
*/
chatMessageHandler = function (chatMessage) {
// if(chatMessage.typeCode && chatMessage.typeCode !== app.sdkParams.generalTypeCode) {
// return;
// }
var threadId = chatMessage.subjectId,
type = chatMessage.type,
typeCode = chatMessage.typeCode,
messageContent = (typeof chatMessage.content === 'string' && Utility.isValidJson(chatMessage.content))
? JSON.parse(chatMessage.content)
: chatMessage.content,
contentCount = chatMessage.contentCount,
uniqueId = chatMessage.uniqueId,
time = chatMessage.time;
app.store.asyncRequestTimeouts[uniqueId] && clearTimeout(app.store.asyncRequestTimeouts[uniqueId]);
switch (type) {
/**
* Type 1 Get Threads
*/
case chatMessageVOTypes.CREATE_THREAD:
app.threadMethods.onCreateThread(uniqueId, messageContent, contentCount, chatMessage);
break;
/**
* Type 2 Message
*/
case chatMessageVOTypes.MESSAGE:
newMessageHandler(threadId, messageContent, chatMessage, uniqueId);
break;
/**
* Type 3 Message Sent
*/
case chatMessageVOTypes.SENT:
if (app.store.sendMessageCallbacks[uniqueId] && app.store.sendMessageCallbacks[uniqueId].onSent) {
app.store.sendMessageCallbacks[uniqueId].onSent({
uniqueId: uniqueId,
messageId: messageContent,
typeCode: chatMessage.typeCode,
ownerId: chatMessage.ownerId
});
delete (app.store.sendMessageCallbacks[uniqueId].onSent);
if (app.store.threadCallbacks[threadId] && app.store.threadCallbacks[threadId][uniqueId])
app.store.threadCallbacks[threadId][uniqueId].onSent = true;
}
break;
/**
* Type 4 Message Delivery
*/
case chatMessageVOTypes.DELIVERY:
// var threadObject = {
// id: messageContent.conversationId,
// lastSeenMessageId: messageContent.messageId,
// lastSeenMessageTime: messageContent.messageTime,
// lastParticipantId: messageContent.participantId
// };
//
// app.chatEvents.fireEvent('threadEvents', {
// type: 'THREAD_LAST_ACTIVITY_TIME',
// result: {
// thread: threadObject
// }
// });
//
// // if (fullResponseObject) {
// // getHistory({
// // offset: 0,
// // threadId: threadId,
// // id: messageContent.messageId,
// // cache: false
// // }, function (result) {
// // if (!result.hasError) {
// // app.chatEvents.fireEvent('messageEvents', {
// // type: 'MESSAGE_DELIVERY',
// // result: {
// // message: result.result.history[0],
// // threadId: threadId,
// // senderId: messageContent.participantId
// // }
// // });
// // }
// // });
// // } else {
// // app.chatEvents.fireEvent('messageEvents', {
// // type: 'MESSAGE_DELIVERY',
// // result: {
// // message: messageContent.messageId,
// // threadId: threadId,
// // senderId: messageContent.participantId
// // }
// // });
// // }
//
// sendMessageCallbacksHandler(chatMessageVOTypes.DELIVERY, threadId, uniqueId);
//
break;
/**
* Type 5 Message Seen
*/
case chatMessageVOTypes.SEEN:
var threadObject = {
id: messageContent.conversationId,
lastSeenMessageId: messageContent.messageId,
lastSeenMessageTime: messageContent.messageTime,
lastParticipantId: messageContent.participantId
};
// check last message id with thread lastmessageVo and update deliverd and seen
const cachedLastMessageItem=app.store.thread.getLastMessageItem(threadId)
if(threadObject.lastSeenMessageId==cachedLastMessageItem.id){
app.store.thread.updateDelivered(threadId, true)
}
app.store.thread.updateMentioned(threadId, false)
app.chatEvents.fireEvent('threadEvents', {
type: 'THREAD_LAST_ACTIVITY_TIME',
result: {
thread: threadObject
}
});
app.chatEvents.fireEvent('messageEvents', {
type: 'MESSAGE_SEEN',
result: {
message: messageContent.messageId,
threadId: threadId,
senderId: messageContent.participantId
}
});
if (app.store.history.get(threadId)) {
app.store.history.updateSeen(threadId, threadObject.lastSeenMessageTime)
}
sendMessageCallbacksHandler(chatMessageVOTypes.SEEN, threadId, uniqueId);
break;
/**
* Type 6 Chat Ping
*/
case chatMessageVOTypes.PING:
break;
/**
* Type 7 Block Contact
*/
case chatMessageVOTypes.BLOCK:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](Utility.createReturnData(chatMessage.typeCode, chatMessage.ownerId, false, '', 0, messageContent));
}
break;
/**
* Type 8 Unblock Blocked User
*/
case chatMessageVOTypes.UNBLOCK:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](Utility.createReturnData(chatMessage.typeCode, chatMessage.ownerId, false, '', 0, messageContent));
}
break;
/**
* Type 9 Leave Thread
*/
case chatMessageVOTypes.LEAVE_THREAD:
app.threadMethods.onLeaveThread(uniqueId, messageContent, contentCount, chatMessage, threadId,typeCode)
break;
/**
* Type 11 Add Participant to Thread
*/
case chatMessageVOTypes.ADD_PARTICIPANT:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](Utility.createReturnData(chatMessage.typeCode, chatMessage.ownerId, false, '', 0, messageContent, contentCount));
}
if (app.sdkParams.fullResponseObject) {
app.threadMethods.getThreads({
threadIds: [messageContent.id],
typeCode,
}, function (threadsResult) {
var threads = threadsResult.result.threads;
if (!threadsResult.cache) {
app.chatEvents.fireEvent('threadEvents', {
type: 'THREAD_ADD_PARTICIPANTS',
result: {
thread: threads[0],
messageContent,
typeCode
}
});
app.chatEvents.fireEvent('threadEvents', {
type: 'THREAD_LAST_ACTIVITY_TIME',
result: {
thread: threads[0],
typeCode
}
});
}
});
} else {
app.chatEvents.fireEvent('threadEvents', {
type: 'THREAD_ADD_PARTICIPANTS',
result: {
thread: messageContent,
messageContent,
typeCode
}
});
app.chatEvents.fireEvent('threadEvents', {
type: 'THREAD_LAST_ACTIVITY_TIME',
result: {
thread: messageContent,
typeCode
}
});
}
break;
/**
* Type 13 Get Contacts List
*/
case chatMessageVOTypes.GET_CONTACTS:
contactsMethods.onGetContacts(uniqueId, messageContent, contentCount, chatMessage);
break;
/**
* Type 14 Get Threads List
*/
case chatMessageVOTypes.GET_THREADS:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](Utility.createReturnData(chatMessage.typeCode, chatMessage.ownerId, false, '', 0, messageContent, contentCount, uniqueId));
}
break;
/**
* Type 15 Get Message History of an Thread
*/
case chatMessageVOTypes.GET_HISTORY:
app.threadHistory.onGetHistory(uniqueId, messageContent, contentCount, chatMessage)
break;
/**
* Type 17 Remove sb from thread
*/
case chatMessageVOTypes.REMOVED_FROM_THREAD:
app.threadMethods.onRemovedFromThread(threadId)
break;
/**
* Type 18 Remove a participant from Thread
*/
case chatMessageVOTypes.REMOVE_PARTICIPANT:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](Utility.createReturnData(chatMessage.typeCode, chatMessage.ownerId, false, '', 0, messageContent, contentCount));
}
if (app.sdkParams.fullResponseObject) {
app.threadMethods.getThreads({
threadIds: [threadId],
typeCode,
}, function (threadsResult) {
var threads = threadsResult.result.threads;
if (!threadsResult.cache) {
app.chatEvents.fireEvent('threadEvents', {
type: 'THREAD_REMOVE_PARTICIPANTS',
result: {
thread: threads[0],
messageContent,
typeCode
}
});
app.chatEvents.fireEvent('threadEvents', {
type: 'THREAD_LAST_ACTIVITY_TIME',
result: {
thread: threads[0],
typeCode
}
});
}
});
} else {
app.chatEvents.fireEvent('threadEvents', {
type: 'THREAD_REMOVE_PARTICIPANTS',
result: {
thread: threadId,
messageContent,
typeCode
}
});
app.chatEvents.fireEvent('threadEvents', {
type: 'THREAD_LAST_ACTIVITY_TIME',
result: {
thread: threadId,
typeCode
}
});
}
break;
/**
* Type 19 Mute Thread
*/
case chatMessageVOTypes.MUTE_THREAD:
app.threadMethods.onMuteThread(uniqueId, messageContent, contentCount, chatMessage, threadId,typeCode)
break;
/**
* Type 20 Unmute muted Thread
*/
case chatMessageVOTypes.UNMUTE_THREAD:
app.threadMethods.onUnMuteThread(uniqueId, messageContent, contentCount, chatMessage, threadId,typeCode)
break;
/**
* Type 21 Update Thread Info
*/
case chatMessageVOTypes.UPDATE_THREAD_INFO:
app.threadMethods.onUpdateThreadInfo(uniqueId, messageContent, contentCount, chatMessage, threadId,typeCode)
break;
/**
* Type 22 Forward Multiple Messages
*/
case chatMessageVOTypes.FORWARD_MESSAGE:
newMessageHandler(threadId, messageContent, chatMessage, uniqueId);
break;
/**
* Type 23 User Info
*/
case chatMessageVOTypes.USER_INFO:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](Utility.createReturnData(chatMessage.typeCode, chatMessage.ownerId, false, '', 0, messageContent));
}
app.chatEvents.fireEvent('systemEvents', {
type: 'SERVER_TIME',
result: {
time: time
}
});
break;
/**
* Type 25 Get Blocked List
*/
case chatMessageVOTypes.GET_BLOCKED:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](Utility.createReturnData(chatMessage.typeCode, chatMessage.ownerId, false, '', 0, messageContent, contentCount));
}
break;
/**
* Type 27 Thread Participants List
*/
case chatMessageVOTypes.THREAD_PARTICIPANTS:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](Utility.createReturnData(chatMessage.typeCode, chatMessage.ownerId, false, '', 0, messageContent, contentCount));
}
break;
/**
* Type 28 Edit Message
*/
case chatMessageVOTypes.EDIT_MESSAGE:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](Utility.createReturnData(chatMessage.typeCode, chatMessage.ownerId, false, '', 0, messageContent, contentCount));
}
chatEditMessageHandler(threadId, messageContent, chatMessage, typeCode, uniqueId);
break;
/**
* Type 29 Delete Message
*/
case chatMessageVOTypes.DELETE_MESSAGE:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](Utility.createReturnData(chatMessage.typeCode, chatMessage.ownerId, false, '', 0, messageContent, contentCount));
}
let msgTime = (parseInt(parseInt(messageContent.time) / 1000) * 1000000000) + parseInt(messageContent.timeNanos);
if (app.store.threads.get(threadId))
app.store.threads.get(threadId).unreadCount.decrease(msgTime);
if (messageContent.pinned) {
unPinMessage({
messageId: messageContent.id,
notifyAll: true
});
}
app.store.history.removeMessage(threadId, messageContent.id);
if (app.sdkParams.fullResponseObject) {
var time, timeMiliSeconds;
if (messageContent.time.toString().length > 14) {
time = messageContent.time;
timeMiliSeconds = parseInt(messageContent.time / 1000000);
} else {
time = (messageContent.timeNanos)
? (parseInt(parseInt(messageContent.time) / 1000) * 1000000000) + parseInt(messageContent.timeNanos)
: (parseInt(pushMessageVO.time));
timeMiliSeconds = parseInt(messageContent.time);
}
app.threadMethods.getThreads({
threadIds: [threadId],
typeCode,
cache:false,
}, function (threadsResult) {
var threads = threadsResult.result.threads;
if (!threadsResult.cache) {
app.chatEvents.fireEvent('messageEvents', {
type: 'MESSAGE_DELETE',
result: {
typeCode: chatMessage.typeCode,
message: {
id: messageContent.id,
pinned: messageContent.pinned,
threadId: threadId,
time,
timeMiliSeconds,
timeNanos: messageContent.timeNanos
}
}
}