const { createRoom, registerMessageInRoom, createThread, registerMessageInThread, isRoomGroup, findRoomsFromMessage, hasSameMembersAsParent, } = require("../db/saveMessageApp"); const { findRoomByOwner, getAddresseId, getUserIdOfMailbox } = require("../db/mail"); const { nbMembers } = require("./utils/statusUtils"); /** * take object address and join mailbox and host to return mailbox@host */ function createAddress(elt) { return `${elt.mailbox}@${elt.host}`; } async function initiateRoom(envelope, ownerId, messageId, isSeen) { await createRoom(envelope.subject, ownerId, messageId).then(async (roomId) => { // todo register members await registerMessageInRoom(messageId, roomId, isSeen, envelope.date); }); } const roomType = { ROOM: 'room', CHANNEL: 'channel', GROUP: 'group', DM: 'dm', THREAD: 'thread' } class registerMessageInApp { constructor(_messageId, _attrs, _boxId) { this.messageId = _messageId; this.attrs = _attrs; this.envelope = this.attrs.envelope; this.messageID = this.envelope.messageId; this.boxId = _boxId; this.isSeen = this.attrs.flags.includes("\\Seen") ? 1 : 0; this.ownerId; this.userId; } async init() { this.ownerId = await getAddresseId(createAddress(this.envelope.from[0])); // todo use sender or from ? } isDm = () => nbMembers(this.envelope) == 2; async isFromUs() { if (!this.userId) this.userId = (await getUserIdOfMailbox(this.boxId))[0]?.user_id; return this.ownerId == this.userId; } async initiateRoom(owner, roomType) { // todo roomType await createRoom(this.envelope.subject, owner, this.messageId).then(async (roomId) => { // todo register members await registerMessageInRoom(this.messageId, roomId, this.isSeen, this.envelope.date); }); } async createOrRegisterOnExistence(owner, roomType) { await findRoomByOwner(owner).then(async (res) => { if (res.length == 0) { // first message with this sender await initiateRoom(owner, roomType); } else { // not a reply, add to the list of message if this sender await registerMessageInRoom(this.messageId, res[0].room_id, this.isSeen, this.envelope.date); } }); } async createOrRegisterOnMembers(roomId) { const hasSameMembers = await hasSameMembersAsParent(this.messageID, this.envelope.inReplyTo); if (hasSameMembers) { await registerMessageInRoom(this.messageId, roomId, this.isSeen, this.envelope.date); } else { await createThread(this.envelope.subject, this.ownerId, this.messageId, roomId, this.isDm()).then( async (threadId) => { await registerMessageInThread(this.messageId, threadId, this.isSeen); }, ); } } async save() { await this.init(); if (this.envelope.inReplyTo) { this.saveReply(); } else { if (await this.isFromUs()) { if (this.isDm()) { // create or add new message to DM const userTo = await getAddresseId(createAddress(this.envelope.to[0])); await this.createOrRegisterOnExistence(userTo, roomType.DM); } else { // it is not a reply and not a dm // so it is a channel, which can be possibly a group initiateRoom(this.envelope, this.ownerId, this.messageId, this.isSeen); } } else { await this.createOrRegisterOnExistence(this.ownerId, roomType.ROOM); } } } async saveReply() { const messageID = envelope.messageId; await findRoomsFromMessage(messageId).then(async (rooms) => { if (rooms.length == 0) { // no rooms, so is a transfer // todo test if members of transferred message are included } else if (rooms.length === 1) { // only one room so message is only in a room and not in a thread // as a thread is associated to a room await isRoomGroup(rooms[0].room_id).then(async (isGroup) => { if (isGroup) { this.createOrRegisterOnMembers(rooms[0].room_id); } else { // reply from channel // todo // if (sender == owner) { // correction from the original sender // // leave in the same channel // } } }); } else if (rooms.length > 1) { // get the lowest thread (order by room_id) const roomId = rooms[rooms.length - 1].room_id; this.createOrRegisterOnMembers(roomId); } }); } } module.exports = { registerMessageInApp, roomType };