Skip to content

Instantly share code, notes, and snippets.

@mark-alfonso
Created March 31, 2025 06:24
Show Gist options
  • Save mark-alfonso/c0bb74dce644b6eb99af5422084601c9 to your computer and use it in GitHub Desktop.
Save mark-alfonso/c0bb74dce644b6eb99af5422084601c9 to your computer and use it in GitHub Desktop.
'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