9

Sending email attachments doesn't appear to be implemented yet in Meteor's official email package. I've tried the nodemailer suggestion (seen here) but received the error "Cannot read property 'createTransport' of undefined".

I'm attempting to create a CSV file in a data URI and then send that attachment. Here's a snippet of my code when using the official email package:

csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csv);

var options = {
          from: "xxx@gmail.com",
          to: "xxx@gmail.com",
          subject: "xxx",
          html: html,
          attachment: {
            fileName: fileName, 
            path: csvData
            }
      };

Meteor.call('sendEmail', options);

EDIT:

Here is basically what my nodemailer code looked like:

var nodemailer = Nodemailer;
var transporter = nodemailer.createTransport();
transporter.sendMail({
    from: 'sender@address',
    to: 'receiver@address',
    subject: 'hello',
    text: 'hello world!',
    attachments: [
        {   
            path: csvData
        }
    ]
});
Community
  • 1
  • 1
Kyle Bachan
  • 1,053
  • 2
  • 15
  • 33
  • what's the nodemailer code you tried? I don't believe attachments are supported in the meteor official package. – rivarolle Feb 04 '15 at 01:27
  • I used [this package](https://atmospherejs.com/mrt/meteor-nodemailer) and followed the instructions to get it running (has pretty similar setup to Meteor's email). I'll update my question with the code. – Kyle Bachan Feb 04 '15 at 02:59
  • This article has some examples http://kukuruku.co/hub/javascript/meteor-how-to-build-a-todo-list – IM_AG Feb 10 '15 at 03:18
  • 2
    If you can hold off just until the next release (probably 1.2) of Meteor you will get attachments in core (or switch to the devel branch). See more details here: https://github.com/andris9/mailcomposer#add-attachments *Source* https://github.com/meteor/meteor/blob/devel/History.md – Stephan Apr 27 '15 at 06:39
  • Wow, that would be pretty sweet! My workaround for the time being was just to embed the attachment details as HTML. – Kyle Bachan Apr 27 '15 at 14:50

1 Answers1

5

Not enough rep to comment.

I ended up solving the attachment issue by using Sendgrids NPM package.

npm install sendgrid

If you don't have npm in you meteor app you can read this. https://meteorhacks.com/complete-npm-integration-for-meteor

In your packages.json

{
  "sendgrid": "1.4.0"
}

Then in a file that runs on the server:

Meteor.startup(function(){
    process.env.MAIL_URL = 'smtp://<username>:<password>@smtp.sendgrid.net:587';
});

Here is a sample meteor method that gets the url of an attachment (we're using S3) from an attachment collection. This particular method can send any number of attachments to any number of recipients. There is some context specific logic in here but it should be enough to get you up and running sending attachments.

The important part:

var email = new sendgrid.Email();
email.setFrom("email@email.com");
email.setSubject("subject");
email.addFile({
    filename: attachment_name,
    url: attachment_url
});
sendgrid.send(email, function (err, json) {
    if (err) {
        console.error(err); 
    } 
    if (json) { 
        console.log(json.message);                   
    }
});

A complete method example:

Meteor.methods({
SendEmail: function (subject, message, templateNumber) {

    //console.log(subject, message, templateNumber);

    var user_id = Meteor.userId();
    var list = UserList.find({user_id: user_id}).fetch();
    var sentTemplate = sentTemplate + templateNumber;
    var counter = 0;
    console.log(list.length);
    // Track is the 'No Response' from the list.
    for (var i = 0; i < list.length; i++) {    
            var email = new sendgrid.Email();
            if (list[i].track == null || list[i].track == "1") {
                //email.addTo(list[0].list[i].Email);
                //console.log(list[0].list[i].Email);
                email.to = list[i].email;
            }
            email.setFrom(Meteor.user().email);
            email.replyto = Meteor.user().email;

            email.setSubject(subject);

            var firstName = list[i].name.split(" ")[0];

            var companyReplace = message.replace("{{Company}}", list[i].company).replace("{{Company}}", list[i].company).replace("{{Company}}", list[i].company).replace("{{Company}}", list[i].company).replace("{{Company}}", list[i].company);
            var nameReplace = companyReplace.replace("{{Name}}",list[i].name).replace("{{Name}}",list[i].name).replace("{{Name}}",list[i].name).replace("{{Name}}",list[i].name).replace("{{Name}}",list[i].name)
            var firstNameReplace = companyReplace.replace("{{FirstName}}",firstName).replace("{{FirstName}}",firstName).replace("{{FirstName}}",firstName).replace("{{FirstName}}",firstName).replace("{{FirstName}}",firstName);

            email.setHtml(firstNameReplace);

            var numAttachments = Attachments.find({user_id: Meteor.userId()}).fetch().length;
            var attachments = Attachments.find({user_id: Meteor.userId()}).fetch();
            console.log("**********Attachments****************");
            console.log(attachments);
            console.log("**********Attachments****************");
            for (var t = 0; t < numAttachments; t++) {
                email.addFile({
                    filename: attachments[t].attachment_name,
                    url: attachments[t].attachment_url
                });
            }
            sendgrid.send(email, function (err, json) {
                if (err) {
                    console.error(err);
                } 
                if (json) {
                    console.log(json.message);

                }
            });
            //console.log(email);

    } // end for loop

    if (templateNumber == 1) {
        Meteor.users.update({_id:Meteor.userId()}, {$set: {"sentTemplate1": true}});
    }
    if (templateNumber == 2) {
        Meteor.users.update({_id:Meteor.userId()}, {$set: {"sentTemplate2": true}});
    }
    if (templateNumber == 3) {
        Meteor.users.update({_id:Meteor.userId()}, {$set: {"sentTemplate3": true}});
    }
    if (templateNumber == 4) {
        Meteor.users.update({_id:Meteor.userId()}, {$set: {"sentTemplate4": true}});
    }
    // for each email. replace all html

   return list.length;
}
});
Andrew Pierno
  • 510
  • 4
  • 12