Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function ChatroomsModule(siberian, io) {
- var _ = require('lodash');
- var Base64 = require('js-base64').Base64;
- var Q = require('q');
- var escapeStringRegexp = require('escape-string-regexp');
- var globals = {};
- var emojis = _.fromPairs(_.map(require('./emoji.json'), function (emoji, code) {
- return [escapeStringRegexp(emoji), ':' + code + ':'];
- }));
- var functions = {
- replaceEmojisWithCodes: function (message) {
- var localMessage = message;
- if (emojis.length) {
- for (var emoji in emojis) {
- localMessage = localMessage.replace(new RegExp(emoji, 'g'), emojis[emoji]);
- }
- }
- return localMessage;
- },
- getFriendship: function (customerId, buddyId) {
- var deferred = Q.defer();
- var result = {
- friend: false,
- blocked: false,
- requested: false,
- pending_accept: false,
- itsyou: false
- };
- var friendship = null;
- var inverse = null;
- if (parseInt(customerId, 10) === parseInt(buddyId, 10)) {
- result.itsyou = true;
- deferred.resolve(result);
- } else {
- result.itsyou = false;
- siberian.application.db.query(
- "SELECT * FROM chatroom_friend WHERE customer_id=? AND buddy_id=?",
- [customerId, buddyId],
- function (err, data) {
- if (err) {
- console.error(err);
- }
- if (data.length > 0) {
- friendship = data[0];
- }
- siberian.application.db.query(
- "SELECT * FROM chatroom_friend WHERE customer_id=? AND buddy_id=?",
- [buddyId, customerId],
- function (cbErr, cbData) {
- if (cbErr) {
- console.error(cbErr);
- }
- if (cbData.length > 0) {
- inverse = cbData[0];
- }
- result.friend = (_.isObject(friendship) && _.isObject(inverse) &&
- !parseInt(friendship.is_blocked, 10) &&
- !parseInt(friendship.is_request, 10) &&
- !parseInt(inverse.is_blocked, 10) &&
- !parseInt(inverse.is_request, 10));
- result.blocked = _.isObject(friendship) && parseInt(friendship.is_blocked, 10) === 1;
- result.requested = _.isObject(friendship) && parseInt(friendship.is_request, 10) === 1;
- result.pending_accept = _.isObject(inverse) && parseInt(inverse.is_request, 10) === 1;
- deferred.resolve(result);
- }
- );
- }
- );
- }
- return deferred.promise;
- },
- getUsersToNotify: function (senderId, receiverId, privateChat) {
- var q = Q.defer(),
- params = [senderId],
- query = "SELECT c.customer_id, cc.chatroom_customer_id, cco.chatroom_customer_options_id, c.nickname, c.customer_id, cco.is_subscribed, cco.is_subscribed_to_all FROM customer as c INNER JOIN chatroom_customer AS cc ON cc.customer_id=c.customer_id INNER JOIN chatroom_customer_options AS cco ON cco.chatroom_customer_id=cc.chatroom_customer_id WHERE (is_subscribed = 1 OR is_subscribed_to_all = 1) AND cc.is_online <> 1 AND c.customer_id <> ?";
- if (privateChat) {
- query += " AND c.customer_id = ? AND cco.recipient_id = ?";
- params.push(receiverId);
- params.push(senderId);
- } else {
- query += " AND cco.chatroom_id = ?";
- params.push(receiverId);
- }
- siberian.application.db.query(
- query,
- params,
- function (err, data) {
- if (err) {
- return q.reject(err);
- }
- if (_.isArray(data) && data.length) {
- return q.resolve(data);
- }
- return q.resolve([]); // No results
- }
- );
- return q.promise;
- },
- getUser: function (data) {
- if (_.isObject (data)) {
- if (_.isString(data.sessionID) && data.sessionID.length > 0) {
- return siberian.customers
- .fromSessionID(data.sessionID, data.appID).then(
- function (user) {
- if (user) {
- var deferred = Q.defer();
- siberian.application.db.query(
- "SELECT c.*, cc.chatroom_customer_id, cc.is_online FROM customer AS c LEFT JOIN chatroom_customer AS cc ON c.customer_id=cc.customer_id WHERE c.customer_id=?",
- [user.customer_id],
- function (cbErr, cbData) {
- if (cbErr) {
- return deferred.reject(cbErr);
- }
- if (cbData.length > 0) {
- deferred.resolve(_.merge({}, user, cbData[0]));
- }
- }
- );
- return deferred.promise;
- }
- return Q.reject(user);
- }
- );
- }
- } else if (_.isNumber(+data)) {
- var deferred = Q.defer();
- siberian.application.db.query(
- "SELECT c.*, cc.chatroom_customer_id, cc.is_online, cc.last_push, cc.push_sent FROM customer AS c LEFT JOIN chatroom_customer AS cc ON c.customer_id=cc.customer_id WHERE c.customer_id=?",
- [data],
- function (cbErr, cbData) {
- if (cbErr) {
- return deferred.reject(cbErr);
- }
- if (cbData.length > 0) {
- deferred.resolve(cbData[0]);
- }
- }
- );
- return deferred.promise;
- }
- return Q.reject(false);
- },
- setUserOnline: function (localConnection, data) {
- return functions.getUser(data)
- .then(function (user) {
- localConnection.socketUser = user;
- localConnection.socket.join('notify/' + (+user.customer_id));
- return Q.Promise(function (res, rej) {
- var sql = "UPDATE chatroom_customer SET is_online = ?, updated_at = ?, push_sent = ?, last_push = ? WHERE customer_id=?";
- var params = [1, new Date(), 0, "2007-01-08 00:00:00", user.customer_id];
- if (user.chatroom_customer_id === null) {
- sql = "INSERT INTO chatroom_customer SET is_online = ?, updated_at = ?, push_sent = ?, last_push = ?, customer_id=?, created_at = ?";
- params.push(new Date());
- }
- var query = siberian.application.db.query(
- sql,
- params,
- function (err, result) {
- if (err) {
- rej(err);
- }
- if (user.chatroom_customer_id === null) {
- user.chatroom_customer_id = result.insertId;
- }
- globals.chatio.to('customer_status/' + user.customer_id)
- .emit('customer_status_update', {
- id: user.customer_id,
- nickname: user.nickname,
- online: true
- });
- globals.connectedUsers[user.customer_id] = user;
- res(user);
- }
- );
- });
- });
- },
- setUserOffline: function (localConnection) {
- if (_.isObject(localConnection.socketUser)) {
- return Q.Promise(function (res, rej) {
- siberian.application.db.query(
- "UPDATE chatroom_customer SET is_online = ?, updated_at = ? WHERE customer_id=?",
- [0, new Date(), localConnection.socketUser.customer_id],
- function (err, result) {
- if (err) {
- rej(err);
- }
- globals.chatio.to('customer_status/' + localConnection.socketUser.customer_id).emit('customer_status_update', {
- id: localConnection.socketUser.customer_id,
- nickname: localConnection.socketUser.nickname,
- online: false
- });
- globals.connectedUsers[localConnection.socketUser.customer_id] = undefined;
- delete globals.connectedUsers[localConnection.socketUser.customer_id];
- _.forEach(globals.UsersByRoom, function (users, room) {
- globals.UsersByRoom[room] = _.reject(users, {
- customer_id: localConnection.socketUser
- });
- });
- res();
- }
- );
- }).then(function () {
- localConnection.socketUser = null;
- return Q.resolve();
- });
- }
- return Q.resolve();
- },
- roomDoorman: function (localConnection, join, data) {
- if (!_.isString(data.room) || data.room.length < 1) {
- return;
- }
- functions.setUserOnline(localConnection, data)
- .then(function (user) {
- var room = data.room;
- var isPrivateMessage = room.match(/^privroom:/);
- var roomId = room.match(/^(?:(?:priv)?room):(.*)$/)[1];
- var channel = (isPrivateMessage ? 'private' : 'chatroom') + '/' + roomId;
- if (join) {
- localConnection.socket.join(channel);
- if (!_.isArray(globals.UsersByRoom[room])) {
- globals.UsersByRoom[room] = [];
- }
- if (!_.includes(globals.UsersByRoom[room], user.customer_id)) {
- globals.UsersByRoom[room].push(user.customer_id);
- }
- functions.sendRoomUserlist(room);
- } else {
- localConnection.socket.leave(channel);
- if (!_.isArray(globals.UsersByRoom[room])) {
- globals.UsersByRoom[room] = [];
- }
- if (_.includes(globals.UsersByRoom[room], user.customer_id)) {
- globals.UsersByRoom[room] = _.reject(globals.UsersByRoom[room], function (id) {
- return parseInt(id, 10) === parseInt(user.customer_id, 10);
- });
- }
- var recipientId = +data.recipient_id;
- var chatroomId = +data.chatroom_id;
- if (recipientId || chatroomId) {
- siberian.application.db.query(
- "DELETE FROM chatroom_customer_options WHERE chatroom_customer_id = (SELECT chatroom_customer_id FROM chatroom_customer WHERE customer_id = ?) AND "+
- (isPrivateMessage ? "recipient_id = ?" : "chatroom_id = ?"),
- [user.customer_id, (isPrivateMessage ? recipientId : chatroomId)],
- function (err) {
- if (err) {
- console.error(err);
- }
- }
- );
- }
- }
- });
- },
- sendRoomUserlist: function (room) {
- var isPrivateMessage = room.match(/^privroom:/);
- var roomId = room.match(/^(?:(?:priv)?room):(.*)$/)[1];
- var channel = (isPrivateMessage ? 'private' : 'chatroom') + '/' + roomId;
- if (_.isArray(globals.UsersByRoom[room])) {
- var users = _(_.map(globals.UsersByRoom[room], function (userId) {
- return _.pick(globals.connectedUsers[userId], ['customer_id', 'nickname']);
- })).compact().uniq().reject(function (o) {
- return !_.isObject(o) || !_.isNumber(o.customer_id) || o.customer_id < 1;
- }).value();
- globals.chatio.to(channel).emit('userlist', {
- room: room,
- users: users
- });
- }
- },
- storeAndRelayMessage: function (localConnection, isPrivateMessage, data) {
- var receiver = isPrivateMessage ? 'recipient_id' : 'chatroom_id';
- var roomId = isPrivateMessage ?
- ([data.receiver_id, localConnection.socketUser.customer_id].sort().join(':')) :
- data.receiver_id;
- var channel = (isPrivateMessage ? 'private' : 'chatroom') + '/' + roomId;
- // Just in case of a disconnect!
- localConnection.socket.join(channel);
- var message = _.isString(data.message) && data.message.length > 0 ?
- functions.replaceEmojisWithCodes(data.message) : null;
- var image = _.isString(data.image) && data.image.length > 0 ? data.image : null;
- var date = (new Date()).toISOString();
- var messageRow = {
- sender_id: localConnection.socketUser.customer_id,
- sender_nickname: localConnection.socketUser.nickname,
- message: (message && Base64.encode(message)) || null,
- image: image || null,
- created_at: date,
- updated_at: date
- };
- messageRow[receiver] = data.receiver_id;
- siberian.application.db.query(
- "INSERT INTO chatroom_message SET ?",
- messageRow,
- function (err, result) {
- if (err) {
- return console.error(err);
- }
- messageRow.message = data.message; // reuse message with emojis, not base64
- messageRow.id = result.insertId;
- var fullRoomId = (isPrivateMessage ? 'privroom' : 'room') + ':' + roomId;
- var pushMessage = message !== null ? messageRow.message : image !== null ? ' ' : null;
- if (pushMessage !== null) {
- var push_row = _.extend({}, messageRow, {
- app_id: data.appID, // we add app ID
- value_id: data.valueID,
- message: pushMessage,
- sender_avatar: data.sender_avatar
- });
- // Do we have individual push ?
- siberian.application.db.query(
- "SELECT 1 FROM push_customer_message LIMIT 1",
- function (cbErr, cbResult) {
- if (!cbErr) {
- functions.handlePushNotification(push_row);
- }
- }
- );
- }
- var msg = {
- id: messageRow.id,
- senderID: messageRow.sender_id,
- nickname: messageRow.sender_nickname,
- message: messageRow.message,
- image: messageRow.image,
- date: messageRow.created_at,
- room: fullRoomId
- };
- msg[receiver] = messageRow[receiver];
- return globals.chatio.to(channel).emit((isPrivateMessage ? 'privmsg' : 'msg'), msg);
- }
- );
- },
- notify: function (userCustomerId, messageRow) {
- functions.getUser(userCustomerId)
- .then(function (user) {
- if (_.isObject(user) && user.customer_id > 0) {
- if (((Date.parse(user.last_push) || 0)+15*60*1000) < (+new Date())) {
- user.push_sent = 0;
- }
- if (user.push_sent < 5) {
- user.push_sent = user.push_sent + 1;
- siberian.application.db.query(
- "INSERT INTO push_messages SET ?",
- {
- app_id: messageRow.app_id,
- type_id: 1,
- title: (new Buffer(messageRow.sender_nickname).toString('base64')),
- text: (new Buffer(messageRow.message).toString('base64')),
- base64: 1,
- cover: messageRow.sender_avatar,
- send_to_all: 0,
- send_to_specific_customer: 1,
- action_value: messageRow.value_id,
- value_id: messageRow.value_id,
- created_at: new Date(),
- updated_at: new Date()
- },
- function (err, result) {
- if (!err && _.isObject(result) && result.insertId > 0) {
- siberian.application.db.query(
- "INSERT INTO push_customer_message SET ?",
- {
- message_id: result.insertId,
- customer_id: user.customer_id
- },
- function (cbErr, cbResult) {
- if (!cbErr) {
- siberian.application.db.query(
- "UPDATE chatroom_customer SET push_sent=?,last_push=? WHERE customer_id=?",
- [user.push_sent, new Date(), user.customer_id],
- function () {
- // We actually don't have anything to do after this
- }
- );
- }
- }
- );
- }
- }
- );
- }
- }
- });
- },
- handlePushNotification: function (messageRow) {
- var receiverId = messageRow.recipient_id || messageRow.chatroom_id;
- var privateChat = +messageRow.recipient_id > 0;
- functions.getUsersToNotify(messageRow.sender_id, receiverId, privateChat)
- .then(function (users) {
- if (_.isArray(users)) {
- _.forEach(users, function (user) {
- functions.getFriendship(user.customer_id, messageRow.sender_id)
- .then(function (result) {
- if (!result.blocked) {
- if (user.is_subscribed_to_all) {
- functions.notify(user.customer_id, messageRow);
- } else if (user.is_subscribed) {
- var mentioned = new RegExp('\\b@?'+user.nickname+'\\b', 'gi');
- if (messageRow.message.match(mentioned)) {
- functions.notify(user.customer_id, messageRow);
- }
- }
- }
- });
- });
- }
- });
- },
- processMessage: function (localConnection, isPrivateMessage, data) {
- functions.setUserOnline(localConnection, data)
- .then(function (user) {
- localConnection.socketUser = user;
- if (!_.isObject(data)) {
- return;
- }
- if (!_.isNumber(+data.receiver_id) || +data.receiver_id < 1) {
- return;
- }
- if (isPrivateMessage) {
- functions.getFriendship(user.customer_id, data.receiver_id)
- .then(function (result) {
- if (result.friend) {
- functions.storeAndRelayMessage(localConnection, isPrivateMessage, data);
- }
- });
- } else {
- functions.storeAndRelayMessage(localConnection, isPrivateMessage, data);
- }
- });
- }
- };
- this.run = function () {
- globals.connectedUsers = {};
- globals.UsersByRoom = {};
- globals.chatio = io.of('/chatrooms');
- globals.chatio.on('connection', function (socket) {
- var localConnection = {
- socket: socket,
- socketUser: null
- };
- localConnection.socket.on('online', function (data) {
- functions.setUserOnline(localConnection, data);
- });
- localConnection.socket.on('join_room', functions.roomDoorman.bind(this, localConnection, true));
- localConnection.socket.on('leave_room', functions.roomDoorman.bind(this, localConnection, false));
- localConnection.socket.on('watch_customer', function (data) {
- functions.setUserOnline(localConnection, data);
- if (!_.isNumber(+data.customer_id) || +data.customer_id < 1) {
- return;
- }
- var channel = 'customer_status/' + data.customer_id;
- localConnection.socket.join(channel);
- });
- localConnection.socket.on('unwatch_customer', function (data) {
- functions.setUserOnline(localConnection, data);
- if (!_.isNumber(+data.customer_id) || +data.customer_id < 1) {
- return;
- }
- var channel = 'customer_status/' + data.customer_id;
- localConnection.socket.leave(channel);
- });
- localConnection.socket.on('sendmsg', functions.processMessage.bind(this, localConnection, false));
- localConnection.socket.on('sendprivmsg', functions.processMessage.bind(this, localConnection, true));
- localConnection.socket.on('buddy_list_update', function (data) {
- if (!_.isObject(data)) {
- return;
- }
- if (!_.isNumber(+data.customer_id) || +data.customer_id < 1) {
- return;
- }
- functions.setUserOnline(data)
- .then(function (user) {
- globals.chatio
- .to('notify/' + (+data.customer_id))
- .to('notify/' + (+user.customer_id))
- .emit('buddy_list_update', null);
- });
- });
- localConnection.socket.on('disconnect', functions.setUserOffline.bind(this, localConnection));
- });
- };
- }
- module.exports = function (siberian, io) {
- return new ChatroomsModule(siberian, io);
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement