UNPKG

podchat-browser

Version:

Javascript SDK to use POD's Chat Service - Browser Only

329 lines (289 loc) 12.7 kB
import {chatMessageVOTypes} from "./lib/constants" import DOMPurify from 'dompurify' import Utility from "./utility/utility" import {errorList} from "./lib/errorHandler"; import buildConfig from "./buildConfig.json"; /** * Communicates with chat server * @param app * @param params * @constructor */ function ChatMessaging(app, params) { let currentModuleInstance = this, asyncClient = params.asyncClient; //Utility = params.Utility, // consoleLogging = app.sdkParams.consoleLogging, //generalTypeCode = app.sdkParams.generalTypeCode, //chatPingMessageInterval = params.chatPingMessageInterval, //asyncRequestTimeout = params.asyncRequestTimeout, //messageTtl = params.messageTtl, //serverName = params.serverName, //msgPriority = params.msgPriority, //typeCodeOwnerId = app.sdkParams.typeCodeOwnerId || null; this.threadCallbacks = {}; this.sendMessageCallbacks = {}; // this.messagesCallbacks = {}; // this.asyncRequestTimeouts = {}; // this.sendPingTimeout = null; this.chatState = false; this.userInfo = null; /** * sendPingTimeout removed, * */ this.startChatPing = function () { app.sdkParams.chatPingMessageInterval && clearInterval(app.sdkParams.chatPingMessageInterval); app.sdkParams.chatPingMessageInterval = setInterval(() => { currentModuleInstance.ping(); }, 20000);//TODO: chatPingMessageInterval } this.stopChatPing = function () { clearInterval(app.sdkParams.chatPingMessageInterval); } this.asyncInitialized = function (client) { asyncClient = client } /** * Send Message * * All socket messages go through this function * * @access private * * @param {string} token SSO Token of current user * @param {string} tokenIssuer Issuer of token (default : 1) * @param {int} type Type of message (object : chatMessageVOTypes) * @param {string} typeCode Type of contact who is going to receive the message * @param {int} messageType Type of Message, in order to filter messages * @param {long} subjectId Id of chat thread * @param {string} uniqueId Tracker id for client * @param {string} content Content of message * @param {long} time Time of message, filled by chat server * @param {string} medadata Metadata for message (Will use when needed) * @param {string} systemMedadata Metadata for message (To be Set by client) * @param {long} repliedTo Id of message to reply to (Should be filled by client) * @param {function} callback The callback function to run after * * @return {object} Instant Function Return */ this.sendMessage = function (params, callbacks, recursiveCallback) { if (!currentModuleInstance.chatState && chatMessageVOTypes.USER_INFO != params.chatMessageVOType) { let clbck; if (!callbacks) { clbck = null; } else if (typeof callbacks === "function") { clbck = callbacks; } else if (callbacks.onResult) { clbck = callbacks.onResult; } app.errorHandler.raiseError(errorList.SOCKET_NOT_CONNECTED, clbck, true, {}); return; } /** * + ChatMessage {object} * - token {string} * - tokenIssuer {string} * - type {int} * - typeCode {string} * - messageType {int} * - subjectId {int} * - uniqueId {string} * - content {string} * - time {int} * - medadata {string} * - systemMedadata {string} * - repliedTo {int} */ var threadId = null; var asyncPriority = (params.asyncPriority > 0) ? params.asyncPriority : app.sdkParams.msgPriority; var messageVO = { type: params.chatMessageVOType, token: app.sdkParams.token, tokenIssuer: 1, agentName: 'podchat-browser', agentVersion: buildConfig.version }; if (params.typeCode) { messageVO.typeCode = params.typeCode; } else { messageVO.typeCode = app.typeCodes.getActiveTypeCode().typeCode; } if (params.ownerId) { messageVO.ownerId = params.ownerId; } else { messageVO.ownerId = app.typeCodes.getActiveTypeCode().ownerId; } // if (app.sdkParams.typeCodeOwnerId) { // messageVO.ownerId = app.sdkParams.typeCodeOwnerId; // } if (params.messageType) { messageVO.messageType = params.messageType; } if (params.subjectId) { threadId = params.subjectId; messageVO.subjectId = params.subjectId; } if (params.content) { if (typeof params.content == 'object') { messageVO.content = JSON.stringify(params.content); } else { messageVO.content = params.content; if (DOMPurify.isSupported) { messageVO.content = DOMPurify.sanitize(messageVO.content, {ALLOWED_TAGS: []}); } } } if (params.metadata) { messageVO.metadata = params.metadata; } if (params.systemMetadata) { messageVO.systemMetadata = params.systemMetadata; } if (params.repliedTo) { messageVO.repliedTo = params.repliedTo; } var uniqueId; if (typeof params.uniqueId != 'undefined') { uniqueId = params.uniqueId; } else if (params.chatMessageVOType !== chatMessageVOTypes.PING) { uniqueId = Utility.generateUUID(); } if (Array.isArray(uniqueId)) { messageVO.uniqueId = JSON.stringify(uniqueId); } else { messageVO.uniqueId = uniqueId; } if (typeof callbacks == 'object') { if (callbacks.onSeen || callbacks.onDeliver || callbacks.onSent) { if (!app.store.threadCallbacks[threadId]) { app.store.threadCallbacks[threadId] = {}; } app.store.threadCallbacks[threadId][uniqueId] = {}; app.store.sendMessageCallbacks[uniqueId] = {}; if (callbacks.onSent) { app.store.sendMessageCallbacks[uniqueId].onSent = callbacks.onSent; app.store.threadCallbacks[threadId][uniqueId].onSent = false; app.store.threadCallbacks[threadId][uniqueId].uniqueId = uniqueId; } if (callbacks.onSeen) { app.store.sendMessageCallbacks[uniqueId].onSeen = callbacks.onSeen; app.store.threadCallbacks[threadId][uniqueId].onSeen = false; } if (callbacks.onDeliver) { app.store.sendMessageCallbacks[uniqueId].onDeliver = callbacks.onDeliver; app.store.threadCallbacks[threadId][uniqueId].onDeliver = false; } } else if (callbacks.onResult) { app.store.messagesCallbacks[uniqueId] = callbacks.onResult; } } else if (typeof callbacks == 'function') { app.store.messagesCallbacks[uniqueId] = callbacks; } /** * Message to send through async SDK * * + MessageWrapperVO {object} * - type {int} Type of ASYNC message based on content * + content {string} * -peerName {string} Name of receiver Peer * -receivers[] {int} Array of receiver peer ids (if you use this, peerName will be ignored) * -priority {int} Priority of message 1-10, lower has more priority * -messageId {int} Id of message on your side, not required * -ttl {int} Time to live for message in milliseconds * -content {string} Chat Message goes here after stringifying * - trackId {int} Tracker id of message that you receive from DIRANA previously (if you are replying a sync message) */ var data = { type: (parseInt(params.pushMsgType) > 0) ? params.pushMsgType : 3, content: { peerName: app.sdkParams.serverName, priority: asyncPriority, content: JSON.stringify(messageVO), ttl: (params.messageTtl > 0) ? params.messageTtl : app.sdkParams.messageTtl }, uniqueId: messageVO.uniqueId }; asyncClient.send(data, function (res) { if (!res.hasError && callbacks) { if (typeof callbacks == 'function') { callbacks(res); } else if (typeof callbacks == 'object' && typeof callbacks.onResult == 'function') { callbacks.onResult(res); } if (app.store.messagesCallbacks[uniqueId]) { delete app.store.messagesCallbacks[uniqueId]; } } }); if (app.sdkParams.asyncRequestTimeout > 0) { app.store.asyncRequestTimeouts[uniqueId] && clearTimeout(app.store.asyncRequestTimeouts[uniqueId]); app.store.asyncRequestTimeouts[uniqueId] = setTimeout(function () { if (typeof callbacks == 'function') { callbacks({ hasError: true, errorCode: 408, errorMessage: 'Async Request Timed Out!' }); } else if (typeof callbacks == 'object' && typeof callbacks.onResult == 'function') { callbacks.onResult({ hasError: true, errorCode: 408, errorMessage: 'Async Request Timed Out!' }); } if (app.store.messagesCallbacks[uniqueId]) { delete app.store.messagesCallbacks[uniqueId]; } if (app.store.sendMessageCallbacks[uniqueId]) { delete app.store.sendMessageCallbacks[uniqueId]; } if (!!app.store.threadCallbacks[threadId] && app.store.threadCallbacks[threadId][uniqueId]) { app.store.threadCallbacks[threadId][uniqueId] = {}; delete app.store.threadCallbacks[threadId][uniqueId]; } }, app.sdkParams.asyncRequestTimeout); } /* currentModuleInstance.sendPingTimeout && clearTimeout(currentModuleInstance.sendPingTimeout); currentModuleInstance.sendPingTimeout = setTimeout(function () { currentModuleInstance.ping(); }, chatPingMessageInterval); */ recursiveCallback && recursiveCallback(); return { uniqueId: uniqueId, threadId: threadId, participant: currentModuleInstance.userInfo?.id,// currentModuleInstance.userInfo, content: params.content }; } /** * Ping * * This Function sends ping message to keep user connected to * chat server and updates its status * * @access private * * @return {undefined} */ this.ping = function () { if (currentModuleInstance.chatState && typeof currentModuleInstance.userInfo !== 'undefined') { /** * Ping messages should be sent ASAP, because * we don't want to wait for send queue, we send them * right through async from here */ currentModuleInstance.sendMessage({ chatMessageVOType: chatMessageVOTypes.PING, pushMsgType: 3 }); } }; } export default ChatMessaging;