Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to attach a node.js readable stream to a Sendgrid email?

I'm using PDFKit to generate PDFs. I'm using Nodejitsu for hosting, so I can't save the PDFs to file, but I can save them to a readable stream. I'd like to attach that stream in a Sendgrid email, like so:

sendgrid.send({
    to: email,
    files: [{ filename: 'File.pdf', content: /* what to put here? */ }]
    /* ... */
});

I've tried doc.output() to no avail.

like image 404
delwin Avatar asked Mar 20 '23 12:03

delwin


2 Answers

To use the SendGrid nodejs API with a streaming file, just convert the streaming into a buffer. You can convert a readable stream into a buffer using stream-to-array.

var streamToArray = require('stream-to-array');

streamToArray(your_stream, function (err, arr) {
  var buffer = Buffer.concat(arr)
  sendgrid.send({
    to: email,
    files: [{ filename: 'File.pdf' content: buffer }]
  })
})
like image 131
scottmotte Avatar answered Apr 06 '23 09:04

scottmotte


Try send the stream through the streamToArray package and encode it to base64. (Without the base64 encoding, Sendgrid will throw an error about no content string)

 // createPdf() module returns the doc stream
 // styling etc etc
 doc.end()      
 return doc // then once doc.end() is called, return the stream

 const sgMail = require('@sendgrid/mail');
 const streamToArray = require('stream-to-array');

 streamToArray(createPdf(), function (err, arr) { // createPdf() returns the doc made by pdfKit
        var buffer = Buffer.concat(arr).toString('base64')
        msg["subject"] = 'Here is your attachment'
        msg["html"] = body // your html for your email, could use text instead
        msg["attachments"] = [{
            filename: 'attachment.pdf',
            content: buffer,
            type: 'application/pdf',
            disposition: 'attachment'
        }]

        sgMail.send(msg) // sendgrid
      })
like image 34
leo_cape Avatar answered Apr 06 '23 10:04

leo_cape