The code below is my sendgrid helper function
presently, this is what comes up as the sender name "info" which is conned from infogmail.com. . i would like to add a custom name. i have read the docs but i have not seen a solution to my problem. all the solutions i saw was for python
const msg = {
to: email,
from: `${SENDER_EMAIL}`,
fromname: FROM_NAME,
subject: "Thanks for the Gift",
html: `${html(name, SENDER_EMAIL, SENDER_NAME)}`,
};
sgMail
.send(msg)
.then(() => {
console.log("Email sent");
})
.catch((error) => {
console.error(error);
});
};```
You can in this way:
sendgrid.send({
to: 'you#yourdomain.com',
from: {
email: 'example#example.com',
name: 'Sender Name'
},
subject: 'Hello World',
text: 'My first email through SendGrid'
});
Related
In my application I have a few email campaigns that get sent out roughly about once a month. Two of my email campaigns have a mailing list that consist of roughly 50+ recipients, whereas the other one can have as many as 800+. I ran into this issue recently where I was trying to send the large email campaign and towards the end when I got this error: Error: too many login attempts. Please try again later.. After doing some research it looks like it would be best if I used the pooling parameter in nodemailer's options when creating a transport.
I've looked on their site regarding this matter but it's a very vague section and doesn't really show how it can be used in an application. Is it as simple as just adding pool: true to my transport options? Or is their more to it than that. I'm using gmail's smtp and I know that they rate limit the amount of emails that can be sent out at once so having a pool to do them in parallel might cause issues.
Here is what my email campaign file looks like:
.
.
.
import { FormatEmailReport } from '../imports/Utilities/EmailReports';
import { smtpTransport } from '../imports/Utilities/EmailService';
import performance from 'perf_hooks';
export const SendCampaign = () => {
try {
let date = new Date();
date.setMonth(date.getMonth() - 4); // get 4 months prior to today
date= ConvertDateToYMD(date);
getEmailList(date).then(email_list => {
FormatEmailsToSend(email_list);
}).catch(e => {
console.log('ERROR: micro.getEmailList: ' + e);
})
} catch (e) {
console.log('ERROR: micro.SendCampaign: ' + e);
}
}
export const FormatEmailsToSend = async (email_list) => {
try {
let accepted = [];
let rejected = [];
let t0 = performance.performance.now();
for(let pbid in email_list){
let customer = email_list[pbid][0];
let to = customer.Email;
let txt = `
<div width="100%">
<p>Hi ${customer.Name},</p>
<p>this is a courtesy email from the server</p>
</div>
`
let result = await SendEmail("myemail.com", to, "myemail.com", `Email Subject`, txt, attachment, customer.CustomerID, customer.PBID);
result.Status == 'accepted' ? accepted.push(result) : rejected.push(result);
}
let t1 = performance.performance.now();
let execution_time = (t1-t0)/1000;
FormatEmailReport(accepted,rejected,execution_time,`Email Report`);
} catch (e) {
console.log('ERROR: micro.FormatEmailsToSend: ' + e);
}
}
export const SendEmail = (from, to, bcc, subject, msg, attachments, customer_id, pbid) => {
return new Promise(async (resolve,reject) => {
try {
smtpTransport.sendMail({ //email options
from: from, // sender address. Must be the same as authenticated user if using Gmail.
to: to,
bcc: bcc,
subject: subject, // subject
html: msg, // body
attachments: attachments
}, function (error, res) {
if (error) {
console.log(`Email FAILED for address: ${to}! ERROR: ${error}`);
reject({CustomerID: customer_id, PBID: pbid, Email: to, Status: 'rejected', Msg: error})
} else {
resolve({CustomerID: customer_id, PBID: pbid, Email: to, Status: 'accepted', Msg: res.response})
}
smtpTransport.close();
});
} catch (e) {
console.log('ERROR: micro.SendEmail: ' + e);
reject({CustomerID: customer_id, PBID: pbid, Email: to, Status: 'rejected', Msg: e})
}
})
}
Here is my EmailService file:
import nodemailer from 'nodemailer';
import env from '../../../env.config.json';
const smtpTransport = nodemailer.createTransport({
service: env.SalesEmail.SERVICE, // "Gmail"
auth: {
user: env.SalesEmail.AUTH.USER,
pass: env.SalesEmail.AUTH.PASS
}
});
module.exports = {smtpTransport}
If anyone has any ideas on how I might be able to use nodemailer's pool instead of a single connection that would be great. TIA!
I'm using Node js, nodemailer and firebase functions in my application.
I've a list of emails in an array emailConfig
const emailConfig = [
{
"name": "A",
"Email": "A#gmail.com"
},
{
"name": "B",
"Email": "B#gmail.com"
}
];
So I need to send an email to all in emailConfig.
So I'm doing this,
function sendMail() {
emailConfig.forEach(email => {
const mailOptions = {
from: 'abc#gmail.com',
to: email.Email,
subject: 'Sending Email using Node.js',
text: `That was easy! ${email.name}`,
attachments: [
{
filename: `${email.name}_KeyMetrics.xlsx`,
path: `${tempath}/${email.name}_KeyMetrics.xlsx`
},
{
filename: `${email.name}_MandatoryCourses.xlsx`,
path: `${tempath}/${email.name}_MandatoryCourses.xlsx`
},
]
};
return transporter.sendMail(mailOptions, (erro, info) => {
if (erro) {
return res.send(erro.toString());
}
return res.send('Sended');
});
});
}
I'm calling the sendMail() on request.
Issue is, I'm getting multiple emails and finally error in terminal Error: Function timed out.
sendMail() is not getting finished. What i'm doing wrong here ?
you cannot call send() after its first call on the single response (assuming your res is a Response socket).
Array.forEach is synchronous, your callbacks will no be handled properly.
Function in forEach is does not return any result. So since you call return keyword, your thread stop at there. Try to remove return keyword like this:
function sendMail() {
emailConfig.forEach(email => {
const mailOptions = {
from: 'abc#gmail.com',
to: email.Email,
subject: 'Sending Email using Node.js',
text: `That was easy! ${email.name}`,
attachments: [
{
filename: `${email.name}_KeyMetrics.xlsx`,
path: `${tempath}/${email.name}_KeyMetrics.xlsx`
},
{
filename: `${email.name}_MandatoryCourses.xlsx`,
path: `${tempath}/${email.name}_MandatoryCourses.xlsx`
},
]
};
//remove return below
transporter.sendMail(mailOptions, (erro, info) => {
if (erro) {
return res.send(erro.toString());
}
return res.send('Sended');
});
});
}
Or if you need an array of result. Try .map() prototype instead:
function sendMail() {
emailConfig.map(email => { //replace forEach by map
const mailOptions = {
from: 'abc#gmail.com',
to: email.Email,
subject: 'Sending Email using Node.js',
text: `That was easy! ${email.name}`,
attachments: [
{
filename: `${email.name}_KeyMetrics.xlsx`,
path: `${tempath}/${email.name}_KeyMetrics.xlsx`
},
{
filename: `${email.name}_MandatoryCourses.xlsx`,
path: `${tempath}/${email.name}_MandatoryCourses.xlsx`
},
]
};
return transporter.sendMail(mailOptions, (erro, info) => {
if (erro) {
return res.send(erro.toString());
}
return res.send('Sended');
});
});
}
I'm trying to write the back-end for a foodie review app. The problem I'm having is at the PUT method, when I'm trying to modify a certain post, the req.body does not contain the imageUrl if I do not modify the URL . When req.file exists (the image), then everything works, because I set up a new imageURL. For some reasons I get the userId, description and everything else back except the imageUrl.
Here is my code:
exports.modifySauce = (req, res, next) => {
let sauce = new Sauce({ _id: req.params._id });
if (req.file) {
const url = req.protocol + '://' + req.get('host');
req.body.sauce = JSON.parse(req.body.sauce);
sauce = {
_id: req.params.id,
name: req.body.sauce.name,
manufacturer:req.body.sauce.manufacturer,
mainPepper:req.body.sauce.mainPepper,
description: req.body.sauce.description,
imageUrl: url + '/images/' + req.file.filename,
heat: req.body.sauce.heat,
userId: req.body.sauce.userId
};
} else {
sauce = {
_id: req.params.id,
name: req.body.name,
manufacturer:req.body.manufacturer,
mainPepper:req.body.mainPepper,
description: req.body.description,
imageUrl: req.body.imageUrl,
heat: req.body.heat,
userId: req.body.userId
};
}
Sauce.updateOne({_id: req.params.id}, sauce).then(
() => {
res.status(201).json({
message: 'Sauce updated successfully!'
});
}
).catch(
(error) => {
res.status(400).json({
error: error
});
}
);
};
More information, in my Repo.
And here is the front end repo.
https://github.com/OpenClassrooms-Student-Center/nem-stack-hot-takes
I am using mailchimp-api-v3 to submit a form.
This list only has three fields, which are FNAME, EMAIL, and COMPANY.
const Mailchimp = require('mailchimp-api-v3');
const mailchimp = new Mailchimp(myMailchimpAPI);
mailchimp.post(`/lists/${myListId}/members`, {
FNAME: 'Jack',
EMAIL: 'jack#example.com',
COMPANY: 'Apple'
})
.then(res => console.log(res))
.catch(err => console.log(err));
This gives me error:
[ { field: 'email_address', message: 'This value should not be blank.'
} ] }
I figured out after reading the Mailchimp API document.
I have to add another two fields email_address and status which are required. Then move the rest of form fields under merge_fields.
The correct code is
const Mailchimp = require('mailchimp-api-v3');
const mailchimp = new Mailchimp(myMailchimpAPI);
mailchimp.post(`/lists/${myListId}/members`, {
email_address: 'jack#example.com',
status: 'subscribed',
merge_fields: {
FNAME: 'Jack',
EMAIL: 'jack#example.com',
COMPANY: 'Apple'
}
})
.then(res => console.log(res))
.catch(err => console.log(err));
It was hard for me to find a simple demo online. Hope this helps for future people.
I have this code inside a post route:
The first one is to alert my when a user register in my site:
sendgrid.send({
to: "my#email.com",
from: "myother#email.com",
subject: "[ALERT] " + req.body.eventDate,
html: "SOME HTML",
},
function(err, json) {
if (err) {
return console.error(err);
}
else {
next();
}
});
The next one is a confirmation email send to the new register member:
sendgrid.send({
to: req.body.email,
from: "my#email.com",
subject: "[CONFIRM] register" + req.body.eventDate,
html: "SOME HTML",
},
function(err, json) {
if (err) {
return console.error(err);
}
else {
next();
}
});
Is working 100%, but this is not a good practice, there is so much duplicate. Can i DRY this? If so, howww??
Thanks!!!
You can create a function which can perform the operation of sending emails using sendgrid like this,
function sendEmail(options) {
sendgrid.send(options,
function(err, json) {
if (err) {
return console.error(err);
}
else {
next();
}
});
}
And then you can utilise above created function as following,
For sending registration email
var registrationEmailOptions = {
to: "my#email.com",
from: "myother#email.com",
subject: "[ALERT] " + req.body.eventDate,
html: "SOME HTML",
}
sendEmail(registrationEmailOptions);
For sending confirmation email.
var confirmationEmailOptions = {
to: req.body.email,
from: "my#email.com",
subject: "[CONFIRM] register" + req.body.eventDate,
html: "SOME HTML",
}
sendEmail(confirmationEmailOptions);