how to send mails using nodemailer after a sucessful purchase in stripe - node.js

i'm trying to send an email after successfully making a payment , but i'm find it hard to add my nodemailer code in stripe,
this is my stripe code
router.post("/pay", verifyToken, (req, res) => {
let totalPrice = Math.round(req.body.totalPrice * 100);
stripe.customers
.create({
email: req.decoded.email
})
.then(customer => {
return stripe.customers.createSource(customer.id, {
source: "tok_visa"
});
})
.then(source => {
return stripe.charges.create({
amount: totalPrice,
currency: "usd",
customer: source.customer
});
})
.then(async charge => {
console.log("charge>", charge);
let order = new Order();
let cart = req.body.cart;
cart.map(product => {
order.products.push({
productID: product._id,
quantity: parseInt(product.quantity),
price: product.price
});
});
order.owner = req.decoded._id;
order.estimatedDelivery = req.body.estimatedDelivery;
await order.save();
res.json({
success: true,
message: "Successfully made a payment"
});
})
.catch(err => {
res.status(500).json({
success: false,
message: err.message
});
});
});
this is my email template
var emailTemplate = `Hello ${req.decoded.name}, \n
thank you for your order! \n
Engraving: ${newCharge.description} \n
Amount: ${newCharge.amount / 100 } \n
Your full order details are available at ecart.io/#/order-complete/${
charge.id
} \n
For questions contact your_support_email#gmail.com \n
Thank you!`;
let mailTransporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "a#gmail.com",
pass: "sq"
}
});
let details = {
from: "a#gmail.com",
to: `${req.decoded.email}`,
subject: "shipping",
text: emailTemplate
};
mailTransporter.sendMail(details, err => {
if (err) {
console.log(err);
} else {
console.log("email sent");
}
});
tried adding it in my .then function but i'm not getting a good response I expected either an error message or the email sent to be logged but that is not happening.

do these
.then(source => {
return stripe.charges.create({
amount: totalPrice,
currency: "usd",
customer: source.customer
},
function(err, charge) {
if (err) {
console.log(err);
} else {
var emailTemplate = `Hello ${req.decoded.name}, \n
thank you for your order! \n
Amount: ${charge.amount / 100} \n
Your full order details are available at ecart.io/#/order-complete/${
charge.id
} \n
For questions contact your_support_email#gmail.com \n
Thank you!`;
let mailTransporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "a#gmail.com",
pass: "sq"
}
});
let details = {
from: "a#gmail.com",
to: `${req.decoded.email}`,
subject: "shipping",
text: emailTemplate
};
mailTransporter.sendMail(details, err => {
if (err) {
console.log(err);
} else {
console.log("email sent");
}
});
}
},
);
})

Related

mailgun.messages is not a function

I am trying to get my e-commerce web app to send emails on purchasing but when I try to pay for things I get the mailgun.messages is not a function I've reverted changes and re coded it twice but this is a different error I'm not sure how to resolve this. Is there another way to use mailgun's api? Here is the code below:
orderRoutes.js:
orderRouter.put(
"/:id/pay",
isAuth,
expressAsyncHandler(async (req, res) => {
const order = await Order.findById(req.params.id).populate(
"user",
"email firstName"
);
if (order) {
order.isPaid = true;
order.paidAt = Date.now();
order.paymentResult = {
id: req.body.id,
status: req.body.status,
update_time: req.body.update_time,
email_address: req.body.email_address,
};
const updateOrder = await order.save();
mailgun.messages().send(
{
from: "Sales <sales#cocoTiCosmetics.com>",
to: `${order.user.firstName} <${order.user.email}>`,
subject: `New Order ${order._id}`,
html: payOrderEmailTemplate(order),
},
(error, body) => {
if (error) {
console.log(error);
} else {
console.log(body);
}
}
);
res.send({ message: "Order Paid", order: updateOrder });
} else {
res.status(404).send({ message: "Order Not Found" });
}
})
);
utils.js
export const mailgun = () =>
mg({
apiKey: process.env.MAILGUN_API_KEY,
domain: process.env.MAILGUN_DOMAIN,
});

how to send email confirmation in nodejs and SendGrid?

