Skip to content
Snippets Groups Projects
index.js 15.3 KiB
Newer Older
const config = require('config')
const Email = require('@pubsweet/component-send-email')
Audrey Hamelers's avatar
Audrey Hamelers committed
const logger = require('@pubsweet/logger')
Audrey Hamelers's avatar
Audrey Hamelers committed
const lodash = require('lodash')
Audrey Hamelers's avatar
Audrey Hamelers committed
const {
  htmlEmailBase,
  setReviewerTemplate,
  newReviewerTemplate,
  newReviewFinalTemplate,
  setReviewFinalTemplate,
ahamelers's avatar
ahamelers committed
  checkReviewerTemplate,
  rejectSubmissionTemplate,
  removeDupeTemplate,
ahamelers's avatar
ahamelers committed
  alreadyCompleteTemplate,
Nikos Marinos's avatar
Nikos Marinos committed
  newPackageForTaggingTemplate,
  processedTaggingFilesTemplate,
  bulkUploadTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  finalReviewTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  correctedReviewTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  preprintReviewTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  preprintVersionReviewTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  completedPreprintTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  resetPasswordTemplate,
  grantsAddedTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  licenseAddedTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  incompleteTemplate,
  stalledTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  stalledPreprintTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  stalledErrorTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  deletedTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
  deletedTaggingTemplate,
Audrey Hamelers's avatar
Audrey Hamelers committed
} = require('./templates')
const superagent = require('superagent')

require('superagent-proxy')(superagent)
Audrey Hamelers's avatar
Audrey Hamelers committed
const { europepmcUrl } = config
ahamelers's avatar
ahamelers committed
const tagger = config.ftp_tagger.email
const { sender, url, testAddress, system, dev, listName } = config['epmc-email']
Audrey Hamelers's avatar
Audrey Hamelers committed
const parsed = string => lodash.unescape(string)

