Skip to content

Instantly share code, notes, and snippets.

@dohomi
Last active August 8, 2018 04:25
Show Gist options
  • Save dohomi/78f68b2c1bae236f0fa58e100e6c034a to your computer and use it in GitHub Desktop.
Save dohomi/78f68b2c1bae236f0fa58e100e6c034a to your computer and use it in GitHub Desktop.
Persist multiple files temporary with apollo-upload-server for sending out attachments as part of an email message.
const fs = require('fs')
const tmp = require('tmp')
/**
*
* @param stream
* @return {Promise<any>}
*/
const storeFS = ({stream}) => {
const tmpObj = tmp.fileSync()
const path = tmpObj.name
// const path = `${uploadDir}/${id}-${filename}`
return new Promise((resolve, reject) =>
stream
.on('error', error => {
if (stream.truncated)
// Delete the truncated file
fs.unlinkSync(path)
reject(error)
})
.pipe(fs.createWriteStream(path))
.on('error', error => reject(error))
.on('close', (...args) => {
console.log(...args)
})
.on('finish', () => resolve(tmpObj))
)
}
/**
*
* @param upload
* @return {Promise<{data: ReadStream, removeCallback: fileCallback, filename: *, contentType: *, knownLength: number}>}
*/
const processUpload = async upload => {
const {stream, filename, mimetype} = await upload
const tmpFile = await storeFS({stream})
return {
data: fs.createReadStream(tmpFile.name),
removeCallback: tmpFile.removeCallback,
filename,
contentType: mimetype,
knownLength: fs.statSync(tmpFile.name).size
}
}
/**
* @description need to check on apollo-upload-server v6 to circumvent the issue with await File in a loop
* @param files
* @return {Promise<any[]>}
*/
const prepareMailGunAttachments = async files => {
const persistedFiles = await Promise.all(
files.map(processUpload)
)
return persistedFiles
}
module.exports = prepareMailGunAttachments
sendMail: async (parent, {message, attachments}) => {
let files = []
let tmpFiles = null
if (attachments && attachments.length) {
tmpFiles = await prepareMailGunAttachments(attachments)
files = tmpFiles.map(item => {
const obj = Object.assign({}, item)
delete obj.removeCallback
return obj
})
}
try {
// sending out email with message and file attachments
const r = await sendMailgunMail(message,files)
// cleanup
if(tmpFiles){
tmpFiles.forEach(f => f.removeCallback())
}
return r
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment