How to prevent SparkPost from changing urls in emails? - node.js

I use SparkPost to send emails from my node.js app.
However, all links are converted to urls such as: http://go.sparkpostmail1.com/f/a/EgvUoS2LdGPzMx-AURKwZA~~/AABUGAA~/RgRZK0BSP0EIAGukLuGW3OxXA3NwY1gEAAAAAFkGc2hhcmVkQgoAAVK7SFdpNVEbUhFuaWNvbGFzQGR1cmFuZC5jaAlRBAAAAABEUWh0dHBzOi8vZGlzaGx5Lm1lbnUvZC9XYXNoaW5ndG9uL1JlZ2VudF9UaGFpL0Jhc2lsX0phZS81NjBmMzk5MmQ0YWUxNTAzMDBmZWZmMGIiLEcCe30
I've tried to disable the "click_tracking" like this (see code sample below), but it's still not working. does anyone have an idea to configure SparkPost to send the emails "as is"?
var sparky = new SparkPost(process.env.SPARKPOST_API_KEY, {"open_tracking": false, "click_tracking": false});
sparky.transmissions.send({transmissionBody: transmissionBody}, function (err, res) {
if (err) {
console.log('Whoops! Something went wrong in sendEmail');
console.log(err);
} else {
console.log('sendEmail sent!');
}
});

open and click tracking isn't set when you instantiate the SparkPostobject, it's done in the transmissionBody via the options key like so:
var SparkPost = require('sparkpost');
var sp = new SparkPost('<YOUR API KEY>');
sp.transmissions.send({
transmissionBody: {
options: {
open_tracking: false,
click_tracking: false
},
content: {
from: 'testing#sparkpostbox.com',
subject: 'Hello, World!',
html:'<html><body><p>Testing SparkPost - the world\'s most awesomest email service!</p></body></html>'
},
recipients: [
{address: '<YOUR EMAIL ADDRESS>'}
]
}
}, function(err, res) {
if (err) {
console.log('Whoops! Something went wrong');
console.log(err);
} else {
console.log('Woohoo! You just sent your first mailing!');
}
});
Additionally you can see examples for transmissions using node-sparkpost here:
https://github.com/SparkPost/node-sparkpost/tree/master/examples/transmissions
This particular examples includes the options key:
https://github.com/SparkPost/node-sparkpost/blob/master/examples/transmissions/send_transmission_all_fields.js

Variables quoted as {{ foo }} are escaped.
Variables quoted as {{{ foo }}} are treated as raw HTML.
https://developers.sparkpost.com/api/template-language/#header-html-escaping

Related

Node JS - nodemailer & imap-simple - Identify threads

(I feel sorry for my poor english, but i'll do my best !) :)
I'm trying to setup a local mailbox for a personnal project, and i'm trying to use imap-simple and nodemailer to do that.
I want to be able to identify a thread, when i send an e-mail.
Here's what i exactly want to do :
In my application, i'll be able to send an e-mail to a specific person (let's admit foo#bar.com)
When the mail is sent, a callback function will store mail content and subject in DB (for example, in a CRM app, i will store the sent mail which will be related to a specific record in my database).
The complex part is just after that :
When the person replies to this e-mail, i want using IMAP to identify that this person is answering to my previous mail, and then store it in DB too, also linked to the same record i used on my first e-mail.
I actually have this in a sandbox folder (For IMAP) :
var imaps = require('imap-simple');
var nodemailer = require('nodemailer');
var config = {
imap: {
user: 'catchall#xxxxxxxx.fr',
password: 'xxxxxxxx',
host: 'imap.gmail.com',
port: 993,
tls: true,
authTimeout: 3000
}
};
imaps.connect(config).then(function (connection) {
return connection.openBox('INBOX').then(function () {
var searchCriteria = [
'UNSEEN'
];
var fetchOptions = {
bodies: ['HEADER', 'TEXT'],
markSeen: false,
};
console.log('Passing there');
return connection.search(searchCriteria, fetchOptions).then(function (results) {
var subjects = results.map(function (res) {
return res.parts.filter(function (part) {
return part.which === 'HEADER';
})[0].body.subject[0];
});
console.log('BASE');
console.log(results[0]);
console.log('FIRST');
console.log(results[0].parts[0]);
console.log('SECOND');
console.log(results[0].parts[1]);
});
});
});
And here is the SMTP part :
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'catchall#xxxxxxxx.fr',
pass: 'xxxxxxxx'
}
});
const mailOptions = {
from: 'catchall#xxxxxxxx.fr', // sender address
to: 'xxxxxxxx#gmail.com', // list of receivers
subject: 'Subject of your email', // Subject line
html: '<p>Here is my test !</p>',// plain text body
headers: {
'collection': 'Pipelines',
'doc-ID': 'mydocid'
}
};
transporter.verify(function(error, success) {
if (error) {
console.log(error);
} else {
console.log("Server is ready to take our messages");
}
});
transporter.sendMail(mailOptions, function (err, info) {
if(err)
console.log(err)
else
console.log(info);
});
Here is a screen of what i want to be able to :
On IMAP, i'm getting exactly the information i want in console :
BASE
{ attributes:
{ date: 2019-12-05T16:53:07.000Z,
flags: [],
uid: 94,
modseq: '27800',
'x-gm-labels': [ '\\Important' ],
'x-gm-msgid': '1652099423356172171',
'x-gm-thrid': '1652099362185438260' },
x-gm-thrid allow me to identify a thread. Perhaps, i can't find this information in the nodemailer callback function :
Server is ready to take our messages
{ accepted: [ 'xxxxxxxxxxxxxxxxx#gmail.com' ],
rejected: [],
envelopeTime: 400,
messageTime: 819,
messageSize: 346,
response: '250 2.0.0 OK 1575566223 m3sm12955793wrs.53 - gsmtp',
envelope:
{ from: 'catchall#xxxxxxxxxx.fr',
to: [ 'xxxxxxxxxxxx#gmail.com' ] },
messageId: '<f93b3970-e17a-84b5-d0d1-ebb4fd6efe46#xxxxxxxxxx.fr>' }
Does anyone have an idea of how i could proceed ?
Thanks a lot btw !
Happy coding :)
For those who will read this post, here the answer, thanks to #arnt,
As #arnt said, there is for IMAP protocol, a reference attribute which is storing the previous message ID stored in results[0].parts[1] :
references: [ '<23df0af1-8ff1-0ffa-091e-a645a38e4a67#foobar.fr>' ],
'in-reply-to': [ '<23df0af1-8ff1-0ffa-091e-a645a38e4a67#foobar.fr>' ],
This one is also available when you send a message, in info :
envelope:
{ from: 'foobar#foobar.fr',
to: [ 'foobar#gmail.com' ] },
messageId: '<23df0af1-8ff1-0ffa-091e-a645a38e4a67#foobar.fr>' }
This way, we're able to correlate mail conversation.
Thanks a lot for help :)
Topic closed

