231 lines
8.0 KiB
JavaScript
231 lines
8.0 KiB
JavaScript
const { getAddresseId } = require("../sql/mail");
|
|
const { DEBUG } = require("../utils/debug");
|
|
const { simpleParser } = require("mailparser");
|
|
const moment = require("moment");
|
|
const fs = require("fs");
|
|
const {
|
|
registerMessage,
|
|
registerMailbox_message,
|
|
saveHeader_fields,
|
|
saveAddress_fields,
|
|
registerBodypart,
|
|
saveBodypart,
|
|
saveSource,
|
|
} = require("../sql/saveMessage");
|
|
|
|
const {
|
|
createRoom,
|
|
registerMessageInRoom,
|
|
createThread,
|
|
registerMessageInThread,
|
|
isRoomGroup,
|
|
findSpacesFromMessage,
|
|
hasSameMembersAsParent,
|
|
} = require("../sql/saveMessageApp");
|
|
const { getFieldId, findRoomByOwner } = require("../sql/mail");
|
|
|
|
function saveMessage(attrs, mailboxId, imap) {
|
|
const envelope = attrs.envelope;
|
|
const ts = moment(new Date(envelope.date).getTime()).format(
|
|
"YYYY-MM-DD HH:mm:ss"
|
|
);
|
|
const rfc822size = attrs.size;
|
|
const messageID = envelope.messageId;
|
|
|
|
registerMessage(ts, rfc822size, messageID)
|
|
.then((messageId) => {
|
|
const isSeen = attrs.flags.includes("Seen") ? 1 : 0; // todo verify
|
|
const deleted = attrs.flags.includes("Deleted") ? 1 : 0; // todo verify
|
|
|
|
registerMailbox_message(
|
|
mailboxId,
|
|
attrs.uid,
|
|
messageId,
|
|
attrs.modseq,
|
|
isSeen,
|
|
deleted
|
|
);
|
|
const f = imap.fetch(attrs.uid, { bodies: "" });
|
|
let buffer = "";
|
|
|
|
f.on("message", function (msg, seqno) {
|
|
msg.on("body", function (stream, info) {
|
|
stream.on("data", function (chunk) {
|
|
buffer += chunk.toString("utf8");
|
|
});
|
|
|
|
stream.once("end", () => {
|
|
// save raw data
|
|
saveSource(messageId, buffer);
|
|
|
|
// parse data
|
|
simpleParser(buffer, async (err, parsed) => {
|
|
saveFromParsedData(parsed, messageId);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
f.once("error", function (err) {
|
|
console.log("Fetch error: " + err);
|
|
});
|
|
f.once("end", function () {
|
|
console.log("Done fetching all messages!");
|
|
});
|
|
})
|
|
.catch((err) => {
|
|
DEBUG.log("Unable to register message: " + err);
|
|
});
|
|
}
|
|
|
|
function saveFromParsedData(parsed, messageId) {
|
|
fs.writeFileSync("./test.txt", JSON.stringify(parsed));
|
|
Object.keys(parsed).forEach((key) => {
|
|
if (["from", "to", "cc", "bcc", "reply-to"].includes(key)) {
|
|
// save address field
|
|
getFieldId(key).then((fieldId) => {
|
|
parsed[key].value.forEach((addr, nb) => {
|
|
getAddresseId(addr.address, addr.name).then((addressId) => {
|
|
saveAddress_fields(messageId, fieldId, addressId, nb);
|
|
});
|
|
});
|
|
});
|
|
} else if (["subject", "inReplyTo"].includes(key)) {
|
|
// todo : "references"
|
|
getFieldId(key).then((fieldId) => {
|
|
saveHeader_fields(
|
|
messageId,
|
|
fieldId,
|
|
undefined,
|
|
undefined,
|
|
parsed[key]
|
|
);
|
|
});
|
|
} else if (["html", "text", "textAsHtml"].includes(key)) {
|
|
const hash = "0";
|
|
const size = "0";
|
|
// saveBodypart(size, hash, parsed[key], "").then((bodypartId) => {
|
|
// getFieldId(key).then((fieldId) => {
|
|
// saveHeader_fields(
|
|
// messageId,
|
|
// fieldId,
|
|
// bodypartId,
|
|
// undefined, // todo ?
|
|
// undefined
|
|
// );
|
|
// });
|
|
// });
|
|
} else if (key == "attachments") {
|
|
// todo
|
|
} else if (
|
|
["date", "messageId", "headers", "headerLines"].includes(key)
|
|
) {
|
|
// messageId and date are already saved
|
|
// other field are not improted and can be retrieved in source
|
|
return;
|
|
} else {
|
|
DEBUG.log("doesn't know key: " + key);
|
|
return;
|
|
}
|
|
});
|
|
// todo when transfered
|
|
}
|
|
|
|
function haveSameReceivers() {
|
|
// take cc and to
|
|
}
|
|
|
|
/**
|
|
* take object address and join mailbox and host to return mailbox@host
|
|
*/
|
|
function createAddress(elt) {
|
|
return `${elt.mailbox}@${elt.host}`;
|
|
}
|
|
|
|
function registerMessageInApp(envelope, messageId, isSeen) {
|
|
getAddresseId(createAddress(envelope.sender[0])).then((ownerId) => {
|
|
if (envelope.inReplyTo) {
|
|
registerReplyMessage(envelope, messageId, isSeen);
|
|
} else {
|
|
findRoomByOwner(ownerId).then((res) => {
|
|
if (res.length == 0) {
|
|
createRoom(envelope.subject, ownerId).then((roomId) => {
|
|
registerMessageInRoom(messageId, roomId, isSeen);
|
|
});
|
|
} else {
|
|
registerMessageInRoom(messageId, res[0].room_id, isSeen);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function registerReplyMessage(envelope, messageId, isSeen) {
|
|
const messageID = envelope.messageId;
|
|
findSpacesFromMessage(messageId).then((spaces) => {
|
|
// todo sub thread will not be in index 0 so look in all indexes
|
|
if (spaces.length == 0) {
|
|
// no space, so is a transfer
|
|
// todo test if members of transferred message are included
|
|
} else if (spaces[0].thread_id) {
|
|
registerMessageInThread(messageId, spaces[0].thread_id, isSeen);
|
|
// todo
|
|
// if (hasSameMembersAsParent(messageID, envelope.inReplyTo)) {
|
|
// // register new message in thread
|
|
// // possibly convert to room only if parent is channel
|
|
// } else {
|
|
// // todo create sub thread
|
|
// }
|
|
} else if (spaces[0].room_id) {
|
|
// message in room and not thread
|
|
isRoomGroup(spaces[0].room_id).then((isGroup) => {
|
|
if (isGroup) {
|
|
if (hasSameMembersAsParent(messageID, envelope.inReplyTo)) {
|
|
registerMessageInRoom(
|
|
messageId,
|
|
spaces[0].room_id,
|
|
isSeen
|
|
);
|
|
} else {
|
|
// group and not the same member as the reply
|
|
// some recipient has been removed create a thread
|
|
const isDm = 0; // todo
|
|
createThread(
|
|
space[0].room_id,
|
|
envelope.subject,
|
|
isSeen,
|
|
isDm
|
|
).then((threadId) => {
|
|
registerMessageInThread(
|
|
messageId,
|
|
threadId,
|
|
isSeen
|
|
);
|
|
});
|
|
}
|
|
} else {
|
|
// reply from channel
|
|
// todo
|
|
// if (messageInRoom == 1) { // was new channel transform to group
|
|
// // register new message in group
|
|
// } else if (sender == owner) { // correction from the original sender
|
|
// // leave in the same channel
|
|
// } else { // user response to announcement
|
|
// // create new thread
|
|
// }
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
// `SELECT app_room_messages.room, app_room_messages.thread FROM app_room_messages INNER JOIN messages WHERE messages.messageID = '${envelope.inReplyTo}' AND app_room_messages.message = messages.id`;
|
|
}
|
|
|
|
function keyNormalizer(key) {
|
|
// todo
|
|
return key;
|
|
}
|
|
|
|
module.exports = {
|
|
saveMessage,
|
|
};
|