const { createRoom, registerMessageInRoom, createThread, registerMessageInThread, isRoomGroup, findRoomsFromMessage, hasSameMembersAsParent, } = require("../db/saveMessageApp"); const { findRoomByOwner, getAddresseId, getUserIdOfMailbox } = require("../db/mail"); const { isDmOnEnvelope, 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 registerMessageInApp(messageId, attrs, boxId) { const isSeen = attrs.flags.includes("\\Seen") ? 1 : 0; // todo verify const envelope = attrs.envelope; await getAddresseId(createAddress(envelope.sender[0])).then(async (ownerId) => { if (envelope.inReplyTo) { await registerReplyMessage(envelope, messageId, isSeen, ownerId); } else { const userId = (await getUserIdOfMailbox(boxId))[0]?.user_id; if (ownerId == userId) { // send by the user if (nbMembers(envelope) == 2) { // this is a dm console.log(envelope) const userTo = (await getAddresseId(createAddress(envelope.to[0]))); await findRoomByOwner(userTo).then(async (res) => { if (res.length == 0) { // first message of this conv with this sender await createRoom(envelope.subject, userTo, messageId).then(async (roomId) => { await registerMessageInRoom(messageId, roomId, isSeen, envelope.date); }); } else { // not a reply, add to the list of message if this sender await registerMessageInRoom(messageId, res[0].room_id, isSeen, envelope.date); } }); } else { // message coming from user with multiple member is a group await createRoom(envelope.subject, ownerId, messageId).then(async (roomId) => { await registerMessageInRoom(messageId, roomId, isSeen, envelope.date); }); } } else { await findRoomByOwner(ownerId).then(async (res) => { if (res.length == 0) { // first message of this sender if (!envelope.subject) console.error(envelope) await createRoom(envelope.subject, ownerId, messageId).then(async (roomId) => { await registerMessageInRoom(messageId, roomId, isSeen, envelope.date); }); } else { // not a reply, add to the list of message if this sender await registerMessageInRoom(messageId, res[0].room_id, isSeen, envelope.date); } }); } } }); } async function registerReplyMessage(envelope, messageId, isSeen, ownerId) { 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 to begin await isRoomGroup(rooms[0].room_id).then(async (isGroup) => { if (isGroup) { const hasSameMembers = await hasSameMembersAsParent(messageID, envelope.inReplyTo); if (hasSameMembers) { await registerMessageInRoom(messageId, rooms[0].room_id, isSeen, envelope.date); } else { // is a group and has not the same member as the previous message // some recipient has been removed create a thread const isDm = isDmOnEnvelope(envelope); await createThread(envelope.subject, ownerId, messageId, rooms[0].room_id, isDm).then(async (threadId) => { await registerMessageInThread(messageId, threadId, isSeen); }); } } 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 room = rooms[rooms.length-1]; const hasSameMembers = await hasSameMembersAsParent(messageID, envelope.inReplyTo); if (hasSameMembers) { await registerMessageInThread(messageId, room.room_id, isSeen); } else { // has not the same members so it is a derivation of this thread // todo put this in a function and add default message in the reply chain const isDm = isDmOnEnvelope(envelope); await createThread(envelope.subject, ownerId, messageId, room.room_id, isDm).then(async (threadId) => { await registerMessageInThread(messageId, threadId, isSeen); }); } } }); } module.exports = { registerMessageInApp };