improve saveMessage (switch to class) and started to test

This commit is contained in:
grimhilt
2023-03-29 21:00:43 +02:00
parent 053213eecb
commit 1a63b3154a
9 changed files with 366 additions and 149 deletions

View File

@@ -9,7 +9,7 @@ const {
} = require("../db/saveMessageApp");
const { findRoomByOwner, getAddresseId, getUserIdOfMailbox } = require("../db/mail");
const { isDmOnEnvelope, nbMembers } = require("./utils/statusUtils");
const { nbMembers } = require("./utils/statusUtils");
/**
* take object address and join mailbox and host to return mailbox@host
@@ -18,105 +18,128 @@ 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 initiateRoom(envelope, ownerId, messageId, isSeen) {
await createRoom(envelope.subject, ownerId, messageId).then(async (roomId) => {
// todo register members
await registerMessageInRoom(messageId, roomId, 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);
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.sender[0])); // todo use sender or from ?
}
isDm = () => nbMembers(this.envelope) == 2;
async isFromUs() {
if (!this.userId) this.userId = (await getUserIdOfMailbox(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 {
// 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);
});
// 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
registerMessageInApp,
roomType
};

View File

@@ -1,7 +1,3 @@
function isDmOnEnvelope(envelope) {
return nbMembers(envelope) === 2;
}
function nbMembers(envelope) {
let nbMembers =
(envelope.bcc?.length ?? 0) +
@@ -18,6 +14,5 @@ function nbMembers(envelope) {
}
module.exports = {
isDmOnEnvelope,
nbMembers,
};