SmartIT_Extensions/BMC/smart-it-full-helix/components/chat/chat-service.js

732 lines
44 KiB
JavaScript

"use strict";
/**
* Jabber connection and data transport Class
* */
(function () {
'use strict';
angular.module('myitsmApp')
.factory("chatService", ['chatDefaults', 'userModel', '$q', '$resource', 'idService', '$timeout', '$interval', '$log',
function (chatDefaults, userModel, $q, $resource, idService, $timeout, $interval, $log) {
var JabberService;
//List of REST calls used by the Chat functionality
var resource = $resource('/smartit/rest/chat/:action/:jid:subAction/:roomId', { action: "@action", jid: "@jid", subAction: "@subAction", roomId: "@roomId" }, {
//Retrieve social profiles by JIDs list.
getSocialProfileByJID: {
method: "GET",
params: {
action: 'profiles',
fields: "jid,elementId,displayName,lastName,firstName,thumbnail"
}
},
//Creates a relation between existing XMPP room and Ticket instance and sends message stanza to all users inside the room
assignChatRoom: {
method: "POST",
params: {
action: "assign"
}
},
//Retrieve relation data of the XMPP room by it's jid
getRoomAssignments: {
method: 'GET',
params: {
action: "assignment"
},
isArray: false,
transformResponse: function (data) {
return (!data || _.isEmpty(data)) ? { assignmentData: null } : { assignmentData: JSON.parse(data) };
}
},
//Deletes room relation info from database and sends message with updated relation data to all conversation participants
removeRoomAssignment: {
method: 'DELETE',
params: {
action: "removeassignment"
}
},
saveChatLogToTicketWorknote: {
method: "POST",
params: {
action: 'save'
},
isArray: false,
transformResponse: function (data) {
return { success: !data, error: data };
}
},
requestConversationsHistoryForCurrentUser: {
method: "GET",
isArray: true,
params: {
action: 'history',
subAction: 'conversations'
}
},
getChatCredentials: {
method: 'GET',
params: {
action: 'credentials'
}
},
getTicketsBulk: {
method: "POST",
url: "/smartit/rest/bulkupdate/details",
isArray: true
}
});
JabberService = {
openChatConnection: function (options) {
if (JabberService.chatServerIsDisabled) {
var deferred = $q.defer();
$timeout(function () { deferred.reject('Chat server not installed'); }, 100);
return deferred.promise;
}
_.each(chatDefaults.additional_namespaces, function (ns) {
Strophe.addNamespace(ns.name, ns.def);
});
return resource.getChatCredentials().$promise
.then(function (credentials) {
if (credentials.boshUrl) {
return new JabberService.Connection(credentials, options);
}
else {
JabberService.chatServerIsDisabled = true;
var deferred = $q.defer();
$timeout(function () { deferred.reject('Chat server not installed'); }, 100);
return deferred.promise;
}
});
},
activeConnection: {},
defaultOptions: chatDefaults,
generateFullJID: function (type, name, customDomain) {
var domain = customDomain;
if (typeof (domain) == 'undefined') {
domain = JabberService.defaultOptions.domain;
}
if (type == 'User') {
return name + "@" + domain;
}
if (type == 'UserList') {
angular.forEach(name, function (val, key) {
name[key] = val + "@" + domain;
});
return name;
}
else if (type == 'ChatRoom') {
var uuid = idService.getRandomId();
return (name ? name : uuid) + "@" + JabberService.activeConnection.options.conference_service_name;
}
},
runCallback: function (cbName, context, args) {
var defaultCallbacks = JabberService.callbacks, callback = defaultCallbacks[cbName];
return callback.apply(context, args);
},
resolvePromise: function (promiseId, resolveData) {
var pendingPromises = JabberService.activeConnection.pendingPromises;
if (pendingPromises[promiseId] && pendingPromises[promiseId].hasOwnProperty('resolve')) {
JabberService.activeConnection.pendingPromises[promiseId].resolve(resolveData);
delete JabberService.activeConnection.pendingPromises[promiseId];
}
},
listeners: {
onPresence: function (presXML) {
// console.log("INBOUND Presence: ",Strophe.serialize(presXML));
var $presXML = $(presXML), from = presXML.getAttribute('from') || "", type = presXML.getAttribute("type") || "", xElements = presXML.getElementsByTagName('x');
if (type == 'subscribed')
return true;
if (type == 'subscribe')
return this.handleSubscriptionRequest(presXML, from);
//Handling case when user's Connection status changed
if (xElements.length == 0) {
var status, manualStatus, userId = Strophe.getNodeFromJid(from);
//User become unavailable, but connections from other resources can be still active
if (type == 'unavailable') {
var chatRooms = this.conn['muc'].rooms;
this.userSessions[userId] = _.without(this.userSessions[userId], from);
_.each(chatRooms, function (room) {
if (room.userSessions && room.userSessions[userId]) {
var sessionIndex = room.userSessions[userId].indexOf(from);
if (sessionIndex >= 0) {
room.userSessions[userId].splice(sessionIndex, 1);
}
}
});
if (this.userSessions[userId] && this.userSessions[userId].length > 0) {
return true;
}
status = EntityVO.CHAT_STATUS_OFFLINE;
}
else {
if (!presXML.childNodes.length) {
status = EntityVO.CHAT_STATUS_ONLINE;
}
else {
var statusNodes = $presXML.find("status"), showNodes = $presXML.find("show");
//If presence stanza contains status node, user status was changed manually, so all resources should inherit it
manualStatus = statusNodes.text();
status = showNodes.length > 0 ? showNodes.text() : EntityVO.CHAT_STATUS_ONLINE;
}
userId = Strophe.getNodeFromJid(from);
this.userSessions[userId] = _.union(this.userSessions[userId], [from]);
}
this.options.userCallbacks.presence(from, status, manualStatus);
return true;
}
else {
JabberService.listeners.onMUCPresence.apply(this, arguments);
}
return true;
},
onMUCPresence: function (presXML) {
var self = this, $presXML = $(presXML), id = presXML.getAttribute('id') || "", from = presXML.getAttribute('from') || "", type = presXML.getAttribute("type") || "", $xElements = $presXML.find('x');
_.each($xElements, function (xElem) {
var ns = xElem.getAttribute('xmlns');
if (ns && ns.match(Strophe.NS.MUC)) {
var roomName = from.split("/")[0], room = self.conn['muc'].rooms[roomName];
if (xElem.getElementsByTagName('destroy').length > 0) {
self.options.userCallbacks.chatRoomChanges(room, { type: 'destroy', data: { roomId: roomName } });
return true;
}
var userItems = xElem.getElementsByTagName('item'), affiliation = userItems[0] ? userItems[0].getAttribute('affiliation') : null, jid = userItems[0] ? userItems[0].getAttribute('jid') : "", userId = jid ? Strophe.getNodeFromJid(jid) : null, evt = (type == 'unavailable') ? 'leave' : 'enter';
if (self.pendingPromises[id]) {
JabberService.resolvePromise(id, room);
}
if (type != 'unavailable') {
if (!room.userSessions[userId] || (room.userSessions[userId] && room.userSessions[userId].length == 0)) {
room.userSessions[userId] = [jid];
}
else {
room.userSessions[userId] = _.union(room.userSessions[userId], [jid]);
return true;
}
}
else {
//When unavailable presence received, this automatically means that all user resources have left chat
if (room.userSessions[userId]) {
room.userSessions[userId] = [];
}
}
if (jid)
self.options.userCallbacks.chatRoomChanges(room, { type: 'roster',
data: { jid: jid, eventType: evt, roomId: roomName, affiliation: affiliation }
});
}
});
return true;
},
onMessage: function (msg) {
// console.log("INBOUND Message: ",Strophe.serialize(msg));
var self = this, $msg = $(msg), inviteQuery = "[xmlns='" + Strophe.NS['INVITE'] + "']", delayQuery = "[xmlns='" + Strophe.NS['DELAY'] + "']", inviteNS = $msg.find(inviteQuery).length > 0 ? true : false, delayNS = $msg.find(delayQuery);
messageType = msg.getAttribute('type');
if (messageType == 'headline') {
var threadQuery = msg.getElementsByTagName('thread'), fromAttr = msg.getAttribute('from');
if (threadQuery.length > 0 && fromAttr != this.conn.jid) {
var roomId = threadQuery[0].getAttribute('parent');
roomId && this.joinChat(roomId)
.then(function (room) {
self.options.userCallbacks.roomAutoJoin(room);
});
}
}
if (messageType == 'groupchat') {
//After openfire upgrade, server is sending subject even if blank as per below defect fixed in openfire
//https://igniterealtime.atlassian.net/browse/OF-1853
//Subject is not stored in openfire by SmartIT so discarding the same.
if ($msg.has('subject').length) {
return true;
}
var from = msg.getAttribute('from').split("/"), senderNick = from[1], roomName = from[0], room = this.conn.muc.rooms[roomName], message = $msg.text(), messageData;
if (message.indexOf("smart-it-connection") >= 0 || message.indexOf("smart-it-disconnection") >= 0) {
var messageType = (message.indexOf("smart-it-connection") >= 0) ? "smart-it-connection" : "smart-it-disconnection", chatParent = JSON.parse(message.replace(messageType + ":", ""));
this.options.userCallbacks.chatRoomChanges(room, { type: messageType.split("-").pop(), data: chatParent });
return true;
}
if (delayNS.length > 0) {
var senderJID = delayNS[0].getAttribute('from') && delayNS[0].getAttribute('from').split("/")[0], tStamp = delayNS[0].getAttribute('stamp');
messageData = { author: { jid: senderJID }, created: tStamp, text: $msg.text() };
}
!messageData ? messageData = { author: { nick: senderNick }, text: message } : angular.noop();
if (this.options.userCallbacks)
this.options.userCallbacks.message(messageData, roomName);
}
if (inviteNS && !window.opener) {
JabberService.listeners.onInvite.apply(this, arguments);
}
return true;
},
onInvite: function (msg) {
var $msg = $(msg);
var xquery = $msg.find("[xmlns='" + Strophe.NS['INVITE'] + "']");
if (!xquery.length) {
return true;
}
var roomName = Strophe.getBareJidFromJid(xquery[0].getAttribute('jid')), inviteJSON = { from: msg.getAttribute('from'), roomId: roomName };
if (this.options.userCallbacks) {
this.options.userCallbacks.invite(inviteJSON);
}
return true;
},
onRosterUpdate: function (iq) {
// console.log("Roster update", +Strophe.serialize(iq));
var self = this, items = iq.getElementsByTagName("item"), rosterUpdates = { removed: [], added: [] };
_.each(items, function (item) {
var jid = item.getAttribute('jid'), subscription = item.getAttribute('subscription');
if (subscription == 'remove') {
rosterUpdates.removed.push(jid);
var room = self.conn['muc'].rooms[jid];
room && self.leaveChatRoom(room);
if (window.opener)
window.close();
}
else
rosterUpdates.added.push(jid);
});
this.options.userCallbacks.rosterUpdates(rosterUpdates);
// this.conn.send($iq({type: 'result', id: $(iq).attr('id')}));
return true;
// console.log("onRosterUpdate",iq);
},
onPingReceived: function (ping) {
this.conn.ping.pong(ping);
return true;
}
},
callbacks: {
connectionState: function (status, condition) {
switch (status) {
case Strophe.Status.CONNECTING:
$log.log("STROPHE CONNECTION: Initiating BOSH session");
break;
case Strophe.Status.AUTHENTICATING:
$log.log("STROPHE CONNECTION: BOSH session initiated, authenticating user");
break;
case Strophe.Status.CONNECTED:
if (this.reconnecting) {
this.resendItems = _.clone(this.conn.cm.element_queue);
}
this.chatConnReconnectTimeOut = 100;
this.options.userCallbacks.connectionState('connected');
JabberService.runCallback('connected', this, [status, condition]);
break;
case Strophe.Status.CONNFAIL:
case Strophe.Status.AUTHFAIL:
case Strophe.Status.ERROR:
if (status == Strophe.Status.AUTHFAIL) {
$log.log("User authorization failed");
}
this.pendingPromises.disconnect.resolve(status, condition);
break;
case Strophe.Status.DISCONNECTED:
$log.log('Strophe is disconnected.');
this.options.userCallbacks.connectionState('disconnected');
this.chatConnReconnectTimeOut = this.chatConnReconnectTimeOut + 100;
if (this.conn.auto_reconnect) {
this.chatConnReconnectTimeOut = this.chatConnReconnectTimeOut + 100;
var obj = this;
this.reconnecting = false;
$timeout(function () { obj.reconnect(); }, this.chatConnReconnectTimeOut);
}
else {
this.pendingPromises.disconnect.resolve(status, condition);
}
break;
}
},
connected: function () {
this.reconnectAttempts = 0;
this.conn.addHandler(JabberService.listeners.onPresence.bind(this), null, 'presence');
this.conn.addHandler(JabberService.listeners.onMessage.bind(this), null, 'message');
this.conn.addHandler(JabberService.listeners.onRosterUpdate.bind(this), Strophe.NS.ROSTER, 'iq', "set");
this.conn.ping.addPingHandler(JabberService.listeners.onPingReceived.bind(this));
this.conn.send($pres().tree());
if (this.reconnecting) {
$log.log("Strophe has reconnected successfully!");
if (this.resendItems && this.resendItems.length > 0) {
this.resendLostStanzas();
}
if (this.reconnectInterval) {
$interval.cancel(this.reconnectInterval);
this.reconnectInterval = null;
}
this.reconnecting = false;
}
else {
this.pendingPromises.connectionState.resolve(this);
}
if (!window.opener)
this.getUserRoster(true);
$log.log("Strophe is connected!");
},
requestSuccess: function (respXML) {
// console.log("XMPP IQ Stanza(response): ",Strophe.serialize(respXML));
var responseJSON = JabberService.activeConnection.xmlTool.xml2json(respXML), reqId = responseJSON._id, normalizedResponse = {};
_.map(responseJSON, _.bind(function (item, key) {
if (key.indexOf("_") < 0) {
var respData;
//TODO: minimize xmlTool usage. Maybe it will be better to parse only part of xml that has NS match
switch (item._xmlns) {
case Strophe.NS['SMARTITIQ']:
this.queryResponse = { data: item.__text, name: item._name };
break;
case Strophe.NS['DISCO_ITEMS']:
case Strophe.NS['DISCO_INFO']:
var resArr = [].concat((item.identity || []), (item.feature || []), (item.item || []));
this.queryResponse = { data: resArr, node: item._node };
this.queryResponse.name = (item._xmlns == Strophe.NS.DISCO_INFO) ? 'DISCO_INFO' : 'DISCO_ITEM';
break;
case Strophe.NS['MUC_OWNER']:
// var respData = item.destroy || (new Strophe.x.Form.fromXML(respXML));
respData = item.destroy || JabberService.activeConnection.conn.x.parseFromResult(respXML);
this.queryResponse = { data: respData, name: 'MUC_OWNER' };
break;
case Strophe.NS['MUC_ADMIN']:
this.queryResponse = { data: item.item, name: 'MUC_ADMIN' };
break;
case Strophe.NS['SEARCH']:
respData = JabberService.activeConnection.conn.x.parseFromResult(respXML);
this.queryResponse = { data: respData, name: 'SEARCH' };
break;
case Strophe.NS['ROSTER']:
this.queryResponse = { data: item.item, name: 'ROSTER' };
break;
case Strophe.NS['ARCHIVE']:
this.queryResponse = { data: item, name: 'ARCHIVE' };
break;
}
}
else {
item ? this[key] = item : angular.noop();
}
}, normalizedResponse));
JabberService.resolvePromise(reqId, normalizedResponse);
return true;
},
requestError: function (errorXML) {
// console.log("Error", errorXML);
var id = errorXML.getAttribute('id'), errorItems = errorXML.getElementsByTagName('error'), errors = [];
_.each(errorItems, function (errorDOM) {
var errorItem = {
type: errorDOM.getAttribute('type'),
code: errorDOM.getAttribute('code'),
details: []
}, errorDetailNodes = errorDOM.hasChildNodes() ? errorDOM.childNodes : [];
_.each(errorDetailNodes, function (detailsNode) {
var detail = {
name: detailsNode.nodeName,
ns: detailsNode.getAttribute('xmlns')
};
errorItem.details.push(detail);
});
errors.push(errorItem);
});
if (JabberService.activeConnection.pendingPromises[id]) {
JabberService.activeConnection.pendingPromises[id].reject(errors);
delete JabberService.activeConnection.pendingPromises[id];
}
return errors;
}
}
};
JabberService.Connection = function (credentials, options) {
this.xmlTool = new X2JS({ attributePrefix: "" });
this.options = angular.extend(JabberService.defaultOptions, options);
this.options.domain = credentials.domain;
this.options.conference_service_name += this.options.domain;
this.pendingPromises = { connectionState: $q.defer(), disconnect: $q.defer() };
this.conn = new Strophe.Connection(credentials.boshUrl);
this.conn.connect(JabberService.generateFullJID('User', credentials.JID) + "/" + idService.getRandomId(), credentials.password, JabberService.callbacks.connectionState.bind(this));
/*Redefinition of core methods*/
this.conn._sendIQ = this.conn.sendIQ;
this.conn.sendIQ = this.sendIQDefered.bind(this);
this.conn.getUniqueId = idService.getRandomId;
this.conn.auto_reconnect = true;
this.reconnectAttempts = 0;
this.maxReconnects = 5;
this.reconnectTimeout = 1000;
this.chatConnReconnectTimeOut = 100;
this.userSessions = {};
// Debug
// this.conn.rawInput = function (data) {console.log('INBOUND: ', data)};
// this.conn.rawOutput = function (data) { console.log('SEND: ' + data); };
Strophe.log = function (lvl, msg) {
if ([Strophe.LogLevel.ERROR, Strophe.LogLevel.FATAL].indexOf(lvl) >= 0) {
$log.log("STROPHE LOG: " + msg);
}
};
JabberService.activeConnection = this;
this.beforeUnload = function (e) {
this.conn.auto_reconnect = false;
this.conn.options.sync = true;
this.conn.flush();
this.conn.disconnect('logout');
};
window.onbeforeunload = this.beforeUnload.bind(this);
// window.onbeforeunload = this.detachSession.bind(this);
};
JabberService.Connection.prototype = {
detachSession: function () {
this.conn.pause();
if (sessionStorage) {
var chatSession = {
sid: this.conn.sid || this.conn._proto.sid,
rid: this.conn.rid || this.conn._proto.rid,
jid: this.conn.jid
};
sessionStorage['chatSession'] = JSON.stringify(chatSession);
}
},
reconnect: function () {
if (this.reconnectAttempts >= this.maxReconnects && !this.reconnectInterval) {
this.reconnectInterval = $interval(this.reconnectTimeout, this.reconnect());
return true;
}
this.conn.lastReconnect = new Date().toISOString();
if (!this.reconnecting) {
this.reconnecting = true;
this.conn.connect(this.conn.jid, this.conn.pass, this.conn.connect_callback, this.conn.wait, this.conn.hold, this.conn.route);
}
this.reconnectAttempts++;
},
//TODO: develop a overriding function for Strophe core method send, which will be checking args for specific value and will be creating deferred object
sendIQDefered: function () {
var uuid = idService.getRandomId(), args = Array.prototype.slice.call(arguments, 0), $iq = args[0];
if (typeof ($iq.tree) === "function") {
$iq = $iq.tree();
}
$iq.setAttribute("id", uuid);
if (!args[1]) {
args[1] = JabberService.callbacks.requestSuccess.bind(this);
}
if (!args[2]) {
args[2] = JabberService.callbacks.requestError.bind(this);
}
// console.log("SENDING STANZA IQ,",Strophe.serialize($iq))
this.conn._sendIQ.apply(this.conn, args);
this.pendingPromises[uuid] = $q.defer();
return this.pendingPromises[uuid].promise;
},
setUserPresence: function (presence) {
var pres = $pres(); //online case - sending empty presence stanza
switch (presence.toLowerCase()) {
case EntityVO.CHAT_STATUS_AWAY:
pres.c('show').t(EntityVO.CHAT_STATUS_AWAY)
.up().c('status').t(EntityVO.CHAT_STATUS_AWAY);
break;
case EntityVO.CHAT_STATUS_OFFLINE:
pres = $pres({
xmlns: Strophe.NS.CLIENT,
type: 'unavailable'
}).c('status').t(EntityVO.CHAT_STATUS_OFFLINE);
break;
default:
pres.c('status').t(EntityVO.CHAT_STATUS_ONLINE);
}
this.conn.send(pres);
},
getUserRoster: function (checkRooms) {
var iq = $iq({ type: 'get' }).c('query', { xmlns: Strophe.NS['ROSTER'] }), self = this, joinActiveRooms = checkRooms;
return this.sendIQDefered(iq, JabberService.callbacks.requestSuccess, JabberService.callbacks.requestError)
.then(function (resp) {
if (!(resp && resp.queryResponse))
return;
joinActiveRooms ? self.processRoomsInRoster(resp.queryResponse.data) : angular.noop();
return resp.queryResponse;
});
},
addToRoster: function (jid) {
var self = this, iq = $iq({ type: 'set' }).c('query', { xmlns: Strophe.NS['ROSTER'] })
.c('item', { jid: jid, name: jid.split("@")[0] })
.c('group', {}, 'conversations');
// console.log("ADDING ROOM TO ROSTER: ", Strophe.serialize(iq));
this.sendIQDefered(iq, JabberService.callbacks.requestSuccess, JabberService.callbacks.requestError)
.then(function () {
var pres = $pres({ to: jid, type: 'subscribe' });
self.conn.send(pres);
});
},
removeRoosterItemByJID: function (jid) {
var iq = $iq({ type: "set" })
.c("query", { xmlns: Strophe.NS.ROSTER })
.c("item", { jid: jid, subscription: "remove" });
// console.log("REMOVING ROOM FROM ROSTER: ", Strophe.serialize(iq));
return this.sendIQDefered(iq, JabberService.callbacks.requestSuccess, JabberService.callbacks.requestError);
},
processRoomsInRoster: function (roster) {
if (!roster)
return;
var self = this, activeRooms = _.filter([].concat(roster), { group: 'conversations' });
activeRooms.forEach(function (roomInfo) {
var jid = roomInfo._jid;
jid && self.conn['disco'].info(jid, null, JabberService.callbacks.requestSuccess, JabberService.callbacks.requestError.bind(self))
.then(function (roomInfo) {
// console.log("Room discovery info",roomInfo);
var roomAlreadyExists = (!!self.conn['muc'].rooms[jid]), history_attr;
if (self.conn.lastReconnect) {
history_attr = { since: self.conn.lastReconnect };
}
self.joinChat(jid, history_attr).then(function (room) {
!roomAlreadyExists && self.options.userCallbacks.roomAutoJoin(room);
});
})
.catch(function (error) {
// console.log("Error while discovering room", error);
self.removeRoosterItemByJID(jid);
});
});
},
handleSubscriptionRequest: function (xml, from) {
var pres = $pres({ to: from.split("/")[0], from: this.conn.authzid, type: 'subscribed' });
return this.conn.send(pres);
},
checkPresence: function (payload) {
var isUsersList = (payload instanceof Array) ? true : false, reqName = isUsersList ? 'bulkPresenceRequest' : 'presenceRequest', request = isUsersList ? JSON.stringify({ jids: payload }) : JSON.stringify({ jid: payload });
var iq = $iq({ type: 'get' })
.c('smart-it-iq', { xmlns: Strophe.NS['SMARTITIQ'], name: reqName }, request);
return this.sendIQDefered(iq, JabberService.callbacks.requestSuccess, JabberService.callbacks.requestError)
.then(function (resp) {
var data = resp.queryResponse.data;
return JSON.parse(data || "{}");
});
},
createChatRoom: function (invitee) {
var self = this, roomName = JabberService.generateFullJID('ChatRoom'), nickName = userModel.userFullData.fullName.replace(/\s/g, "_") || this.conn.authcid.split("_")[0] + "_" + this.options.resource, inviteId = invitee;
var mucRoom = this.conn.muc.createRoom(roomName, nickName);
this.conn.flush();
var roomConfigIQ = this.generateRoomConfigStanza(mucRoom.name, this.options.chatroom_default_config);
return this.sendIQDefered(roomConfigIQ, JabberService.callbacks.requestSuccess, JabberService.callbacks.requestError)
.then(function () {
self.notifyAllResources({ type: 'new_room', jid: mucRoom.name });
if (inviteId) {
mucRoom.directInvite(JabberService.generateFullJID('User', inviteId));
self.conn.flush();
}
var participants = _.map(mucRoom.roster, 'jid');
self.sendArchiveMessage(mucRoom.name, self.conn.jid, participants);
self.addToRoster(mucRoom.name);
return mucRoom;
});
},
generateRoomConfigStanza: function (roomJid, configFields) {
var iq;
iq = $iq({ to: roomJid, type: "set" }).c("query", { xmlns: Strophe.NS.MUC_OWNER });
iq.c("x", { xmlns: "jabber:x:data", type: "submit" });
iq.c('field', { 'var': 'FORM_TYPE' }).c('value').t('http://jabber.org/protocol/muc#roomconfig').up().up();
_.each(configFields, function (value, key) {
iq.c('field', { 'var': 'muc#roomconfig_' + key }).c('value').t("" + value).up().up();
});
return iq.tree();
},
notifyAllResources: function (notification) {
if (notification.type == 'new_room') {
var msg = $msg({ to: this.conn.authzid, type: 'headline' })
.c('body').t(notification.type).up()
.c('thread', { parent: notification.jid });
this.conn.send(msg);
}
},
sendArchiveMessage: function (roomId, inviterJID, inviteesJID) {
var inviteesList = (inviteesJID instanceof Array) ? inviteesJID : [inviteesJID], request = {
chatRoomId: roomId,
notification: 'smart-it-start:' + JSON.stringify({ inviterJid: inviterJID, inviteesJids: inviteesList })
}, iq = $iq({ type: 'get' })
.c('smart-it-iq', { xmlns: Strophe.NS['SMARTITIQ'], name: 'chatRoomNotification' }, JSON.stringify(request));
this.sendIQDefered(iq, JabberService.callbacks.requestSuccess, JabberService.callbacks.requestError)
.then(function (resp) {
var data = resp.queryResponse.data;
return JSON.parse(data || "{}");
});
},
inviteUserToChatRoom: function (user, room) {
room.directInvite(JabberService.generateFullJID('User', user.jid));
},
joinChat: function (roomName, history_attr) {
var uuid = idService.getRandomId(), nickName = userModel.userFullData.fullName.replace(/\s/g, "_") || this.conn.authcid.split("_")[0] + "_" + this.options.resource;
this.pendingPromises[uuid] = $q.defer();
this.conn['muc'].join(roomName, nickName, null, null, null, null, (history_attr || null), uuid);
return this.pendingPromises[uuid].promise;
},
leaveChatRoom: function (room, skipStatusNode) {
var pres = $pres({ to: room.name + "/" + room.nick, from: Strophe.getBareJidFromJid(this.conn.jid), type: 'unavailable' }).tree();
pres.removeAttribute('xmlns');
// console.log("LEAVE ROOM PRESENCE: ",pres)
this.conn.send(pres);
},
destroyChatRoom: function (room) {
var iq = $iq({ to: room.name, type: 'set' }).c("query", { xmlns: Strophe.NS['MUC_OWNER'] })
.c('destroy').c("reason", "Owner request");
return this.sendIQDefered(iq, JabberService.callbacks.requestSuccess, JabberService.callbacks.requestError)
.then(function (response) {
})
.catch(function (err) {
// console.log("Error while deleting a room", err);
});
},
getUserProfileByJID: function (JIDs) {
if (!JIDs)
return $q.when(1);
return resource.getSocialProfileByJID({ jids: JSON.stringify(JIDs) }).$promise.then(function (response) {
if (response && response.items) {
return response.items;
}
});
},
assignChatRoom: function (room, parent) {
var roomName = room.name.split("@")[0];
var request = {
chatRoom: roomName,
objectType: parent.type,
objectId: parent.id,
classId: parent.additionalInformation ? parent.additionalInformation.classId : parent.classId
};
return resource.assignChatRoom(request, null).$promise.then(function (error) {
return room;
});
},
getRoomAssignments: function (room) {
var roomId = Strophe.getNodeFromJid(room.name);
return resource.getRoomAssignments({ jid: roomId }).$promise;
},
removeChatAssignment: function (room) {
var roomId = Strophe.getNodeFromJid(room.name);
return resource.removeRoomAssignment({ jid: roomId }).$promise;
},
saveChatLogToTicketWorknote: function (room, ticketId, ticketType) {
var roomId = Strophe.getNodeFromJid(room.name);
return resource.saveChatLogToTicketWorknote({ jid: roomId }, null).$promise;
// return resource.saveChatLogToTicketWorknote({roomJid: roomId,objectId: ticketId, objectType: ticketType}, null).$promise;
},
requestConversationsHistoryForCurrentUser: function (params) {
return resource.requestConversationsHistoryForCurrentUser(params).$promise;
},
getArchivedConversationById: function (convId) {
var payload = { conversationId: convId };
var iq = $iq({ type: 'get' })
.c('smart-it-iq', { xmlns: Strophe.NS['SMARTITIQ'], name: 'archiveMessagesRequest' }, JSON.stringify(payload));
return this.sendIQDefered(iq)
.then(function (resp) {
var data = resp.queryResponse.data;
return data;
});
},
getTicketDetailsBulk: function (idList) {
var payload = { ids: idList };
return resource.getTicketsBulk(payload).$promise
.then(function (ticketList) {
return _.groupBy(ticketList, 'id');
});
},
resendLostStanzas: function () {
this.conn.cm.onDequeueElement = this.resolveResendPromise.bind(this);
this.conn.cm.resendStanzas(this.resendItems);
},
resolveResendPromise: function (respXML) {
var itemId = respXML.getAttribute('id'), promise = this.pendingPromises[itemId];
if (promise) {
JabberService.callbacks.requestSuccess.call(this, respXML);
}
}
};
return JabberService;
}]);
})();