I'm trying to send my stream data via email using Nodemailer but for some reason, the attachment is coming up as 0 kb
when I download it and look at its info. How can I properly send the stream & it's data as an attachment? The stream should contain a PKPass
is it a better option to send the response as an attachment? I'm using passkit-generator to generate the PKPass
const stream = examplePass.generate();
res.set({
'Content-Type': 'application/vnd.apple.pkpass',
'Content-disposition': `attachment; filename=${passName}.pkpass`,
});
stream.pipe(res);
//Send the receipt email
stream.on('finish', (attach) => {
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false,
requireTLS: true,
auth: {
user: '[email protected]',
pass: 'password',
},
});
let mailOptions = {
from: '[email protected]',
to: '[email protected]',
subject: 'You\'re on your way to ',
html: '<h1>Reciept email</h1>',
attachments: [
{
filename: 'Event.pkpass',
contentType: 'application/vnd.apple.pkpass',
content: stream,
},
],
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error.message);
}
console.log('success ' + info);
});
});
It seems that in this case, the only way to send the file is to read the entire stream and send it as a string or buffer:
const stream = examplePass.generate();
res.set({
'Content-Type': 'application/vnd.apple.pkpass',
'Content-disposition': `attachment; filename=${passName}.pkpass`,
});
stream.pipe(res);
const chunks = [];
stream.on('data', chunk => {
chunks.push(chunk);
});
stream.on('end', () => {
const content = Buffer.concat(chunks);
const transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false,
requireTLS: true,
auth: {
user: '[email protected]',
pass: 'password',
},
});
const mailOptions = {
from: '[email protected]',
to: '[email protected]',
subject: 'You\'re on your way to ',
html: '<h1>Reciept email</h1>',
attachments: [
{
filename: 'Event.pkpass',
contentType: 'application/vnd.apple.pkpass',
content
},
],
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error.message);
}
console.log('success:', info);
});
});
BUT! You need to be careful with this approach if the file is large, as it is fully loaded into RAM.
Your problem is that you piped the stream to res
which is a "StreamReader" aka consumer, instead you need just to pass it to nodeMailer which it is a StreamReader by itself.
const stream = examplePass.generate();
// res.set({
// 'Content-Type': 'application/vnd.apple.pkpass',
// 'Content-disposition': `attachment; filename=${passName}.pkpass`,
// });
// stream.pipe(res); <- remove this
//Send the receipt email
stream.on('finish', (attach) => {
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false,
requireTLS: true,
auth: {
user: '[email protected]',
pass: 'password',
},
});
let mailOptions = {
from: '[email protected]',
to: '[email protected]',
subject: "You're on your way to ",
html: '<h1>Reciept email</h1>',
attachments: [
{
filename: 'Event.pkpass',
contentType: 'application/vnd.apple.pkpass',
content: stream,
},
],
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error.message);
}
console.log('success ' + info);
});
});
This is how I'm streaming email attachments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With