Merge pull request #1 from nylas/contacts

Build(contacts): built contact model, added routes and processor
This commit is contained in:
Ben Gotow 2016-07-11 15:22:04 -07:00 committed by GitHub
commit 5085730902
4 changed files with 160 additions and 1 deletions

View file

@ -0,0 +1,83 @@
const Joi = require('joi');
const Serialization = require('../serialization');
module.exports = (server) => {
server.route({
method: 'GET',
path: '/contacts',
config: {
description: 'Returns an array of contacts',
notes: 'Notes go here',
tags: ['contacts'],
validate: {
query: {
name: Joi.string(),
email: Joi.string().email(),
limit: Joi.number().integer().min(1).max(2000).default(100),
offset: Joi.number().integer().min(0).default(0),
},
},
response: {
schema: Joi.array().items(
Serialization.jsonSchema('Contact')
),
},
},
handler: (request, reply) => {
request.getAccountDatabase().then((db) => {
const {Contact} = db;
const query = request.query;
const where = {};
if (query.name) {
where.name = {like: query.name};
}
if (query.email) {
where.email = query.email;
}
Contact.findAll({
where: where,
limit: request.query.limit,
offset: request.query.offset,
}).then((contacts) => {
reply(Serialization.jsonStringify(contacts))
})
})
},
})
server.route({
method: 'GET',
path: '/contacts/{id}',
config: {
description: 'Returns a contact with specified id.',
notes: 'Notes go here',
tags: ['contacts'],
validate: {
params: {
id: Joi.string(),
},
},
response: {
schema: Serialization.jsonSchema('Contact'),
},
},
handler: (request, reply) => {
request.getAccountDatabase().then(({Contact}) => {
const {params: {id}} = request
Contact.findOne({where: {id}}).then((contact) => {
if (!contact) {
return reply.notFound(`Contact ${id} not found`)
}
return reply(Serialization.jsonStringify(contact))
})
.catch((error) => {
console.log('Error fetching contacts: ', error)
reply(error)
})
})
},
})
}

View file

@ -6,7 +6,8 @@ function replacer(key, value) {
}
function jsonSchema(modelName) {
const models = ['Message', 'Thread', 'File', 'Error', 'SyncbackRequest', 'Account']
const models = ['Message', 'Thread', 'File', 'Error', 'SyncbackRequest', 'Account', 'Contact']
if (models.includes(modelName)) {
return Joi.object();
}

View file

@ -0,0 +1,22 @@
module.exports = (sequelize, Sequelize) => {
const Contact = sequelize.define('contact', {
accountId: { type: Sequelize.STRING, allowNull: false },
version: Sequelize.INTEGER,
name: Sequelize.STRING,
email: Sequelize.STRING,
}, {
instanceMethods: {
toJSON: function toJSON() {
return {
id: this.id,
account_id: this.accountId,
object: 'contact',
email: this.email,
name: this.name,
}
},
},
})
return Contact;
}

View file

@ -0,0 +1,53 @@
class ContactProcessor {
verified(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 (regex.test(contact.email) || contact.email.length > 60) {
console.log('Email address doesn\'t seem to be areal person')
return false
}
return true
}
emptyContact(Contact, options = {}, accountId) {
options.accountId = accountId
return Contact.create(options)
}
findOrCreateByContactId(Contact, contact, accountId) {
return Contact.find({where: {email: contact.email}})
.then((contactDb) => {
return contactDb || this.emptyContact(Contact, contact, accountId)
})
}
processMessage({db, message}) {
const {Contact} = db;
let allContacts = []
const fields = ['to', 'from', 'bcc', 'cc']
fields.forEach((field) => {
allContacts = allContacts.concat(message[field])
})
const filtered = allContacts.filter(this.verified)
const contactPromises = filtered.map((contact) => {
return this.findOrCreateByContactId(Contact, contact, message.accountId)
})
return Promise.all(contactPromises)
.then(() => {
return message
})
}
}
const processor = new ContactProcessor()
module.exports = {
order: 3,
processMessage: processor.processMessage.bind(processor),
}