email.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. // buffer each user's email text in a queue, then flush them in single email
  2. Meteor.startup(() => {
  3. Notifications.subscribe('email', (user, title, description, params) => {
  4. // add quote to make titles easier to read in email text
  5. const quoteParams = _.clone(params);
  6. ['card', 'list', 'oldList', 'board', 'comment'].forEach(key => {
  7. if (quoteParams[key]) quoteParams[key] = `"${params[key]}"`;
  8. });
  9. ['timeValue', 'timeOldValue'].forEach(key => {
  10. quoteParams[key] = quoteParams[key] ? `${params[key]}` : '';
  11. });
  12. const lan = user.getLanguage();
  13. const subject = TAPi18n.__(title, params, lan); // the original function has a fault, i believe the title should be used according to original author
  14. const existing = user.getEmailBuffer().length > 0;
  15. const text = `${existing ? `<br/>\n${subject}<br/>\n` : ''}${
  16. params.user
  17. } ${TAPi18n.__(description, quoteParams, lan)}<br/>\n${params.url}`;
  18. user.addEmailBuffer(text);
  19. // unlike setTimeout(func, delay, args),
  20. // Meteor.setTimeout(func, delay) does not accept args :-(
  21. // so we pass userId with closure
  22. const userId = user._id;
  23. Meteor.setTimeout(() => {
  24. const user = Users.findOne(userId);
  25. // for each user, in the timed period, only the first call will get the cached content,
  26. // other calls will get nothing
  27. const texts = user.getEmailBuffer();
  28. if (texts.length === 0) return;
  29. // merge the cached content into single email and flush
  30. const html = texts.join('<br/>\n\n');
  31. user.clearEmailBuffer();
  32. try {
  33. Email.send({
  34. to: user.emails[0].address.toLowerCase(),
  35. from: Accounts.emailTemplates.from,
  36. subject,
  37. html,
  38. });
  39. } catch (e) {
  40. return;
  41. }
  42. }, process.env.EMAIL_NOTIFICATION_TIMEOUT || 30000);
  43. });
  44. });