Created
March 31, 2025 06:24
-
-
Save mark-alfonso/c0bb74dce644b6eb99af5422084601c9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const nodemailer = require('nodemailer'); | |
const assert = require('assert'); | |
const MONGO_URL = process.env.MONGO_URL | |
? process.env.MONGO_URL | |
: null; | |
console.log(MONGO_URL); | |
const stateMap = { | |
'on hold': 'On hold', | |
'closed won': 'Became order', | |
'closed declined': 'Declined', | |
'closed lost': 'Lost', | |
'closed spam': 'Spam', | |
'1. Inquiry Check': '1. Inquiry Check', | |
'2. Continue or not': '2. Continue or not? [CD]', | |
'3. Research solutions': '3. Research solutions', | |
'4. Send samples': '4. Send samples [MS]', | |
'5. Calculate costs': '5. Calculate costs [CC]', | |
'6. Price offer': '6. Price offer [PR]', | |
'7. Test reel': '7. Test reel', | |
"a.identify_contact_person": "a. Identify contact person", | |
"b.send_intro_email": "b. Send intro email", | |
"c.meet_live_online": "c. Meet live/online", | |
"d.bring_in_specific_inquiry": "d. Bring in specific inquiry", | |
"A.new_lead": "A. New lead", | |
"B.test_sincerity_by_email": "B. Test sincerity by email", | |
"C.get_phone_number": "C. Get phone number", | |
"D.call_customer": "D. CALL CUSTOMER", | |
"E.schedule_appointment_call_again": "E. Schedule appointment/call again", | |
"F.get_further_info_after_call": "F. Get further info (after call)", | |
"G.enter_lead_assessment_fields": "G. ENTER LEAD ASSESSMENT FIELDS", | |
"H.transfer_to_deal": "H. TRANSFER TO DEAL", | |
"1.understand_needs_get_originals": "1. Understand needs & get originals", | |
"2.find_solutions": "2. Find solutions", | |
"3.present_samples_finalize_specs": "3. Present samples & finalize specs", | |
"1.understand_motivation": "1. Understand motivation", | |
"2.define_winning_strategy": "2. Define winning strategy", | |
"3.execute_winning_strategy": "3. Execute winning strategy", | |
"4.send_offer": "4. Send offer", | |
"5.bring_in_test_order": "5. Bring in test order", | |
"6.deliver_test_reel": "6. Deliver test reel", | |
"7.win_the_order_go_get_it": "7. Win the order - go get it!" | |
}; | |
console.log('process.env.mail_url', process.env.MAIL_URL); | |
const MAIL_URL = process.env.MAIL_URL ? process.env.MAIL_URL : null; | |
var transporter = null; | |
if (MAIL_URL) transporter = nodemailer.createTransport(MAIL_URL); | |
var MongoClient = require('mongodb').MongoClient, | |
mongodb = null; | |
async function getUsers(db, query) { | |
return db.collection('users').find(query); | |
} | |
async function getInquiries(db, query) { | |
return db | |
.collection('inquiries') | |
.find(query) | |
.sort({ followUpAt: 1 }); | |
} | |
function formatInquiryEditTitle(doc) { | |
let title = ''; | |
if (doc.productName && doc.clientName) | |
title += doc.productName.split(doc.clientName + ': ').pop(); | |
return title; | |
} | |
function formatDate(date) { | |
let options = { | |
weekday: 'long', | |
year: 'numeric', | |
month: '2-digit', | |
day: '2-digit', | |
}; | |
if (date) { | |
const dateStringEN = date.toLocaleDateString('en-US', options); | |
const dateStringDE = date.toLocaleDateString('de-DE', options); | |
const dateStringENParts = dateStringEN.split(',')[0]; | |
const dateStringDEParts = dateStringDE.split(',')[1]; | |
return dateStringENParts + ',' + dateStringDEParts; | |
} else { | |
return '<without date>'; | |
} | |
} | |
function formatInquiryEmailString(inquiry) { | |
return ( | |
"<a href='https://orderly.alfipa.com/admin/Inquiries/" + | |
inquiry._id + | |
"/edit'>" + | |
inquiry.inquiryId + | |
'</a> <strong>' + | |
inquiry.clientName + | |
'</strong>: ' + | |
formatInquiryEditTitle(inquiry) + | |
' on ' + | |
formatDate(inquiry.followUpAt) + | |
'. Status: ' + | |
stateMap[inquiry.state] + | |
'.' | |
); | |
} | |
function formatUserEmailHtml(userDetails) { | |
let greetingText = '<p>Good morning ' + [userDetails.name] + ',<p>'; | |
let bodyText = ''; | |
let endingText = '<p>Have fun and lots of success!</p>'; | |
// first list | |
if (userDetails.firstInquiryHeader) { | |
bodyText += userDetails.firstInquiryHeader; | |
bodyText += '<ul>'; | |
for (let inquiry of userDetails.firstInquiries) { | |
bodyText += '<li>' + inquiry + '</li>'; | |
} | |
bodyText += '</ul>'; | |
} else { | |
bodyText += | |
'<p>Wishing you a nice start into the week. Looks like there are no inquiries due this week? Time for outbound acquisition?</p>'; | |
} | |
// second list | |
if (userDetails.secondInquiryHeader) { | |
bodyText += userDetails.secondInquiryHeader; | |
bodyText += '<ul>'; | |
for (let inquiry of userDetails.secondInquiries) { | |
bodyText += '<li>' + inquiry + '</li>'; | |
} | |
bodyText += '</ul>'; | |
} else { | |
bodyText += '<p>No overdue inquiries. Very nice!</p>'; | |
} | |
// third list | |
if (userDetails.thirdInquiryHeader) { | |
bodyText += userDetails.thirdInquiryHeader; | |
bodyText += '<ul>'; | |
for (let inquiry of userDetails.thirdInquiries) { | |
bodyText += '<li>' + inquiry + '</li>'; | |
} | |
bodyText += '</ul>'; | |
} | |
return greetingText + bodyText + endingText; | |
} | |
// Connect to the db | |
MongoClient.connect(MONGO_URL, function (err, client) { | |
if (err) console.log(err); | |
else { | |
assert.equal(null, err); | |
console.log('Connected correctly to MongoDB server'); | |
var db = client.db('alfipa'); | |
let usersInquiryMap; | |
let currDate = new Date(); | |
let nextWeek = new Date( | |
currDate.getTime() + 7 * 24 * 60 * 60 * 1000 | |
); | |
let firstInquiryList = getInquiries(db, { | |
user: { $ne: null }, | |
followUpAt: { $gte: currDate, $lte: nextWeek }, | |
state: { $nin: ['closed won', 'closed lost', 'closed spam'] }, | |
}); | |
let secondInquiryList = getInquiries(db, { | |
user: { $ne: null }, | |
followUpAt: { $lt: currDate }, | |
state: { $nin: ['closed won', 'closed lost', 'closed spam'] }, | |
}); | |
let thirdInquiryList = getInquiries(db, { | |
user: { $ne: null }, | |
state: 'wait on user', | |
$or: [{ followUpAt: { $gt: nextWeek } }, { followUpAt: null }], | |
}); | |
let users = getUsers(db, { 'roles.__global_roles__': 'admin' }); | |
console.log(nextWeek); | |
users.then(function (usersResult) { | |
usersResult.toArray(function (errUsers, usersList) { | |
let userDetailsMap = {}; | |
// place users info into a map | |
for (let user of usersList) { | |
let userObject = {}; | |
if (user.emails && user.emails[0] && user.emails[0].address) | |
userObject['address'] = user.emails[0].address; | |
if (user.profile && user.profile.firstName) | |
userObject['firstName'] = user.profile.firstName; | |
userDetailsMap[user._id] = userObject; | |
} | |
let usersEmailDetailsMap = {}; | |
firstInquiryList.then(function (firstResult) { | |
firstResult.toArray(function (errFirst, firstList) { | |
console.log('firstList:', firstList.length); | |
for (let inquiry of firstList) { | |
if (userDetailsMap[inquiry.user]) { | |
// initialize user email details object | |
if (!usersEmailDetailsMap[inquiry.user]) { | |
usersEmailDetailsMap[inquiry.user] = {}; | |
} | |
// initialize user address | |
if ( | |
!usersEmailDetailsMap[inquiry.user].emailAddress | |
) { | |
usersEmailDetailsMap[inquiry.user].emailAddress = | |
userDetailsMap[inquiry.user].address; | |
} | |
// initialize user name | |
if (!usersEmailDetailsMap[inquiry.user].name) { | |
usersEmailDetailsMap[inquiry.user].name = | |
userDetailsMap[inquiry.user].firstName; | |
} | |
// initialize header | |
if ( | |
!usersEmailDetailsMap[inquiry.user] | |
.firstInquiryHeader | |
) { | |
usersEmailDetailsMap[ | |
inquiry.user | |
].firstInquiryHeader = | |
'<p>Wishing you a nice start into the week. The following inquiries are due this week:</p>'; | |
} | |
// initialize first inquiry list | |
if ( | |
!usersEmailDetailsMap[inquiry.user].firstInquiries | |
) { | |
usersEmailDetailsMap[inquiry.user].firstInquiries = | |
[]; | |
} | |
// push inquiry to user's first list | |
usersEmailDetailsMap[ | |
inquiry.user | |
].firstInquiries.push( | |
formatInquiryEmailString(inquiry) | |
); | |
} | |
} | |
secondInquiryList.then(function (secondResult) { | |
secondResult.toArray(function (errSecond, secondList) { | |
console.log('secondList: ', secondList.length); | |
for (let inquiry of secondList) { | |
if (userDetailsMap[inquiry.user]) { | |
// initialize user email details object | |
if (!usersEmailDetailsMap[inquiry.user]) { | |
usersEmailDetailsMap[inquiry.user] = {}; | |
} | |
// initialize user address | |
if ( | |
!usersEmailDetailsMap[inquiry.user].emailAddress | |
) { | |
usersEmailDetailsMap[ | |
inquiry.user | |
].emailAddress = | |
userDetailsMap[inquiry.user].address; | |
} | |
// initialize user name | |
if (!usersEmailDetailsMap[inquiry.user].name) { | |
usersEmailDetailsMap[inquiry.user].name = | |
userDetailsMap[inquiry.user].firstName; | |
} | |
// initialize header | |
if ( | |
!usersEmailDetailsMap[inquiry.user] | |
.secondInquiryHeader | |
) { | |
usersEmailDetailsMap[ | |
inquiry.user | |
].secondInquiryHeader = | |
'<p>The following inquiries are overdue:</p>'; | |
} | |
// initialize second inquiry list | |
if ( | |
!usersEmailDetailsMap[inquiry.user] | |
.secondInquiries | |
) { | |
usersEmailDetailsMap[ | |
inquiry.user | |
].secondInquiries = []; | |
} | |
// push inquiry to user's second list | |
usersEmailDetailsMap[ | |
inquiry.user | |
].secondInquiries.push( | |
formatInquiryEmailString(inquiry) | |
); | |
} | |
} | |
thirdInquiryList.then(function (thirdResult) { | |
thirdResult.toArray(function (errThird, thirdList) { | |
console.log('thirdList: ', thirdList.length); | |
for (let inquiry of thirdList) { | |
if (userDetailsMap[inquiry.user]) { | |
// initialize user email details object | |
if (!usersEmailDetailsMap[inquiry.user]) { | |
usersEmailDetailsMap[inquiry.user] = {}; | |
} | |
// initialize user address | |
if ( | |
!usersEmailDetailsMap[inquiry.user] | |
.emailAddress | |
) { | |
usersEmailDetailsMap[ | |
inquiry.user | |
].emailAddress = | |
userDetailsMap[inquiry.user].address; | |
} | |
// initialize user name | |
if ( | |
!usersEmailDetailsMap[inquiry.user].name | |
) { | |
usersEmailDetailsMap[inquiry.user].name = | |
userDetailsMap[inquiry.user].firstName; | |
} | |
// initialize header | |
if ( | |
!usersEmailDetailsMap[inquiry.user] | |
.thirdInquiryHeader | |
) { | |
usersEmailDetailsMap[ | |
inquiry.user | |
].thirdInquiryHeader = | |
'<p>These inquiries are waiting for your processing:</p>'; | |
} | |
// initialize third inquiry list | |
if ( | |
!usersEmailDetailsMap[inquiry.user] | |
.thirdInquiries | |
) { | |
usersEmailDetailsMap[ | |
inquiry.user | |
].thirdInquiries = []; | |
} | |
// push inquiry to user's third list | |
usersEmailDetailsMap[ | |
inquiry.user | |
].thirdInquiries.push( | |
formatInquiryEmailString(inquiry) | |
); | |
} | |
} | |
if ( | |
Object.keys(usersEmailDetailsMap).length > 0 | |
) { | |
for (let user in usersEmailDetailsMap) { | |
if ( | |
usersEmailDetailsMap.hasOwnProperty(user) | |
) { | |
let userHtml = formatUserEmailHtml( | |
usersEmailDetailsMap[user] | |
); | |
// setup email data with unicode symbols | |
let mailOptions = { | |
from: '[email protected]', // sender address | |
to: usersEmailDetailsMap[user] | |
.emailAddress, // list of receivers | |
subject: 'Current inquiries this week', // Subject line | |
cc: '[email protected]', | |
text: '', // plain text body | |
html: userHtml, // html body | |
}; | |
// send mail with defined transport object | |
transporter.sendMail( | |
mailOptions, | |
(error, info) => { | |
if (error) { | |
return console.log(error); | |
} | |
console.log( | |
'Message sent: %s', | |
info.messageId | |
); | |
} | |
); | |
} | |
} | |
client.close(); | |
} | |
}); | |
}); | |
}); | |
}); | |
}); | |
}); | |
}); | |
}); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment