const Message = require('./message.js').Message ,MeMessage = require('./message.js').MeMessage ,NoticeMessage = require('./message.js').NoticeMessage ,RoomHistory = require('./message.js').RoomHistory; /** * @constructor * @extends {RoomHistory} * @param {Slack} ctx * @param {string} serviceId * @param {Room|string} room or roomId * @param {string} idPrefix * @param {number} keepMessages number of messages to keep in memory * @param {number} maxAge number of messages to keep in memory * @param {Array=} evts * @param {number=} now **/ function SlackHistory(ctx, remoteId, room, idPrefix, keepMessages, maxAge, evts, now) { RoomHistory.call(this, room, keepMessages, maxAge, evts, now); /** @const @type {string} */ this.remoteId = remoteId; /** @const @type {string} */ this.idPrefix = idPrefix; /** @const @type {Slack} */ this.ctx = ctx; } SlackHistory.prototype = Object.create(RoomHistory.prototype); SlackHistory.prototype.constructor = SlackHistory; SlackHistory.prototype.prepareMessage = function(ev, targetId) { if (ev) { if (ev["edited"] && ev["edited"]["ts"]) ev["edited"] = Math.round(parseFloat(ev["edited"]["ts"]) * 1000); if (ev["ts"]) ev["ts"] = parseFloat(ev["ts"]) * 1000; if (!ev["id"]) ev["id"] = targetId; if (ev["attachments"] && ev["attachments"].length) ev["attachments"].forEach((a) => { a.ts *= 1000; }); } return ev; } SlackHistory.prototype.messageFactory = function(ev, ts) { if (!ev["user"]) { if (ev["bot_id"]) ev["user"] = ev["bot_id"]; if (ev["comment"] && ev["comment"]["user"]) ev["user"] = ev["comment"]["user"]; } ev["user"] = this.idPrefix +ev["user"]; if (ev["reactions"]) { ev["reactions"].forEach((r) => { for (var i =0, nbUsers =r["users"].length; i < nbUsers; i++) r["users"][i] = this.idPrefix +r["users"][i]; }); } if (ev["is_ephemeral"] === true) return new NoticeMessage(ev, ts); if (ev["subtype"] === "me_message") return new MeMessage(ev, ts); return new Message(ev, ts); }; /** * @param {Object} ev * @param {number} t * @return {number} ts **/ SlackHistory.prototype.push = function(ev, t) { var msg; if (!ev["type"] || ev["type"] === "message") { var exists = false ,targetId = ev["ts"] ,modifArg = ev; if (ev["subtype"] === "message_changed") { if (ev["previous_message"]) targetId = ev["previous_message"]["ts"]; else if (ev["message"]) targetId = ev["message"]["ts"]; modifArg = ev["message"] } else if (ev["subtype"] === "message_deleted" && (ev["previous_message"] || ev["deleted_ts"])) { if (ev["previous_message"]) targetId = ev["previous_message"]["ts"]; else targetId = ev["deleted_ts"]; modifArg = null; } else if (ev["subtype"] === "star_changed") { modifArg = ev["message"]; targetId = ev["message"]["ts"]; } var msg = this.getMessageById(targetId); if (msg) { msg.update(this.prepareMessage(modifArg), t); exists = true; } else { this.prepareMessage(ev["previous_message"], targetId); this.prepareMessage(ev["message"], targetId); var msgSource = ev["previous_message"] || ev["message"]; if (msgSource) { msg = this.messageFactory(msgSource, t); msg.update(modifArg, t); } else { msg = this.messageFactory(this.prepareMessage(ev, targetId), t); } this.messages.push(msg); } } else if (ev["type"] === "reaction_added") { msg = this.addReaction(ev["reaction"], this.idPrefix +ev["user"], ev["item"]["ts"], t); if (!msg) { let self = this; this.ctx.fetchHistory(this.ctx.getChatContext().channels[this.id], (msg) => { if (msg && msg.length) { msg[0].version = t; self.messages.push(msg[0]); self.resort(); self.v = Math.max(self.v, t); self.ctx.getChatContext().liveV = Math.max(self.ctx.getChatContext().liveV, t); } }, 1, ev["item"]["ts"]); } } else if (ev["type"] === "reaction_removed") { let self = this; msg = this.removeReaction(ev["reaction"], this.idPrefix +ev["user"], ev["item"]["ts"], t); if (!msg) { this.ctx.fetchHistory(this.ctx.getChatContext().channels[this.id], (msg) => { if (msg && msg.length) { msg[0].version = t; self.messages.push(msg[0]); self.resort(); self.v = Math.max(self.v, t); self.ctx.getChatContext().liveV = Math.max(self.ctx.getChatContext().liveV, t); } }, 1, ev["item"]["ts"]); } } else if (ev["type"] === "star_added" || ev["type"] === "star_removed") { ev["item"]["subtype"] = "star_changed"; return this.push(ev["item"], t); } else { return 0; } this.cleanOld(t); return msg ? msg.ts : 0; }; SlackHistory.prototype.resort = function() { this.messages.sort(function(a, b) { return a.ts -b.ts; }); }; module.exports.SlackHistory = SlackHistory;