Vulcan/packages/vulcan-email/lib/server/email.js

136 lines
4.7 KiB
JavaScript
Raw Normal View History

2018-01-25 15:03:03 -06:00
/* eslint-disable no-console */
2017-03-24 10:35:19 +09:00
import VulcanEmail from '../namespace.js';
import Juice from 'juice';
import htmlToText from 'html-to-text';
import Handlebars from 'handlebars';
import { Utils, getSetting, registerSetting, runQuery, Strings } from 'meteor/vulcan:lib'; // import from vulcan:lib because vulcan:core is not loaded yet
registerSetting('secondaryColor', '#444444');
registerSetting('accentColor', '#DD3416');
registerSetting('title', 'My App');
registerSetting('tagline');
registerSetting('emailFooter');
registerSetting('logoUrl');
registerSetting('logoHeight');
registerSetting('logoWidth');
registerSetting('defaultEmail', 'noreply@example.com');
registerSetting('title', 'Vulcan');
registerSetting('enableDevelopmentEmails', false);
2017-03-24 10:35:19 +09:00
VulcanEmail.templates = {};
2017-03-24 10:35:19 +09:00
VulcanEmail.addTemplates = templates => {
_.extend(VulcanEmail.templates, templates);
};
2018-09-16 11:48:38 +09:00
VulcanEmail.getTemplate = templateName =>
Handlebars.compile(VulcanEmail.templates[templateName], { noEscape: true, strict: true });
VulcanEmail.buildTemplate = (htmlContent, data = {}, locale) => {
const emailProperties = {
2016-12-12 15:00:56 +09:00
secondaryColor: getSetting('secondaryColor', '#444444'),
accentColor: getSetting('accentColor', '#DD3416'),
2017-03-24 10:35:19 +09:00
siteName: getSetting('title', 'My App'),
2016-12-12 15:00:56 +09:00
tagline: getSetting('tagline'),
2016-12-12 11:34:28 +09:00
siteUrl: Utils.getSiteUrl(),
body: htmlContent,
unsubscribe: '',
2018-09-16 11:48:38 +09:00
accountLink: Utils.getSiteUrl() + 'account',
2016-12-12 15:00:56 +09:00
footer: getSetting('emailFooter'),
logoUrl: getSetting('logoUrl'),
logoHeight: getSetting('logoHeight'),
logoWidth: getSetting('logoWidth'),
...data,
__: Strings[locale],
};
2018-09-12 11:59:00 +09:00
const emailHTML = VulcanEmail.getTemplate('wrapper')(emailProperties);
2018-09-16 11:48:38 +09:00
const inlinedHTML = Juice(emailHTML, { preserveMediaQueries: true });
const doctype =
'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
2018-09-16 11:48:38 +09:00
return doctype + inlinedHTML;
};
VulcanEmail.generateTextVersion = html => {
return htmlToText.fromString(html, {
2018-09-16 11:48:38 +09:00
wordwrap: 130,
});
2018-09-16 11:48:38 +09:00
};
2018-09-26 12:24:48 -07:00
VulcanEmail.send = (to, subject, html, text, throwErrors, cc, bcc, replyTo, headers) => {
// TODO: limit who can send emails
// TODO: fix this error: Error: getaddrinfo ENOTFOUND
2018-09-16 11:48:38 +09:00
if (typeof to === 'object') {
// eslint-disable-next-line no-redeclare
2018-09-26 12:24:48 -07:00
var { to, cc, bcc, replyTo, subject, html, text, throwErrors, headers } = to;
}
const from = getSetting('defaultEmail', 'noreply@example.com');
const siteName = getSetting('title', 'Vulcan');
2018-09-16 11:48:38 +09:00
subject = '[' + siteName + '] ' + subject;
2018-09-16 11:48:38 +09:00
if (typeof text === 'undefined') {
// Auto-generate text version if it doesn't exist. Has bugs, but should be good enough.
text = VulcanEmail.generateTextVersion(html);
}
const email = {
from: from,
to: to,
cc: cc,
bcc: bcc,
replyTo: replyTo,
subject: subject,
2018-09-26 12:24:48 -07:00
headers: headers,
text: text,
2018-09-16 11:48:38 +09:00
html: html,
};
2018-09-26 12:41:02 -07:00
const shouldSendEmail = process.env.NODE_ENV === 'production' || getSetting('enableDevelopmentEmails', false)
2018-09-26 12:41:02 -07:00
console.log(`//////// sending email${shouldSendEmail ? '' : ' (simulation)'}`); // eslint-disable-line
console.log('from: ' + from); // eslint-disable-line
console.log('cc: ' + cc); // eslint-disable-line
console.log('bcc: ' + bcc); // eslint-disable-line
console.log('replyTo: ' + replyTo); // eslint-disable-line
console.log('headers: ' + JSON.stringify(headers)); // eslint-disable-line
if (shouldSendEmail) {
try {
Email.send(email);
} catch (error) {
2018-09-16 11:48:38 +09:00
console.log('// error while sending email:'); // eslint-disable-line
console.log(error); // eslint-disable-line
if (throwErrors) throw error;
}
}
return email;
};
VulcanEmail.build = async ({ emailName, variables, locale }) => {
// execute email's GraphQL query
2017-08-24 13:16:50 +09:00
const email = VulcanEmail.emails[emailName];
2018-09-16 11:48:38 +09:00
const result = email.query ? await runQuery(email.query, variables, { locale }) : { data: {} };
// if email has a data() function, merge its return value with results from the query
2018-09-16 11:48:38 +09:00
const data = email.data ? { ...result.data, ...email.data(variables) } : result.data;
const subject = typeof email.subject === 'function' ? email.subject(data) : email.subject;
data.__ = Strings[locale];
const html = VulcanEmail.buildTemplate(VulcanEmail.getTemplate(email.template)(data), data, locale);
return { data, subject, html };
2018-09-16 11:48:38 +09:00
};
2017-08-19 16:13:59 +09:00
2018-09-26 12:24:48 -07:00
VulcanEmail.buildAndSend = async ({ to, cc, bcc, replyTo, emailName, variables, locale = getSetting('locale'), headers }) => {
const email = await VulcanEmail.build({ to, emailName, variables, locale });
2018-09-26 12:24:48 -07:00
return VulcanEmail.send({ to, cc, bcc, replyTo, subject: email.subject, html: email.html, headers });
};
VulcanEmail.buildAndSendHTML = (to, subject, html) => VulcanEmail.send(to, subject, VulcanEmail.buildTemplate(html));