Audrey Hamelers's avatar
Audrey Hamelers committed
const sendMail = async (
  to,
  subject,
  message,
  from = null,
  cc = null,
  bcc = null,
) => {
  const mailData = {
Audrey Hamelers's avatar
Audrey Hamelers committed
    from: from || sender,
    to: testAddress || to,
    subject: `[${listName}] ${subject}`,
    html: htmlEmailBase(message, url),
  }
  if (cc) {
    mailData.cc = testAddress || cc
  }
  if (bcc) {
    mailData.bcc = testAddress || bcc
Audrey Hamelers's avatar
Audrey Hamelers committed
  const { transport } = require(config.get('mailer.path'))
  logger.info(
    `Sending email. Mailer host: ${transport.host}, port: ${transport.port}`,
  )
Audrey Hamelers's avatar
Audrey Hamelers committed
  logger.info(
Audrey Hamelers's avatar
Audrey Hamelers committed
    `Recipients: ${to}${cc ? `, CC: ${cc}` : ''}${bcc ? `, BCC: ${bcc}` : ''}`,
Audrey Hamelers's avatar
Audrey Hamelers committed
  if (testAddress) {
    logger.info('Testing! Mail recipients overwritten to', testAddress)
  }
Audrey Hamelers's avatar
Audrey Hamelers committed
  return Email.send(mailData)
Audrey Hamelers's avatar
Audrey Hamelers committed
const userMessage = async (
Audrey Hamelers's avatar
Audrey Hamelers committed
  email,
  subject,
  message,
  from = null,
  cc = null,
  bcc = null,
) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const regex = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()[\]{};:'".,<>?«»“”‘’]))/gi
ahamelers's avatar
ahamelers committed
  const linkAdded = message.replace(
    regex,
    '<a href="$&" style="color:#20699C">$&</a>',
  )
  const systemBcc = (bcc && [system].concat(bcc)) || system
  const messageDiv = `<div style="white-space: pre-wrap;overflow-wrap: break-word;">${linkAdded}</div>`
  return sendMail(email, subject, messageDiv, from, cc, systemBcc)
ahamelers's avatar
ahamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const taggerErrorEmail = async (subject, message) => {
  const html = `<p>This manuscript has been returned to you. Please correct the following tagging errors.</p>${message}`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(tagger, subject, html, null, null, system)
ahamelers's avatar
ahamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const taggerEmail = async (email, manId, title, link) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const html = newPackageForTaggingTemplate(manId, parsed(title), link)
  const subject = 'New Package Available for Tagging'
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
const processedTaggerEmail = async (email, manId, title, packageName) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const html = processedTaggingFilesTemplate(manId, parsed(title), packageName)
  const subject = 'Tagging files have been uploaded'
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
const errorDevEmail = async (process, err) => {
  const html = `<p>Something went wrong with ${process}<p>
  <p>Error: <b>${err}</b>
  <p>The Europe PMC plus system</p>`
  const subject = `Something went wrong with ${process}`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(dev, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
const bulkUploaderEmail = async (email, message, filename = '') => {
  const html = bulkUploadTemplate(message, filename)
Yogmatee Roochun's avatar
Yogmatee Roochun committed
  const subject = `Error while processing package ${filename}`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, [system, dev])
Audrey Hamelers's avatar
Audrey Hamelers committed
const resetPassword = async (email, user, token) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const link = `${url}password-reset/${token}`
  const html = resetPasswordTemplate(user, link)
  const subject = `Password reset requested`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const completedEmail = async (email, manInfo) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const { title, pmcid, claim } = manInfo
  const link = `${europepmcUrl}/article/PMC/${pmcid}`
  const html = completedTemplate(parsed(title), link, pmcid, claim)
  const subject = `${manInfo.id}: Manuscript available in Europe PMC`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Nikos Marinos's avatar
Nikos Marinos committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const completedPreprintEmail = async (email, manInfo) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const { pprid, title, version, claim } = manInfo
  const link = `${europepmcUrl}/article/PPR/${pprid}`
  const html = completedPreprintTemplate(parsed(title), version, link, claim)
Audrey Hamelers's avatar
Audrey Hamelers committed
  const subject = `${manInfo.id}: Preprint displayed in Europe PMC`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
const deletedEmail = async (email, manInfo) => {
  const html = deletedTemplate(parsed(manInfo.title))
Audrey Hamelers's avatar
Audrey Hamelers committed
  const subject = `${manInfo.id}: Submission cancelled`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const deletedTaggerEmail = async manId => {
  const html = deletedTaggingTemplate(manId)
  const subject = `${manId}: Cancel tagging`
  return sendMail(tagger, subject, html, null, null, system)
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const incompleteEmail = async (manInfo, submitter) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const { title, givenNames, surname } = submitter
  const { email } = submitter.identities[0]
  const salutation = `${title ? `${title} ` : ''}${givenNames} ${surname}`
  const link = `${url}submission/${manInfo.id}/${
    manInfo.status === 'INITIAL' ? 'create' : 'submit'
  }`
  const html = incompleteTemplate(salutation, parsed(manInfo.title), link)
Audrey Hamelers's avatar
Audrey Hamelers committed
  const subject = `${manInfo.id}: Your submission is incomplete`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const stalledEmail = async (manInfo, reviewer, preprint) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const { title, givenNames, surname, email, token } = reviewer
  const salutation = `${title ? `${title} ` : ''}${givenNames} ${surname}`
  const link = token
    ? `${url}dashboard?accept=${token}`
    : `${url}submission/${manInfo.id}/${
        manInfo.status === 'xml-review' ? 'review' : 'submit'
      }`
Audrey Hamelers's avatar
Audrey Hamelers committed
  const args = [salutation, parsed(manInfo.title), link]
  const html = preprint
    ? stalledPreprintTemplate(...args)
    : stalledTemplate(...args)
Audrey Hamelers's avatar
Audrey Hamelers committed
  const subject = `${manInfo.id}: Please review your ${
    preprint ? 'preprint' : 'submission'
  }`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const stalledErrorEmail = async (manInfo, user) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const { title, givenNames, surname } = user
  const { email } = user.identities[0]
  const salutation = `${title ? `${title} ` : ''}${givenNames} ${surname}`
  const link = `${url}submission/${manInfo.id}/submit`
  const html = stalledErrorTemplate(salutation, parsed(manInfo.title), link)
Audrey Hamelers's avatar
Audrey Hamelers committed
  const subject = `${manInfo.id}: Your submission still needs corrections`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const grantEmail = async (pi, grants, manInfo, reviewer) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const html = grantsAddedTemplate(pi, grants, manInfo, reviewer)
  const subject = `Publication linked to your grants`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(pi.email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const licenseEmail = async (person, funder, license, manInfo) => {
  const { title: t, givenNames, surname } = person.name
  const salutation = `${t ? `${t} ` : ''}${givenNames} ${surname}`
  const { id, title, status } = manInfo
  const loc = status === 'INITIAL' ? 'create' : 'submit'
  const link = `${url}submission/${id}/${loc}`
  const html = licenseAddedTemplate(salutation, funder, title, license, link)
  const subject = `${id}: License exception confirmed`
  await sendMail(person.email, subject, html, null, null, system)
  return { subject, html }
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const reviewerEmail = async ({ reviewer, manInfo, submitter, token }) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const { title, givenNames, surname } = submitter
  const submitterName = `${title ? `${title} ` : ''}${givenNames} ${surname}`
  const { title: t, givenNames: g, surname: s } = reviewer.name
  const salutation = `${t ? `${t} ` : ''}${g} ${s}`
  const link = `${url}submission/${manInfo.id}/submit`
Audrey Hamelers's avatar
Audrey Hamelers committed
  const args = [salutation, parsed(manInfo.title), submitterName, link]
Audrey Hamelers's avatar
Audrey Hamelers committed
  let html = ''
  if (token === 'correction') {
Audrey Hamelers's avatar
Audrey Hamelers committed
    html = checkReviewerTemplate(...args)
  } else if (reviewer.id) {
Audrey Hamelers's avatar
Audrey Hamelers committed
    html = setReviewerTemplate(...args)
Audrey Hamelers's avatar
Audrey Hamelers committed
  } else {
    args[3] = `${url}dashboard?accept=${token}`
Audrey Hamelers's avatar
Audrey Hamelers committed
    html = newReviewerTemplate(...args)
Audrey Hamelers's avatar
Audrey Hamelers committed
  }
  const subject = `Approve submission of ${manInfo.id}`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(reviewer.email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
const finalReviewerEmail = async ({
  reviewer,
  manInfo,
  submitter = null,
  token,
}) => {
  const { title, givenNames, surname } = submitter || ''
  const submitterName =
    submitter && `${title ? `${title} ` : ''}${givenNames} ${surname}`
  const { title: t, givenNames: g, surname: s } = reviewer.name
  const salutation = `${t ? `${t} ` : ''}${g} ${s}`
  const finalReview = manInfo.status === 'xml-review'
  const link = `${url}submission/${manInfo.id}/review`
  const args = [
    salutation,
    parsed(manInfo.title),
    submitterName,
    link,
    finalReview,
  ]
  let html = ''
  if (reviewer.id) {
    html = setReviewFinalTemplate(...args)
  } else if (token) {
    args[3] = `${url}dashboard?accept=${token}`
    html = newReviewFinalTemplate(...args)
  }
  if (html) {
    const subject = finalReview
      ? `Please review manuscript ${manInfo.id}`
      : `You've been assigned to review ${manInfo.id}`
Audrey Hamelers's avatar
Audrey Hamelers committed
    return sendMail(reviewer.email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
const submitterRejectEmail = async ({
  reviewer,
  manInfo,
  submitter,
  message,
}) => {
ahamelers's avatar
ahamelers committed
  const { title, givenNames, surname } = submitter
  const { email } = submitter.identities[0]
  const salutation = `${title ? `${title} ` : ''}${givenNames} ${surname}`
  const { title: t, givenNames: g, surname: s } = reviewer
  const reviewerName = `${t ? `${t} ` : ''}${g} ${s}`
  const link = `${url}submission/${manInfo.id}/submit`
ahamelers's avatar
ahamelers committed
  const html = rejectSubmissionTemplate(
    salutation,
Audrey Hamelers's avatar
Audrey Hamelers committed
    parsed(manInfo.title),
ahamelers's avatar
ahamelers committed
    reviewerName,
    message,
    link,
  )
  const subject = `${manInfo.id}: Submission rejected`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
ahamelers's avatar
ahamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const removeDuplicateEmail = async (user, badInfo, goodInfo) => {
  const { title, givenNames, surname } = user
  const { email } = user.identities[0]
  const salutation = `${title ? `${title} ` : ''}${givenNames} ${surname}`
  const pmcid =
    goodInfo['meta,articleIds'] &&
    goodInfo['meta,articleIds'].find(id => id.pubIdType === 'pmcid')
      ? goodInfo['meta,articleIds'].find(id => id.pubIdType === 'pmcid').id
      : null
  const html = removeDupeTemplate(
    salutation,
    badInfo.id,
Audrey Hamelers's avatar
Audrey Hamelers committed
    parsed(badInfo['meta,title']),
    goodInfo.id,
    pmcid,
  )
  const subject = `${badInfo.id}: Duplicate submission`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
ahamelers's avatar
ahamelers committed
const alreadyCompleteEmail = async (user, manInfo) => {
  const { title, givenNames, surname } = user
  const { email } = user.identities[0]
  const salutation = `${title ? `${title} ` : ''}${givenNames} ${surname}`
  const pmcid =
    manInfo['meta,articleIds'] &&
    manInfo['meta,articleIds'].find(id => id.pubIdType === 'pmcid') &&
    manInfo['meta,articleIds'].find(id => id.pubIdType === 'pmcid').id
  const epmcURL = `https://www.ebi.ac.uk/europepmc/webservices/rest/search?query=PMCID:${pmcid}&resulttype=lite&format=json`
  let superagentRequest = superagent.get(epmcURL)
  if (process.env.superagent_http_proxy) {
    superagentRequest = superagentRequest.proxy(
      process.env.superagent_http_proxy,
    )
  }
  const response = await superagentRequest
  const { body } = response
  const epmc =
    body.resultList &&
    body.resultList.result[0] &&
    body.resultList.result[0].inEPMC
ahamelers's avatar
ahamelers committed
  const inEPMC = epmc === 'Y'
  const html = alreadyCompleteTemplate(
    salutation,
    manInfo.id,
    manInfo['meta,title'],
    pmcid,
    inEPMC,
Audrey Hamelers's avatar
Audrey Hamelers committed
    europepmcUrl,
ahamelers's avatar
ahamelers committed
  )
  const subject = `${manInfo.id}: Article already in Europe PMC`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
ahamelers's avatar
ahamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const finalReviewEmail = async (reviewer, manInfo) => {
Audrey Hamelers's avatar
Audrey Hamelers committed
  const { title, givenNames, surname } = reviewer
  const { email } = reviewer.identities[0]
  const salutation = `${title ? `${title} ` : ''}${givenNames} ${surname}`
  const link = `${url}submission/${manInfo.id}/review`
Audrey Hamelers's avatar
Audrey Hamelers committed
  const releaseDelay =
    manInfo.releaseDelay === '0'
      ? 'immediately'
      : `${manInfo.releaseDelay} month${
          manInfo.releaseDelay === '1' ? '' : 's'
        }`
  const html = finalReviewTemplate(
    salutation,
Audrey Hamelers's avatar
Audrey Hamelers committed
    parsed(manInfo.title),
Audrey Hamelers's avatar
Audrey Hamelers committed
    link,
    releaseDelay,
  )
  const subject = `${manInfo.id}: Ready for final review`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
const correctedReviewEmail = async (reviewer, manInfo) => {
  const { id, title, preprint, releaseDelay } = manInfo
  const { title: t, givenNames: g, surname: s } = reviewer
  const { email } = reviewer.identities[0]
  const salutation = `${t ? `${t} ` : ''}${g} ${s}`
  const link = `${url}submission/${id}/review`
  const html = correctedReviewTemplate(
    salutation,
    parsed(title),
    link,
    preprint,
    releaseDelay,
  )
  const subject = `${id}: Review your corrected ${
    preprint ? 'preprint' : 'manuscript'
  }`
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const preprintReviewEmail = async (reviewer, manInfo, token) => {
  const { id, title, server, openAccess, version } = manInfo
Audrey Hamelers's avatar
Audrey Hamelers committed
  const { title: t, givenNames: g, surname: s } = reviewer.name
  const salutation = `${t ? `${t} ` : ''}${g} ${s}`
Audrey Hamelers's avatar
Audrey Hamelers committed
  const unrestricted =
    openAccess && openAccess.search(/\/(by-nd|by-nc-nd)\//i) < 0
Audrey Hamelers's avatar
Audrey Hamelers committed
  let existing = true
Audrey Hamelers's avatar
Audrey Hamelers committed
  let link = `${url}submission/${id}/review`
Audrey Hamelers's avatar
Audrey Hamelers committed
  if (token && !reviewer.id) {
    existing = false
    link = `${url}dashboard?accept=${token}`
  }
Audrey Hamelers's avatar
Audrey Hamelers committed
  const fortnightDate = new Date(Date.now() + 12096e5)
  const fortnight = `${fortnightDate.getUTCDate()} ${fortnightDate.toLocaleString(
    'en-GB',
    { month: 'long' },
  )}`
Audrey Hamelers's avatar
Audrey Hamelers committed
  const html = preprintReviewTemplate(
Audrey Hamelers's avatar
Audrey Hamelers committed
    id,
Audrey Hamelers's avatar
Audrey Hamelers committed
    salutation,
Audrey Hamelers's avatar
Audrey Hamelers committed
    parsed(title),
Audrey Hamelers's avatar
Audrey Hamelers committed
    link,
Audrey Hamelers's avatar
Audrey Hamelers committed
    existing,
Audrey Hamelers's avatar
Audrey Hamelers committed
    openAccess,
Audrey Hamelers's avatar
Audrey Hamelers committed
    unrestricted,
    fortnight,
Audrey Hamelers's avatar
Audrey Hamelers committed
  )
  if (html) {
    const subject = `Enabling search and display of your preprint${
      server ? ` from ${server}` : ''
    } in the Europe PMC archive.`
Audrey Hamelers's avatar
Audrey Hamelers committed
    return sendMail(reviewer.email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
  }
}

Audrey Hamelers's avatar
Audrey Hamelers committed
const preprintVersionEmail = async (reviewer, manInfo) => {
  const { id, title, server } = manInfo
  const { title: t, givenNames: g, surname: s } = reviewer
  const { email } = reviewer.identities[0]
  const salutation = `${t ? `${t} ` : ''}${g} ${s}`
  const subject = 'Display new preprint version in Europe PMC'
  const link = `${url}submission/${id}/review`
  const html = preprintVersionReviewTemplate(
    id,
    salutation,
    parsed(title),
    server,
    link,
  )
Audrey Hamelers's avatar
Audrey Hamelers committed
  return sendMail(email, subject, html, null, null, system)
Audrey Hamelers's avatar
Audrey Hamelers committed
}

Audrey Hamelers's avatar
Audrey Hamelers committed
  parsed,
  sendMail,
ahamelers's avatar
ahamelers committed
  userMessage,
Nikos Marinos's avatar
Nikos Marinos committed
  taggerEmail,
  processedTaggerEmail,
Yogmatee Roochun's avatar
Yogmatee Roochun committed
  errorDevEmail,
ahamelers's avatar
ahamelers committed
  taggerErrorEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  reviewerEmail,
  finalReviewerEmail,
ahamelers's avatar
ahamelers committed
  submitterRejectEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  grantEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  licenseEmail,
  removeDuplicateEmail,
ahamelers's avatar
ahamelers committed
  alreadyCompleteEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  finalReviewEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  correctedReviewEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  preprintReviewEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  preprintVersionEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  completedPreprintEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  deletedEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  deletedTaggerEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  resetPassword,
Audrey Hamelers's avatar
Audrey Hamelers committed
  incompleteEmail,
  stalledEmail,
Audrey Hamelers's avatar
Audrey Hamelers committed
  stalledErrorEmail,