how to send email using loop and update each record?

I have implemented nodemailer for sending emails. for email detail like email id, subject and text I have a table in the db. in that table I had a flag (new, processed)to get the list of new records so that I can send mail of new records
I am using for loop on the record list to send emails. the thing I want to know is once the mail is forwarded successfully I want to update the record flag in the db. I am using sequlize in node.js.
var WEBDialerList=[];
var WEBDialerListCount;
SqlObj.WEBDialer.findAll(
{
where: {
IsDeleted: 0,
Status: 'New'
}
}
)
.then(data => {
WEBDialerList = JSON.parse(JSON.stringify(data));
console.log("d.length")
console.log(WEBDialerList.length)
console.log("d.length")
if (WEBDialerList.length > 0) {
for (var i in WEBDialerList){//= 0; i < WEBDialerList.length; i++) {
WEBDialerListCount = i;
"use strict";
const nodemailer = require("nodemailer");
let transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: 'abc#gmail.com',
pass: '******'
}
});
var e = WEBDialerList[i].Email;
let mailOptions = {
from: '"ib ik" <ib.ik2093#gmail.com>',
to: e,
subject: "Test Email from Node.js",
text: " scheduler Hello, this is a test email. I have configured my gmail account in node.js to send emails. I am checking, is it configured correctly.",// plain text body
html: "<b> " + WEBDialerList[i].WEBDialerId + " scheduler Hello, this is a test email. I have configured my gmail account in node.js to send emails. I am checking, is it configured correctly.</b>" // html body
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
return console.log(error);
}
else {
console.log("Message sent1: ", info);
console.log(WEBDialerListCount)
transporter.close();
}
})
}
}
})
.catch(function (err) {
console.log(err)
});
In transporter.sendMail I just get it at the end of the loop so it is difficult for me to get what records needs to be updated.
A possibile solution can be:
[..]
// Move this declarations out is a good idea
const nodemailer = require("nodemailer");
let transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: 'foobar#gmail.com',
pass: 'foobar'
}
});
[..]
for (var i in WEBDialerList) {
[..]
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
sql.setFlag('errored') // pseudocode
} else {
sql.setFlag('processed') // pseudocode
transporter.close();
}
})
}
[..]
PS: remove your gmail credentials!
Please, async await instead of promises code look good and easy to read.
Here is the solution to your question.
Promis.all(
WEBDialerList.map(WEBDialer => {
let mailOptions = {
from: '"ib ik" <ib.ik2093#gmail.com>',
to: WEBDialer.email,
subject: "Test Email from Node.js",
text: " scheduler Hello, this is a test email. I have configured my gmail account in node.js to send emails. I am checking, is it configured correctly.",// plain text body
html: "<b> " + WEBDialer.WEBDialerId + " scheduler Hello, this is a test email. I have configured my gmail account in node.js to send emails. I am checking, is it configured correctly.</b>" // html body
};
return new Promise((resolve, reject) => {
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
reject(error)
} else {
console.log("Message sent1: ", info);
console.log(WEBDialerListCount)
// Update user here
transporter.close();
resolve()
}
})
})
})
)
Please make the necessary changes according to your requirements.
DO let me know if you need more help or anything you want to ask.
I hope you like it :)

