From 27cc47d3fdef5a1e721453b2004ef0f962f1a2a2 Mon Sep 17 00:00:00 2001 From: Eemeli Aro Date: Fri, 27 Jul 2018 00:38:18 +0300 Subject: [PATCH] kyyhky: Move custom data fields to template-specific files --- .../hugo-packet-series-extra.js | 4 + .../hugo-update-nominations.js | 14 +++ config/message-templates/hugo-update-votes.js | 14 +++ config/message-templates/kansa-new-payment.js | 19 ++++ .../message-templates/kansa-update-payment.js | 1 + .../message-templates/kansa-upgrade-person.js | 3 + kyyhky/lib/login-uri.js | 3 +- kyyhky/lib/send-email.js | 91 +++++-------------- 8 files changed, 80 insertions(+), 69 deletions(-) create mode 100644 config/message-templates/hugo-packet-series-extra.js create mode 100644 config/message-templates/hugo-update-nominations.js create mode 100644 config/message-templates/hugo-update-votes.js create mode 100644 config/message-templates/kansa-new-payment.js create mode 100644 config/message-templates/kansa-update-payment.js create mode 100644 config/message-templates/kansa-upgrade-person.js diff --git a/config/message-templates/hugo-packet-series-extra.js b/config/message-templates/hugo-packet-series-extra.js new file mode 100644 index 0000000..c61d202 --- /dev/null +++ b/config/message-templates/hugo-packet-series-extra.js @@ -0,0 +1,4 @@ +module.exports = (data) => { + data.voter_email = data.email + data.email = 'hugos@choiceofgames.com' +} diff --git a/config/message-templates/hugo-update-nominations.js b/config/message-templates/hugo-update-nominations.js new file mode 100644 index 0000000..4c2f70a --- /dev/null +++ b/config/message-templates/hugo-update-nominations.js @@ -0,0 +1,14 @@ +function categoryString({ category, nominations }, wrap) { + const title = category.charAt(0) + category.slice(1).replace(/[A-Z]/g, ' $&') + const cn = nominations.map(n => { + const ns = Object.values(n).join('; ') + return ' - ' + wrap(' ', ns) + }); + return `${title}:\n${cn.join('\n')}` +} + +module.exports = (data, wrap) => { + data.nominations = data.nominations + .map(n => categoryString(n, wrap)) + .join('\n\n') +} diff --git a/config/message-templates/hugo-update-votes.js b/config/message-templates/hugo-update-votes.js new file mode 100644 index 0000000..e568b59 --- /dev/null +++ b/config/message-templates/hugo-update-votes.js @@ -0,0 +1,14 @@ +function categoryString({ category, finalists }, wrap) { + const fi = finalists && finalists.filter(f => f) + if (!fi || fi.length === 0) return null + const title = category.charAt(0) + category.slice(1).replace(/[A-Z]/g, ' $&') + const votes = fi.map((finalist, i) => ` ${i + 1}. ` + wrap(' ', finalist)) + return `${title}:\n${votes.join('\n')}` +} + +module.exports = (data, wrap) => { + data.votes = data.votes + .map(v => categoryString(v, wrap)) + .filter(s => s) + .join('\n\n') +} diff --git a/config/message-templates/kansa-new-payment.js b/config/message-templates/kansa-new-payment.js new file mode 100644 index 0000000..a2be157 --- /dev/null +++ b/config/message-templates/kansa-new-payment.js @@ -0,0 +1,19 @@ +function paymentDataString(data, shape, ignored) { + if (!data) return '' + return Object.keys(data) + .filter(key => key && data[key] && !ignored[key]) + .map(key => { + const field = shape && shape.find(s => s.key === key) + const label = field && field.label || key; + return `${label}: ${data[key]}` + }) + .join('\n') +} + +module.exports = (data) => { + data.data = paymentDataString(data.data, data.shape, { mandate_url: true }) + data.strAmount = data.currency.toUpperCase() + ' ' + (data.amount / 100).toFixed(2) + if (data.type === 'ss-token' && data.status === 'succeeded') { + return 'kansa-new-siteselection-token' + } +} diff --git a/config/message-templates/kansa-update-payment.js b/config/message-templates/kansa-update-payment.js new file mode 100644 index 0000000..234a7dc --- /dev/null +++ b/config/message-templates/kansa-update-payment.js @@ -0,0 +1 @@ +module.exports = require('./kansa-new-payment') diff --git a/config/message-templates/kansa-upgrade-person.js b/config/message-templates/kansa-upgrade-person.js new file mode 100644 index 0000000..ef6e50d --- /dev/null +++ b/config/message-templates/kansa-upgrade-person.js @@ -0,0 +1,3 @@ +module.exports = (data) => { + if (data.paper_pubs) data.membership += ' with paper pubs' +} diff --git a/kyyhky/lib/login-uri.js b/kyyhky/lib/login-uri.js index 63a8d5a..43a1d3e 100644 --- a/kyyhky/lib/login-uri.js +++ b/kyyhky/lib/login-uri.js @@ -2,12 +2,13 @@ const apiRoot = process.env.API_URI_ROOT const loginRoot = process.env.LOGIN_URI_ROOT function barcodeUri({ id, key, memberId, membership }) { - if (membership === 'Supporter') return '' + if (!key || membership === 'Supporter') return '' const parts = [apiRoot, 'barcode', key, memberId || id] return encodeURI(parts.join('/')) } function loginUri({ email, key, memberId, path }) { + if (!key) return '' const parts = [loginRoot, email, key] if (memberId) parts.push(memberId) let uri = parts.join('/') diff --git a/kyyhky/lib/send-email.js b/kyyhky/lib/send-email.js index 7ce7655..16d31f9 100644 --- a/kyyhky/lib/send-email.js +++ b/kyyhky/lib/send-email.js @@ -9,37 +9,24 @@ const sendgrid = require('./sendgrid') const TEMPLATES_DIR = '/message-templates' const WRAP_WIDTH = 78; -function nominationsString(data) { - return data.map(({ category, nominations }) => { - const ct = category.charAt(0) + category.slice(1).replace(/[A-Z]/g, ' $&'); - const cn = nominations.map(n => { - const ns = Object.keys(n).map(k => n[k]).join('; '); - return ' - ' + wrap(WRAP_WIDTH - 4)(ns).replace(/\n/g, '\n '); - }); - return `${ct}:\n${cn.join('\n')}`; - }).join('\n\n'); +function wrapIndented(prefix, str) { + return prefix + ? wrap(WRAP_WIDTH - prefix.length)(str).replace(/\n/g, '\n' + prefix) + : wrap(WRAP_WIDTH)(str) } -function paymentDataString(data, shape, ignored) { - if (!data) return ''; - const label = (key) => shape && (shape.find(s => s.key === key) || {}).label || key; - return Object.keys(data) - .filter(key => key && data[key] && !ignored[key]) - .map(key => `${label(key)}: ${data[key]}`) - .join('\n'); -} - -function votesString(data) { - return data - .map(({ category, finalists }) => ({ - title: category.charAt(0) + category.slice(1).replace(/[A-Z]/g, ' $&'), - votes: finalists && finalists.filter(finalist => finalist).map((finalist, i) => { - return ` ${i+1}. ` + wrap(WRAP_WIDTH - 4)(finalist).replace(/\n/g, '\n '); - }) - })) - .filter(({ votes }) => votes && votes.length > 0) - .map(({ title, votes }) => `${title}:\n${votes.join('\n')}`) - .join('\n\n'); +function applyCustomConfig(name, data) { + const fn = path.resolve(process.cwd(), TEMPLATES_DIR, name) + return new Promise((resolve, reject) => { + try { + const customFunction = require(fn) + const customName = customFunction(data, wrapIndented) + resolve(customName || name) + } catch (error) { + if (error && error.code === 'MODULE_NOT_FOUND') resolve(name) + else reject(error) + } + }) } function getTemplate(name) { @@ -74,45 +61,13 @@ function sgRequest(msgTemplate, data) { }); } -function sendEmail(tmplName, data) { - let tmplData = Object.assign({ - barcode_uri: barcodeUri(data), - login_uri: loginUri(data) - }, data); - switch (tmplName) { - - case 'hugo-packet-series-extra': - tmplData = { - email: 'hugos@choiceofgames.com', - voter_email: data.email - } - break; - - case 'hugo-update-nominations': - tmplData.nominations = nominationsString(data.nominations); - break; - - case 'hugo-update-votes': - tmplData.votes = votesString(data.votes); - break; - - case 'kansa-new-payment': - case 'kansa-update-payment': - if (data.type === 'ss-token' && data.status === 'succeeded') { - tmplName = 'kansa-new-siteselection-token'; - } - tmplData.data = paymentDataString(data.data, data.shape, { mandate_url: true }); - tmplData.strAmount = data.currency.toUpperCase() + ' ' + (data.amount / 100).toFixed(2); - break; - - case 'kansa-upgrade-person': - if (data.paper_pubs) tmplData.membership += ' with paper pubs'; - break; - - } - return getTemplate(tmplName) - .then(msgTemplate => { - const request = sgRequest(msgTemplate, tmplData); +function sendEmail(name, data) { + data.barcode_uri = barcodeUri(data) + data.login_uri = loginUri(data) + return applyCustomConfig(name, data) + .then(getTemplate) + .then(template => { + const request = sgRequest(template, data); return sendgrid.API(request) }) .then(() => data.email)