I have a NodeJs and ReactJs project, where a user can register and after the user is registered they will get an email to confirm their account.
so now when I register the email is working well. but it works with an email that I set in like this.
function sendMail() {
const msg = {
to: "someoneemail#gmail.com",
from: "myemail#gmail.com",
subject: "a subject",
text: "some text herer",
html: "<strong>and easy to do anywhere, even with Node.js</strong>",
};
sgMail
.send(msg)
.then(() => {
console.log("Email sent");
})
.catch((error) => {
console.error(error);
});
}
module.exports = { sendMail };
I need to remove this to: "someoneemail#gmail.com" a*
nd instead set the user email, the user who to register on this
system
and instead of text: i have to send the token.
so here is the registration part:
router.post("/register", async (req, res) => {
const { fullName, emailAddress, password } = req.body;
const user = await Users.findOne({
where: {
[Op.and]: [{ fullName: fullName }, { emailAddress: emailAddress }],
},
});
if (user) {
res.status(400).send({
error: `some message.`,
});
} else {
bcrypt
.hash(password, 10)
.then((hash) => {
return {
fullName: fullName,
emailAddress: emailAddress,
password: hash,
isVerified: false,
};
})
.then((user) => {
const token = TokenGenerator.generate();
const creator = Verifications.belongsTo(Users, { as: "user" });
return Verifications.create(
{
token,
user: user,
},
{
include: [creator],
}
);
})
.then((verification) => {
console.log("verification", verification);
sendMail();
})
.then(() => res.json("User, Successmessage "));
}
});
but the codes are not in the same file.
Just add the parameters you need to the sendMail function:
function sendMail(user, token) {
const msg = {
to: user.emailAddress,
from: "myemail#gmail.com",
subject: "Sending with SendGrid is Fun",
text: token,
html: `<strong>${token}</strong>`,
};
sgMail
.send(msg)
.then(() => {
console.log("Email sent");
})
.catch((error) => {
console.error(error);
});
}
Also inject the needed parameters in the promises:
.then(async (user) => {
const token = TokenGenerator.generate();
const creator = Verifications.belongsTo(Users, { as: "user" });
await Verifications.create(
{
token,
user: user,
},
{
include: [creator],
}
);
return {user, token};
})
.then(({user, token}) => {
sendMail(user, token);
})
.then(() => res.json("User, Successmessage "));

Node.JS server crashes

