Mailspring/packages/local-sync/src/new-message-processor/extract-contacts.js
Juan Tejada a185a8a5fe [local-sync] Fix file/contact creation
We were getting sql unique constraint violation errors for ids because
we were attempting to create objects with the same id within the same
transaction.

This commit ensures that only attempt to write a contact with the same
id once, and that we check for all exsiting contacts before hand.

For file, we ensure that we don't attempt to write 2 files with the same
id more than once
2016-12-07 14:48:57 -08:00

60 lines
1.6 KiB
JavaScript

function isContactMeaningful(contact) {
// some suggestions: http://stackoverflow.com/questions/6317714/apache-camel-mail-to-identify-auto-generated-messages
const regex = new RegExp(/^(noreply|no-reply|donotreply|mailer|support|webmaster|news(letter)?@)/ig)
if (!contact.email) {
return false;
}
if (regex.test(contact.email) || contact.email.length > 60) {
return false
}
return true
}
async function extractContacts({db, message}) {
const {Contact} = db
let allContacts = [];
['to', 'from', 'bcc', 'cc'].forEach((field) => {
allContacts = allContacts.concat(message[field])
})
const meaningfulContacts = allContacts.filter(c => isContactMeaningful(c));
const contactsDataById = new Map()
meaningfulContacts.forEach(c => {
const id = Contact.hash(c)
const cdata = {
id,
name: c.name,
email: c.email,
accountId: message.accountId,
}
contactsDataById.set(id, cdata)
})
const existingContacts = await Contact.findAll({
where: {
id: Array.from(contactsDataById.keys()),
},
})
await db.sequelize.transaction(async (transaction) => {
const promises = []
for (const c of contactsDataById.values()) {
const existing = existingContacts.find(({id}) => id === c.id)
if (!existing) {
promises.push(Contact.create(c, {transaction}));
} else {
const updateRequired = (c.name !== existing.name);
if (updateRequired) {
promises.push(existing.update(c, {transaction}));
}
}
}
await Promise.all(promises);
})
return message;
}
module.exports = extractContacts