1

I need to notify all users through their email when I have new post

server/methods.js

Meteor.methods({
  sendNewsletter: function(doc) {
    var pipeline = [
      {$group: {_id:"$emails.address"}}
    ];
    var to = Meteor.users.aggregate(pipeline);
    var text = "Title: " + doc.title + "\n\n"
            + "Summary: " + doc.summary + "\n\n\n\n"

    this.unblock();

    // Send the e-mail
    Email.send({
        to: to,
        from: "[email protected]",
        subject: "MyApp - " + doc.title,
        text: text
    });
  }
});

When I call sendNewsletter's method in client, I got following warning on my terminal:

I20151030-04:16:42.039(7)? Exception while invoking method 'sendNewsletter' RecipientError: Can't send mail - all recipients were rejected
I20151030-04:16:42.041(7)?     at Object.Future.wait (/Users/user/.meteor/packages/meteor-tool/.1.1.9.1f0n2l1++os.osx.x86_64+web.browser+web.cordova/mt-os.osx.x86_64/dev_bundle/server-lib/node_modules/fibers/future.js:398:15)
I20151030-04:16:42.042(7)?     at smtpSend (packages/email/email.js:86:1)
I20151030-04:16:42.042(7)?     at Object.Email.send (packages/email/email.js:176:1)
I20151030-04:16:42.043(7)?     at maybeAuditArgumentChecks (livedata_server.js:1692:12)
I20151030-04:16:42.043(7)?     at livedata_server.js:708:19
I20151030-04:16:42.043(7)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20151030-04:16:42.044(7)?     at livedata_server.js:706:40
I20151030-04:16:42.044(7)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20151030-04:16:42.044(7)?     at livedata_server.js:704:46
I20151030-04:16:42.044(7)?     - - - - -
I20151030-04:16:42.045(7)?     at SMTPClient._actionRCPT (/Users/user/.meteor/packages/email/.1.0.7.11df8pa++os+web.browser+web.cordova/npm/node_modules/simplesmtp/lib/client.js:909:27)
I20151030-04:16:42.045(7)?     at SMTPClient._onData (/Users/user/.meteor/packages/email/.1.0.7.11df8pa++os+web.browser+web.cordova/npm/node_modules/simplesmtp/lib/client.js:329:29)
I20151030-04:16:42.045(7)?     at CleartextStream.emit (events.js:95:17)
I20151030-04:16:42.045(7)?     at CleartextStream.<anonymous> (_stream_readable.js:765:14)
I20151030-04:16:42.046(7)?     at CleartextStream.emit (events.js:92:17)
I20151030-04:16:42.046(7)?     at emitReadable_ (_stream_readable.js:427:10)
I20151030-04:16:42.046(7)?     at _stream_readable.js:420:7
I20151030-04:16:42.046(7)?     at process._tickCallback (node.js:448:13)

Does anyone know how to send email to multiple recipients? thank You,,,,

3
  • hi @MichelFloyd.. yes that's the problem.,, i have asked solution at this: stackoverflow.com/questions/33425565/… Commented Oct 30, 2015 at 4:26
  • what do you mean string with comma? Commented Oct 30, 2015 at 4:34
  • Oops, never mind. Meteor docs call for a "string or array of strings" so you're on the right track. Commented Oct 30, 2015 at 6:27

1 Answer 1

2

Re-write your server/methods.js file get the to variable hold an array of the email addresses. Since Meteor doesn't support distinct in MongoDB (yet) which you could simply use in mongo shell as db.users.distinct("emails.address"), you can instead

Use three methods in the underscore.js library map(), flatten() and uniq() to get the distinct email addresses from the users collection.

First convert the Meteor cursor returned by .find() to an array by using .fetch() on your cursor. Example:

var users = Users.find({}, { fields: {"emails": true} }).fetch();   

Then use the map() method to produces a new array of only email address values within another array by mapping each document in list through a transformation function (iteratee). Define the transformation function as follows

var callback = function(doc) {
    var emailAddresses = [];
    for (var i = 0; i < doc.emails.length; i++) {
        emailAddresses.push(doc.emails[i].address);
    }
    return emailAddresses;
};

var emails = _.map(users, callback);

You can also use the mongo cursor's map() method which is compatible with Array.map() to get the arrays directly with your collection:

var emails = Users.find({}).map(callback);

Flatten the array by using the flatten() to get a usable array then use the uniq() method to return a bunch of unique arrays as follows:

var uniqueEmails = _.uniq(_.flatten(emails));

Altogether your code should now have an array of email addresses that you can then send

Meteor.methods({
    sendNewsletter: function(doc) {
        var users = Users.find({}, { fields: {"emails": true} }).fetch();
        var callback = function(doc) {
            var emailAddresses = [];
            for (var i = 0; i < doc.emails.length; i++) {
                emailAddresses.push(doc.emails[i].address);
            }
            return emailAddresses;
        };

        var emails = _.map(users, callback);
        var to = _.uniq(_.flatten(emails));
        var text = "Title: " + doc.title + "\n\n"
                + "Summary: " + doc.summary + "\n\n\n\n"

        this.unblock();

        // Send the e-mail
        Email.send({
            to: to,
            from: "[email protected]",
            subject: "MyApp - " + doc.title,
            text: text
        });
    }
});

Check the demo below.

var users = [
	{
		"_id" : "ukn9MLo3hRYEpCCty",    
		"emails" : [ 
			{
				"address" : "[email protected]",
				"verified" : false
			}
		]
	},
	{
		"_id" : "5SXRXraariyhRQACe",    
		"emails" : [ 
			{
				"address" : "[email protected]",
				"verified" : false
			}
		]
	},
	{
		"_id" : "WMHWxeymY4ATWLXjz",    
		"emails" : [ 
			{
				"address" : "[email protected]",
				"verified" : false
			}
		]
	}
];

var callback = function(d) {
	var emailAddresses = [];
	for (var i = 0; i < d.emails.length; i++) {
		emailAddresses.push(d.emails[i].address);
	}
	return emailAddresses;
};
var emails = users.map(callback);
var to = _.uniq(_.flatten(emails));

pre.innerHTML = JSON.stringify(to, null, 4);
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<pre id="pre"></pre>

Sign up to request clarification or add additional context in comments.

1 Comment

@KarinaL No worries, happy to help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.