I have a problem, I'm creating app where you can buy tickets for cultural events. The problem is the server crashes when I try buying tickets when there is no tickets left. It gives this message: "[nodemon] app crashed - waiting for file changes before starting...".
try {
const { email, firstName, lastName, phoneNumber } = req.body;
const id = req.query.id;
let eventFound: any;
const event = await Event.findById(id, (error, result) => {
if(!error) eventFound = result;
else throw new Error(error.message);
});
Ticket.find({ eventId: event?.id }, (error, tickets) => {
if (!error) {
if (event?.toJSON().maxTicketsAmount - 1 < tickets.length) {
throw new Error("Not enough tickets");
}
}
});
const paymentIntent = await stripe.paymentIntents.create({
amount: eventFound.ticketPrice, // NEEDS TO BE ABOVE SOME VALUE!!!!!!!
currency: "pln",
payment_method_types: ["card"],
receipt_email: email,
metadata: { integration_check: "accept a payment" },
});
console.log(paymentIntent);
const ticket = new Ticket({
email: email,
firstName: firstName,
lastName: lastName,
phoneNumber: phoneNumber,
eventId: eventFound.id,
purchaseDate: new Date(),
});
ticket.save((error) => {
if (error) {
throw new Error(error.message);
}
});
res.status(200).send(paymentIntent.client_secret);
} catch (error) {
res.status(500).json({ statusCode: 500, message: error.message });
}
the issue is because you are throwing the error:
Ticket.find({ eventId: event?.id }, (error, tickets) => {
if (!error) {
if (event?.toJSON().maxTicketsAmount - 1 < tickets.length) {
throw new Error("Not enough tickets");
}
}
and then it is getting "catched" in the try/catch statement. As a result you are manually crashing the server. Instead you should:
Ticket.find({ eventId: event?.id }, (error, tickets) => {
if (!error) {
if (event?.toJSON().maxTicketsAmount - 1 < tickets.length) {
res.status(404).send("no more tickets")
}
}

nodemailer sendEmail doesn't wait in Node.js

When I make a request to my endpoint I need to get a successful response only if the email is sent! otherwise, it should throw an error:
myendpoint.js
router.post("/", upload.none(), async (req, res) => {
try {
let body = JSON.parse(req.body.contact);
await getDb("messages").insertOne({
name: body.name,
email: body.email,
phone: body.phone,
subject: body.subject,
message: body.message,
});
await sendEmail(body);
res.send(
JSON.stringify({
success: true,
msg: "Message has been sent successfully",
})
);
} catch (err) {
res.send(JSON.stringify({ success: false, msg: err }));
}
});
sendEmail.js
const sendEmail = async function (props) {
const transporter = nodemailer.createTransport({
service: process.env.EMAIL_SERVICE,
host: process.env.EMAIL_HOST,
auth: {
user: process.env.EMAIL_FROM,
pass: process.env.EMAIL_PASS,
},
});
const mailOptions = {
from: process.env.EMAIL_FROM,
to: process.env.EMAIL_TO,
name: props.name,
email: props.email,
phone: props.phone,
subject: props.subject,
text: props.message,
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
throw new Error("Message did Not send!");
}
});
};
the problem is before "await sendEmail(body);" ends and i get the error, i get the "Message has been sent successfully" and then server crashes!
what am i missing?
Check document function sendMail from nodemailer at here
If callback argument is not set then the method returns a Promise object. Nodemailer itself does not use Promises internally but it wraps the return into a Promise for convenience.
const sendEmail = async function (props) {
const transporter = nodemailer.createTransport({
service: process.env.EMAIL_SERVICE,
host: process.env.EMAIL_HOST,
auth: {
user: process.env.EMAIL_FROM,
pass: process.env.EMAIL_PASS,
},
});
const mailOptions = {
from: process.env.EMAIL_FROM,
to: process.env.EMAIL_TO,
name: props.name,
email: props.email,
phone: props.phone,
subject: props.subject,
text: props.message,
};
// remove callback and function sendMail will return a Promise
return transporter.sendMail(mailOptions);
};
Hello you can change your Transporter sendMail to :
return await transporter.sendMail(mailOptions);
Or You can Use Promise.
const handler = async ({ subject, name, body, contact }) => {
const transporter = nodemailer.createTransport({
service: "zoho",
// Disable MFA here to prevent authentication failed: https://accounts.zoho.com/home#multiTFA/modes
// ********************* OR *****************
// set up Application-Specific Passwords here: https://accounts.zoho.com/home#security/device_logins
auth: { user: process.env.NEXT_PUBLIC_EMAIL_ADDRESS, pass: process.env.NEXT_PUBLIC_EMAIL_PASSWORD },
});
return transporter
.sendMail(mailOptions({ subject, name, body, contact }))
.then((info) => {
if (process.env.NODE_ENV !== "production") console.log("Email sent: " + info.response);
return true;
})
.catch((err) => {
if (process.env.NODE_ENV !== "production") console.log("error sending mail", err);
return false;
});
};

how to send mail with data that data from database using nodejs?

this is my code: i am getting perfect output in postman.but i want the output to send through my mail.In this code var result i am getting error i cannot able to get the responses.
var startBroadcasting = function (req, res) {
authToken = req.headers.authorization;
userAuthObj = JSON.parse(UserAuthServices.userAuthTokenValidator(authToken));
var todayDate = new Date();
var expireDate = new Date(userAuthObj.expire_date);
tokenOK = TokenValidator.validateToken(userAuthObj.user_id, authToken).then(function (userSessions) {
if (userSessions.length === 1) {
if (expireDate >= todayDate) {
template_id = req.params.id;
image_id = req.params.img_id;
TemplateController.findById(template_id, {
attributes: {
exclude: ['created_by', 'created_on', 'updated_by', 'updated_on']
},
include: [{
attributes: {
exclude: ['created_by', 'created_on', 'updated_by', 'updated_on']
},
model: Broadcasting,
where: {
id: image_id,
}
},
]
}
).then(function (templatefindByid) {
BccSetting.findAll({
where: {
template_id: template_id
}
}).then(bccSettings => {
res.status(200).json({
id: templatefindByid.id,
name: templatefindByid.name,
template_images: templatefindByid.template_images,
bcc_settings: bccSettings,
})
}).catch(err => {
console.log(err);
res.status(404).json({
message: ' not found...'
});
});
}).catch(function (err) {
console.log(err);
res.status(404).json({
message: 'not found...'
});
});
} else {
res.status(401).json({
message: 'Not ...'
});
}
} else {
res.status(401).json({
message: 'Expired...'
});
}
}).catch(function (err) {
res.status(401).json({
message: 'Expired...'
});
});
var result = "Hi " + template_images.client_name + "!We are pleased to inform you that " + template_images.client_name + " newschannel streaming has been stopped sucessfully on " +template_images.destination_type + "" +
"" +
"This email was sent from a notification-only address that cannot accept incoming email. Please do not reply to this message.";
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
auth: true,
active: true,
secure: true,
requireTLS: true,
auth: {
user: 'trans#gmail.com',
pass: 'wertyy'
}
});
let mailOptions = {
from: 'trans#gmail.com',
to: 'wwww#gmail.com',
bcc: bcc_setting.bcc_setting,// here i want bcc setting data
subject: 'yvnuyybymyed',
html: 'result'
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log("mail not sent" + error.message);
}
console.log('success');
});
};

Resources