Send email when adding contacts to Close.io leads

This commit is contained in:
Matt Lott 2016-04-07 21:23:39 -07:00
parent 6c0823486f
commit cd7ec7f8dd

View file

@ -1,8 +1,8 @@
// Upsert new lead data into Close.io
'use strict';
if (process.argv.length !== 5) {
log("Usage: node <script> <Close.io API key> <Intercom 'App ID:API key'> <mongo connection Url>");
if (process.argv.length !== 7) {
log("Usage: node <script> <Close.io general API key> <Close.io mail API key1> <Close.io mail API key2> <Intercom 'App ID:API key'> <mongo connection Url>");
process.exit();
}
@ -24,14 +24,19 @@ const customFieldsToRemove = [
];
// Skip these problematic leads
const leadsToSkip = ['6 sınıflar', 'fdsafd', 'ashtasht', 'matt+20160404teacher3 school', 'sdfdsf'];
const leadsToSkip = ['6 sınıflar', 'fdsafd', 'ashtasht', 'matt+20160404teacher3 school', 'sdfdsf', 'ddddd', 'dsfadsaf', "Nolan's School of Wonders"];
const demoRequestEmailTemplates = ['tmpl_s7BZiydyCHOMMeXAcqRZzqn0fOtk0yOFlXSZ412MSGm', 'tmpl_cGb6m4ssDvqjvYd8UaG6cacvtSXkZY3vj9b9lSmdQrf'];
const createTeacherEmailTemplates = ['tmpl_i5bQ2dOlMdZTvZil21bhTx44JYoojPbFkciJ0F560mn', 'tmpl_CEZ9PuE1y4PRvlYiKB5kRbZAQcTIucxDvSeqvtQW57G'];
const emailDelayMinutes = 27;
const scriptStartTime = new Date();
const closeIoApiKey = process.argv[2];
const intercomAppIdApiKey = process.argv[3];
const closeIoMailApiKeys = [process.argv[3], process.argv[4]]; // Automatic mails sent as API owners
const intercomAppIdApiKey = process.argv[5];
const intercomAppId = intercomAppIdApiKey.split(':')[0];
const intercomApiKey = intercomAppIdApiKey.split(':')[1];
const mongoConnUrl = process.argv[4];
const mongoConnUrl = process.argv[6];
const MongoClient = require('mongodb').MongoClient;
const async = require('async');
const request = require('request');
@ -88,7 +93,12 @@ class Lead {
}
addTrialRequest(email, trial) {
if (!this.contacts[email.toLowerCase()]) this.contacts[email.toLowerCase()] = {};
this.contacts[email.toLowerCase()].name = trial.properties.name;
if (trial.properties.firstName && trial.properties.lastName) {
this.contacts[email.toLowerCase()].name = `${trial.properties.firstName} ${trial.properties.lastName}`;
}
else if (trial.properties.name) {
this.contacts[email.toLowerCase()].name = trial.properties.name;
}
this.contacts[email.toLowerCase()].trial = trial;
}
addUser(email, user) {
@ -98,11 +108,11 @@ class Lead {
const postData = {
display_name: this.name,
name: this.name,
status: 'Not Attempted',
status: 'Auto Attempted',
contacts: this.getContactsPostData(),
custom: {
lastUpdated: new Date(),
'Lead Origin': 'Demo Request'
'Lead Origin': this.getLeadOrigin()
}
};
for (const email in this.contacts) {
@ -121,8 +131,8 @@ class Lead {
// console.log('DEBUG: getLeadPutData', currentLead.name);
const putData = {};
const currentCustom = currentLead.custom || {};
if (currentCustom['Lead Origin'] !== 'Demo Request') {
putData['custom.Lead Origin'] = 'Demo Request';
if (!currentCustom['Lead Origin']) {
putData['custom.Lead Origin'] = this.getLeadOrigin();
}
for (const email in this.contacts) {
@ -145,6 +155,18 @@ class Lead {
}
return putData;
}
getLeadOrigin() {
for (const email in this.contacts) {
const props = this.contacts[email].trial.properties;
switch (props.siteOrigin) {
case 'create teacher':
return 'Create Teacher';
case 'convert teacher':
return 'Convert Teacher';
}
}
return 'Demo Request';
}
getContactsPostData(existingLead) {
const postData = [];
const existingEmails = {};
@ -362,7 +384,7 @@ function updateExistingLead(lead, existingLead, done) {
const tasks = []
for (const newContact of newContacts) {
newContact.lead_id = existingLead.id;
tasks.push(createAddContactFn(newContact));
tasks.push(createAddContactFn(newContact, lead, existingLead));
}
async.parallel(tasks, (err, results) => {
if (err) return done(err);
@ -409,12 +431,27 @@ function saveNewLead(lead, done) {
tasks.push(createAddNoteFn(existingLead.id, newNote));
}
async.parallel(tasks, (err, results) => {
return done(err);
if (err) return done(err);
// Send emails to new contacts
const tasks = [];
for (const contact of existingLead.contacts) {
for (const email of contact.emails) {
if (['create teacher', 'convert teacher'].indexOf(lead.contacts[email.email].trial.properties.siteOrigin) >= 0) {
tasks.push(createSendEmailFn(email.email, existingLead.id, contact.id, getRandomEmailTemplate(createTeacherEmailTemplates)));
}
else {
tasks.push(createSendEmailFn(email.email, existingLead.id, contact.id, getRandomEmailTemplate(demoRequestEmailTemplates)));
}
}
}
async.parallel(tasks, (err, results) => {
return done(err);
});
});
});
}
function createUpdateLeadFn(lead) {
return (done) => {
// console.log('DEBUG: updateLead', lead.name);
@ -441,21 +478,30 @@ function createUpdateLeadFn(lead) {
};
}
function createAddContactFn(postData) {
function createAddContactFn(postData, internalLead, externalLead) {
return (done) => {
// console.log('DEBUG: addContact', postData.lead_id);
const options = {
uri: `https://${closeIoApiKey}:X@app.close.io/api/v1/activity/Contact/`,
uri: `https://${closeIoApiKey}:X@app.close.io/api/v1/contact/`,
body: JSON.stringify(postData)
};
request.post(options, (error, response, body) => {
if (error) return done(error);
const result = JSON.parse(body);
if (result.errors || result['field-errors']) {
console.error(`New Contact POST error for ${leadId}`);
const newContact = JSON.parse(body);
if (newContact.errors || newContact['field-errors']) {
console.error(`New Contact POST error for ${postData.lead_id}`);
console.error(body);
return done();
}
// Send emails to new contact
const email = postData.emails[0].email;
if (['create teacher', 'convert teacher'].indexOf(internalLead.contacts[email].trial.properties.siteOrigin) >= 0) {
return sendMail(email, externalLead.id, newContact.id, getRandomEmailTemplate(createTeacherEmailTemplates), done);
}
else {
return sendMail(email, externalLead.id, newContact.id, getRandomEmailTemplate(demoRequestEmailTemplates), done);
}
return done();
});
};
}
@ -484,6 +530,53 @@ function createAddNoteFn(leadId, newNote) {
};
}
function getRandomEmailTemplate(templates) {
if (templates.length < 0) return '';
return templates[Math.floor(Math.random() * templates.length)];
}
function getRandomEmailApiKey() {
if (closeIoMailApiKeys.length < 0) return;
return closeIoMailApiKeys[Math.floor(Math.random() * closeIoMailApiKeys.length)];
}
function createSendEmailFn(email, leadId, contactId, template) {
return (done) => {
return sendMail(email, leadId, contactId, template, done);
};
}
function sendMail(toEmail, leadId, contactId, template, done) {
// console.log('DEBUG: sendMail', toEmail, leadId, contactId, template);
const dateScheduled = new Date();
dateScheduled.setUTCMinutes(dateScheduled.getUTCMinutes() + emailDelayMinutes);
const postData = {
to: [toEmail],
contact_id: contactId,
lead_id: leadId,
template_id: template,
status: 'scheduled',
date_scheduled: dateScheduled
};
const options = {
uri: `https://${getRandomEmailApiKey()}:X@app.close.io/api/v1/activity/email/`,
body: JSON.stringify(postData)
};
request.post(options, (error, response, body) => {
if (error) return done(error);
const result = JSON.parse(body);
if (result.errors || result['field-errors']) {
const errorMessage = `Send email POST error for ${toEmail} ${leadId} ${contactId}`;
console.error(errorMessage);
console.error(body);
// console.error(postData);
return done(errorMessage);
}
return done();
});
}
function updateLeads(leads, done) {
const tasks = []
for (const name in leads) {