У меня есть ночной процесс, который отправляет запланированные отчеты, вызывая созданную мной конечную точку, которая возвращает оперативный отчет в формате PDF.
Проблема, с которой я столкнулся, заключалась в том, чтобы получить двоичный файл, возвращенный из конечной точки, в буфер, который Nodemailer может использовать для прикрепления отчета в формате PDF.
Я просто использую обещание, возвращаемое из fetch() и arrayBuffer(). Я НЕ использую Async Await.
Приведенный ниже фрагмент кода с использованием arrayBuffer() и Buffer.from() работает, но мне интересно, есть ли более эффективный способ обработки этого, особенно при работе с большими файлами PDF.
Я предпочитаю работать в памяти, а не записывать на диск. Я выделил много памяти в Express и пока НЕ вижу проблем с памятью.
const sendPDFReport = (reportScheduleId, cb) => {
let scheduleObj;
//*** Get Report Schedule Data from MongoDB and Assign to scheduleObj
let emailAddresses = [];
//*** Push Recipient Emails into Email Array
//*** Do Work Like Build Fetch URL and Connection Properties Object ie.,
let fetchBody={};
//*** Build JSON object of POST Params and assign to fetchBody
let fetchURL = process.env.APPSERVER_URL+some_report_path;
let config = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(fetchBody),
responseType: 'blob'
};
let transporter = nodemailer.createTransport({
host: 'mail.whatever.com',
service: "Outlook365",
secure: true,
port: 465,
auth: {
user: process.env.NO_REPLY,
pass: process.env.NO_REPLY_PW
},
tls: {
ciphers: 'SSLv3',
rejectUnauthorized: false
}
});
fetch(fetchURL, config)
.then(response => {
if (response.ok) {
//*** PDF Binary Response Buffering for Nodemailer
response.arrayBuffer()
.then(resBufferAr => {
const pdfBuffer = Buffer.from(resBufferAr);
// **** Build Email mailOptions for Nodemailer Transporter Object ***
let mailOptions = {
from: process.env.NO_REPLY,
to: emailAddresses.join([separator = ',']),
subject: 'Scheduled Report: ' + scheduleObj.reportType + ' ' + scheduleObj.selectedReport,
html: '<h4> See Attached Report </h4>';
//*** Nodemailer Attachment Section
attachments: [{
filename: scheduleObj.reportType + '_' + scheduleObj.selectedReport + '_' + now + '.pdf',
content: pdfBuffer,
encoding: 'base64',
contentType: 'application/pdf'
}]
};
transporter.sendMail(mailOptions, function (err) {
if (err) {
console.log('Transporter Error: ' + err);
return cb(err);
}
return cb(null);
}
})
.catch((err) => {
console.log('Problem Processing Alert Notification: ' + err);
return cb(err);
})
return cb(null);
}
Любые комментарии или предложения были бы замечательными.
let
? Конечно, большинство из них могут бытьconst
. И ваш обратный вызов будет вызываться дважды... Один раз сразу после выполнения функции, а затем еще раз в блоках.then()
или.catch()
. ;) - person TJBlackman   schedule 22.06.2021const
редко имеет ценность ниже верхнего уровня, посколькуconst
не предотвращает мутацию объекта или затенение переменных, что, по моему мнению, является настоящей проблемой, особенно если у вас уже есть линтер. - person user3781737   schedule 22.06.2021