AWS-SES Email address is not verified. Gmail account

I have try to send email using AWS-SES when new customer registration.
But i got some error like this
Email address is not verified. The following identities failed the check in region US-EAST-1: mathuk22#gmail.com (Request ID: 2278b8eb-544e-11e9-bab8-536962476bb7)
Note: Am not verify mathuk22#gmail.com email id in my AWS-SES
Without verify email how can i send email ?
exports.emailSend = (req, res) =>{
var htmlContentData = req.body.htmlContentData; // html content
var htmlSubjectData = req.body.htmlSubjectData; // subject
var params = {
Destination: {
//BccAddresses: [],
//CcAddresses: [],
ToAddresses: ["mathuk22#gmail.com"]
},
Message: {
Body: {
Html: {
Charset: "UTF-8",
Data: htmlContentData // html mail content
},
Text: {
Charset: "UTF-8",
Data: "Hello Charith Sample description time 1517831318946"
}
},
Subject: {
Charset: "UTF-8",
Data: htmlSubjectData // html mail subject
}
},
ReplyToAddresses: [],
Source: "source#example.com",
};
ses.sendEmail(params, function(err, data) {
if (err)
console.log(err, err.stack);
else
res.send(data);
});
}
Initially AWS puts your account in Sandbox where you need to verify the recipient email address, you need to contact AWS Support and ask them to move your Account to production, once account is in production and limits have been increased, you don't need to verify recipient "To" address. It doesn't cause additional cost.
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html
Do the following steps to verify email on AWS:

AWS SES Nodejs SDK - email with dash bounces

I'm using the aws nodejs SES sdk and emails with to address with something like 'email#host-name.com' appear to all be bouncing even though they exist. Works for other emails without the dash.
I looked and the emails do look like they end up as query parameters, do I just need to individually url encode them? I dont get an error anymore, but I dont have any email address to test with.
var params = {
Destination: {
ToAddresses: [
'email#host-name.com'
]
},
Message: {
Body: {
Html: {
Data: body
}
},
Subject: {
Data: subject
}
},
Source: fromAddress
};
ses.sendEmail(params, function (err, data) {
if (err){
console.log(err, err.stack);
} else {
//sent
}
});
This ended up not having to do with the dash. The emails were bouncing because an AWS email service IP was blacklisted.

Sending emails using Mailgun with NodeMailer package

A couple of days ago I realized that Google has changed the security of gmail accounts, particularly for the possibility of sending emails from applications. After Googling around for a while I couldn't find a fix for it.
So, I resorted to using Mailgun. I created an account and had it enabled with Business verification. However, I still can't send emails. I keep getting an error about the requested URL not being found.
I am suspecting that since I haven't set up a domain yet, it is not picking the mailgun domain it provided by default. Could someone show me how to test sending emails using Mailgun from NodeMailer indicating the sandbox name provided by mailgun.
thanks in advance
José
var nodemailer = require('nodemailer');
// send mail with password confirmation
var transporter = nodemailer.createTransport( {
service: 'Mailgun',
auth: {
user: 'postmaster#sandboxXXXXXXXXXXXXXXXX.mailgun.org',
pass: 'XXXXXXXXXXXXXXXX'
}
});
var mailOpts = {
from: 'office#yourdomain.com',
to: 'user#gmail.com',
subject: 'test subject',
text : 'test message form mailgun',
html : '<b>test message form mailgun</b>'
};
transporter.sendMail(mailOpts, function (err, response) {
if (err) {
//ret.message = "Mail error.";
} else {
//ret.message = "Mail send.";
}
});
I created the Nodemailer transport for mailgun.
Here it how it works.
You install the package with npm install as you would do with any package, then in an empty file:
var nodemailer = require('nodemailer');
var mg = require('nodemailer-mailgun-transport');
// This is your API key that you retrieve from www.mailgun.com/cp (free up to 10K monthly emails)
var auth = {
auth: {
api_key: 'key-1234123412341234',
domain: 'sandbox3249234.mailgun.org'
}
}
var nodemailerMailgun = nodemailer.createTransport(mg(auth));
nodemailerMailgun.sendMail({
from: 'myemail#example.com',
to: 'recipient#domain.com', // An array if you have multiple recipients.
subject: 'Hey you, awesome!',
text: 'Mailgun rocks, pow pow!',
}, function (err, info) {
if (err) {
console.log('Error: ' + err);
}
else {
console.log('Response: ' + info);
}
});
Replace your API key with yours and change the details and you're ready to go!
It worked me, when I added the domain also to the auth object (not only the api_key). Like this:
var auth = {
auth: {
api_key: 'key-12319312391',
domain: 'sandbox3249234.mailgun.org'
}
};

Resources