diff --git a/README.md b/README.md index 261f24f..ffb7897 100644 --- a/README.md +++ b/README.md @@ -32,10 +32,30 @@ NOTE: You will NOT receive an email if you(the author that registered their emai "urlToPads": "http://beta.etherpad.org/p/", // urlToPads = The URL to your pads note the trailing / "emailServer": { // See https://github.com/eleith/emailjs for settings "host": "127.0.0.1" + }, + "messages": { // All fields are optional; omit any to use the built-in default + "footer": "\nYou can unsubscribe from these emails in the pad's Settings window.\n", + "beginSubject": "Someone started editing {padId}", + "beginBody": "This pad is now being edited:\n <{padUrl}>\n{footer}", + "endSubject": "Someone finished editing {padId}", + "endBody": "This pad is done being edited:\n <{padUrl}>\n{footer}", + "subscribeSubject": "Email subscription confirmation for pad {padId}", + "subscribeBody": "Please click on this link in order to validate your subscription to the pad {padId}\n{confirmLink}", + "unsubscribeSubject": "Email unsubscription confirmation for pad {padId}", + "unsubscribeBody": "Please click on this link in order to validate your unsubscription to the pad {padId}\n{confirmLink}" } } ``` +Supported placeholders in `messages` templates: + +| Placeholder | Available in | Description | +|---|---|---| +| `{padId}` | all | The pad's identifier | +| `{padUrl}` | all | Full URL to the pad | +| `{footer}` | `beginBody`, `endBody` | The configured (or default) footer text | +| `{confirmLink}` | `subscribeBody`, `unsubscribeBody` | The one-click confirmation URL | + # Translation This plugin has for now translations for english, french and german. In case you would like to have it in another language, you can easily translate the few sentences and then contact us on irc (#etherpad-lite-dev on irc.freenode.net) or create a Pull-Request on the GitHub repository. diff --git a/handleMessage.js b/handleMessage.js index 7cc7bc4..4b1a6b8 100644 --- a/handleMessage.js +++ b/handleMessage.js @@ -18,6 +18,8 @@ const urlToPads = (pluginSettings && pluginSettings.urlToPads) ? pluginSettings.urlToPads : 'http://beta.etherpad.org/p/'; const emailServer = (pluginSettings && pluginSettings.emailServer) ? pluginSettings.emailServer : {host: '127.0.0.1'}; +const messageSettings = (pluginSettings && pluginSettings.messages) || {}; +const {renderTemplate} = require('./messageUtils'); if (!pluginSettings) { console.warn('Settings for ep_email_notifications plugin are missing in settings.json file'); @@ -159,14 +161,25 @@ const subscriptionEmail = async (context, email, emailFound, userInfo, padId) => }); // Send mail to user with the link for validation + const confirmLink = `${padUrl(padId)}/subscribe=${subscribeId}`; + const vars = {padId, padUrl: padUrl(padId), confirmLink}; + const subject = renderTemplate( + messageSettings.subscribeSubject != null + ? messageSettings.subscribeSubject + : 'Email subscription confirmation for pad {padId}', + vars); + const text = renderTemplate( + messageSettings.subscribeBody != null + ? messageSettings.subscribeBody + : 'Please click on this link in order to validate your subscription to the pad {padId}\n{confirmLink}', + vars); let message; try { message = await util.promisify(server.send.bind(server))({ - text: 'Please click on this link in order to validate your subscription to the pad ' + - `${padId}\n${padUrl(padId)}/subscribe=${subscribeId}`, + text, from: `${fromName} <${fromEmail}>`, to: userInfo.email, - subject: `Email subscription confirmation for pad ${padId}`, + subject, }); } catch (err) { console.error(err); @@ -231,14 +244,25 @@ const unsubscriptionEmail = async (context, emailFound, userInfo, padId) => { }); // Send mail to user with the link for validation + const confirmLink = `${padUrl(padId)}/unsubscribe=${unsubscribeId}`; + const vars = {padId, padUrl: padUrl(padId), confirmLink}; + const subject = renderTemplate( + messageSettings.unsubscribeSubject != null + ? messageSettings.unsubscribeSubject + : 'Email unsubscription confirmation for pad {padId}', + vars); + const text = renderTemplate( + messageSettings.unsubscribeBody != null + ? messageSettings.unsubscribeBody + : 'Please click on this link in order to validate your unsubscription to the pad {padId}\n{confirmLink}', + vars); let message; try { message = await util.promisify(server.send.bind(server))({ - text: 'Please click on this link in order to validate your unsubscription to the pad ' + - `${padId}\n${padUrl(padId)}/unsubscribe=${unsubscribeId}`, + text, from: `${fromName} <${fromEmail}>`, to: userInfo.email, - subject: `Email unsubscription confirmation for pad ${padId}`, + subject, }); } catch (err) { console.error(err); diff --git a/messageUtils.js b/messageUtils.js new file mode 100644 index 0000000..c4a961e --- /dev/null +++ b/messageUtils.js @@ -0,0 +1,14 @@ +'use strict'; + +/** + * Expand template placeholders of the form {key} using the provided vars map. + * Unknown placeholders are left unchanged. + * + * @param {string} template - The template string containing {key} placeholders. + * @param {Object} vars - Map of placeholder names to replacement values. + * @returns {string} The rendered string. + */ +const renderTemplate = (template, vars) => + template.replace(/\{(\w+)\}/g, (_, key) => (key in vars ? vars[key] : `{${key}}`)); + +module.exports = {renderTemplate}; diff --git a/update.js b/update.js index 3e58eff..f825dea 100644 --- a/update.js +++ b/update.js @@ -24,6 +24,8 @@ const urlToPads = (pluginSettings && pluginSettings.urlToPads) ? pluginSettings.urlToPads : 'http://beta.etherpad.org/p/'; const emailServer = (pluginSettings && pluginSettings.emailServer) ? pluginSettings.emailServer : {host: '127.0.0.1'}; +const messageSettings = (pluginSettings && pluginSettings.messages) || {}; +const {renderTemplate} = require('./messageUtils'); // A timer object we maintain to control how we send emails const timers = {}; @@ -33,7 +35,9 @@ const timers = {}; const server = new SMTPClient(emailServer); -const emailFooter = "\nYou can unsubscribe from these emails in the pad's Settings window.\n"; +const emailFooter = messageSettings.footer != null + ? messageSettings.footer + : "\nYou can unsubscribe from these emails in the pad's Settings window.\n"; exports.padUpdate = (hookName, _pad) => { if (!pluginSettings) return false; @@ -70,13 +74,24 @@ const notifyBegin = async (padId) => { return; } console.debug(`Emailing ${recipient} about a new begin update`); + const vars = {padId, padUrl: padUrl(padId), footer: emailFooter}; + const subject = renderTemplate( + messageSettings.beginSubject != null + ? messageSettings.beginSubject + : 'Someone started editing {padId}', + vars); + const text = renderTemplate( + messageSettings.beginBody != null + ? messageSettings.beginBody + : 'This pad is now being edited:\n <{padUrl}>\n{footer}', + vars); let message; try { message = await util.promisify(server.send.bind(server))({ - text: `This pad is now being edited:\n <${padUrl(padId)}>\n${emailFooter}`, + text, from: `${fromName} <${fromEmail}>`, to: recipient, - subject: `Someone started editing ${padId}`, + subject, }); } catch (err) { console.error(err); @@ -104,13 +119,24 @@ const notifyEnd = async (padId) => { return; } console.debug(`Emailing ${recipient} about a pad finished being updated`); + const vars = {padId, padUrl: padUrl(padId), footer: emailFooter}; + const subject = renderTemplate( + messageSettings.endSubject != null + ? messageSettings.endSubject + : 'Someone finished editing {padId}', + vars); + const text = renderTemplate( + messageSettings.endBody != null + ? messageSettings.endBody + : 'This pad is done being edited:\n <{padUrl}>\n{footer}', + vars); let message; try { message = await util.promisify(server.send.bind(server))({ - text: `This pad is done being edited:\n <${padUrl(padId)}>\n${emailFooter}`, + text, from: `${fromName} <${fromEmail}>`, to: recipient, - subject: `Someone finished editing ${padId}`, + subject, }); } catch (err) { console.error(err);