Send hyperlinks in email body using AWS SES in Node.js - node.js

I am using the AWS.SES (simple email service) kit in my Node.js Lambda function.
I can send emails just fine, but if I try to include a simple hyperlink in the email, it displays just plain text instead of a clickable hyperlink.
This is the code I'm using to send the email.
function sendVerificationEmail(userinfo, vKey, after) {
var params = {
Destination: {
ToAddresses: [userinfo.email]
},
Message: {
Body: {
Html: {
Charset: "UTF-8",
Data: "<html><body>Hey " + userinfo.name + ", <a href='https://s3.amazonaws.com/xxxx/xxxx.html?v=" + vKey + "'>Click here to validate this email address.</a></body></html>"
},
Text: {
Charset: "UTF-8",
Data: "Hey " + userinfo.name + ",\n\nOpen this link in your web browser to validate this email address:\nhttps://s3.amazonaws.com/xxxx/xxxx.html?v=" + vKey
}
},
Subject: { Data: "Scheduler - Verify Your Email Address" }
},
Source: "xxxx#gmail.com"
};
ses.sendEmail(params, function(err, data) {
after(err, data);
});
}
As you can see in the HTML, I have included an <a> tag. However, The link is displayed as unclickable plaintext in the email.
Edit: Gmail's "Show Original" feature displays the following:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
Hey TestName,
Open this link in your web browser to validate this email address:
https://s3.amazonaws.com/xxxx/xxxx.html?v=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
---------------------------------------------------
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 7bit
<html><body>Hey TestName, <a href='https://s3.amazonaws.com/xxxx/xxxx.html?v=xxxxxxxxxxxxx'>Click here to validate this email address.</a></body></html>

If you observe the raw email contents you will observe that it misses the = sign between in href=<link>. This is because the '=' symbol is used as a line break in the smtp protocol messages(I think).
Anyways, the way to fix this is to add the unicode for the '=' symbol which is U+003D
Try this:-
${text}
The =3D is interpreted as the = symbol and the content encoding is done correctly.

Related

Sent html email using gmail API, it appears in "chinese" on apple mail client

I am sending emails using the Gmail NodeJS API using these code snippet (leaving auth out of it)
const headers: any = {
'To': event.to,
'Subject': event.subject,
"Content-Type": "text/html; charset='UTF-8'",
"Content-Transfer-Encoding": "base64"
}
let email = ''
for (let header in headers) {
email += header += ": " + headers[header] + "\r\n";
}
email += "\r\n" + event.body;
const theMessage = {
'userId': "me",
'resource': {
'raw': _btoa(unescape(encodeURIComponent(email))).replace(/\+/g, '-').replace(/\//g, '_')
}
}
const auth = new google.auth.OAuth2(
webAppClientId, this.clientSecret, "https://docs-n-data......");
const gmail = google.gmail({version: 'v1', auth})
gmail.users.messages.send(theMessage)
The email renders correctly on most email clients, except the ios email client on iphone. It looks like "chinese" in that client. Please see the attached image, following the suggestion by #DalmTo:
Some articles on the web hint that this might be due to the email being interpreted as UTF-16 instead of UTF-8, but none of them explain what to do.
I am trying to state that the encoding is UTF-8 in the above code, so am not sure whats wrong. Please help, thanks!
Update Maybe the content of the email body is important. The content comes from this template:
const emailBody = `<html>
<body>
<p>Hi {{Customer.First name}},</p>
<p>Your booking is confirmed for {{Date}} at {{Time}} and we have charged you the
amount of £{{Paid}}</p>
<p>Your booking reference is {{Booking number}}.</p>
<p>Use this link to cancel your booking, should you wish to.</p>
<p>Use this link to amend your booking, should you wish to.</p>
</body>
</html>`
Update 2 I changed the template for the email to:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<p>Hi {{Customer.First name}},</p>
<p>Your booking with The Smart Wash Ltd is confirmed for {{Date}} at {{Time}} and we have charged you the
amount of £{{Paid}}</p>
<p>Your booking reference is {{Booking number}}.</p>
</body>
</html>
And now I get this rendering on iphone mail client. On the ipad mail client and gmail, it renders correctly:
When I view the same email in gmail, and "Show original", I see this:
Not sure who or what is putting the text/plain version in there, but including this detail in case it helps.
I setted "Content-Transfer-Encoding": "8bit" and it worked for me!

Base64 encoded image sent using sendgrid not displayed in mails

I am trying to send a logo image in the HTML using sendGrid mailing service. I went through a lot of articles and tried a lot but still could not figure out on how to display inline image using content_id.
I went through following links but still could not make it work:
[Link1][1]: https://sendgrid.com/blog/embedding-images-emails-facts/
[Link2][2]: https://github.com/sendgrid/sendgrid-nodejs/issues/841
Few of the answers suggest to add image as a base64 string in HTML but that does not work with few web mailing clients.
Here is my code:
`
try
{
const msg = {
to: `${customerData.raw[0].invoicemail}`, // List of receivers email address
from : 'xxxx#xxx.com',
subject: `${subject}`, // Subject line
html: emailData, // HTML body content
attachments:
[
{filename:`${filename}`,content:invoice,type:"application/pdf"},
{filename:'logo.jpg',content:logoImageData,content_id:'logo',type:"image/jpg",disposition:"inline"}
],
}
sgMail.send(msg)
//return this.mailerService.sendEmail(msg)
}
catch
{
return false
}`
And here is the HTML block:
<img src = "content_id:logo" alt = "Logo Image" width=140 height=20>
Also, the image is being received as an attachment but is not displayed.
Sorry for the very late reply, I've also had trouble getting my image to display using SendGrid.
#Abhijeet, have you tried replacing src = "content_id:logo" with src="cid:logo"?
For other beginners, like myself, using SendGrid I will include the other steps that #Abhijeet already has done.
Upload and convert your image file to base64 (we'll call this logoImageData).
We want to replace the beginning of the base64 encoded image string using String.prototype.replace().
export const cleanLogoImageData = logoImageData.replace('data:image/jpeg;base64,' , '')
Now, in the attachments for mail data for SendGrid, you need to add these to your object: filename, content, contentType, content_id, and disposition.
const msg = {
attachments: [
{
filename: "logo.jpg",
content: cleanLogoImageData,
contentType: "image/jpeg",
content_id: "logo",
disposition: "inline",
},
],
}
content_id and disposition: "inline" are what got my logo to show.
Finally, in the html file holding your <img />, you must set the src as cid:logo or whatever your content_id is. And moreover, it's recommended to add align="top" and display: block in your img tag for better and consistent cross-platform email display of the image.
<img align="top"
style="display: block"
src="cid:logo"
alt="company logo"
/>

while sending mail using gmail api html part is also going along with content instead of content

Here is the piece of code I wrote in node js:
function makeBody(to, from, subject, message) {
let str = [
"to: ", to, "\n",
"from: ", from, "\n",
"subject: ", subject, "\n\n",
message,
].join('');
return str;
}
let raw = makeBody("dinesh.kumar#gmail.com", "dinesh.kumar#gmail.com",
"Test mail", "Everything is fine");
const userId = 'me'; // Please modify this for your situation.
let option = {
url: "https://www.googleapis.com/upload/gmail/v1/users/" + userId + "/messages/send",
method: 'POST',
headers: {
'Authorization': `Bearer ${req.query.access_token}`,
'Content-Type': 'message/rfc822',
},
body: raw,
};
When I am sending mail with html content as I am using some editor in front-end part. In the mail also html content is going. How to stop it. I have tried using text/html in content-type but it throws error.
Mail going as:
<p style="text-align: left;"><em><strong>Hi,</strong></em></p>
<p style="text-align: left;"><em><strong>Would like to know more about deal. Let's meet.</strong></em></p>
<p style="text-align: left;"><em><strong>Thanks,</strong></em></p>
<p style="text-align: left;"><em><strong>Samresh</strong></em></p>

Nodemailer - Unable to send clickable link

I am using nodemailer for sending emails from my nodejs app. I am successfully able to send an email. But, if I want to send a link, the href or anchor tag is not working. That is the link does not go as part of the mail. The rest of the text is sent. Any ideas?
Here is the relevant code :
var messagebody = "Hello ".concat(req.body.name).concat(", One of your team mates have submitted an application form for intern next summer. Please approve or reject the same on the internship portal. Best Regards.");
var mailOptions = {
from: from, // sender address
to: to, // list of receiver
// cc: cc,
subject: subject, // Subject line
text: messagebody, // plaintext body
html: ' Hello '.concat(req.body.name).concat(' , <br /></br > One of your team mates have submitted an application for intern(s) for next summer. Please approve or reject the proposal on the internship portal. <br /> Here is the link of the internship portal : <br /><br /> Best Regards.') // html body
};
Your code is Correct but you havn't wrote anything in between <a></a> tags.
Just put some text between them and it will work.
Click here
You can also render a jade (or pug) file and get it as a string
const render = jade.compileFile('./views/my_email.jade');
const html = render(content);
const mailOptions = {
from: from, // sender address
to: to, // list of receivers
subject: subject, // Subject line
html: html
};
where content is the array with the data you want to pass to the jade file

Mail as plain text in Netsuite

Whenever I send a mail from netsuite, It goes in Rich text format (HTML format).
Instead, I want to send it in Plain text format.
I tried many ways but not working. even when I send it with just as a string it goes in HTML format.
E.g.:
var email_subj = "Mail Subject";
var mail_content = "This goes in Body";
nlapiSendEmail(1234,'abc#gmail.com',email_subj,mail_content ,null,null,rec_MailID);
The above mail too goes to the recipient in Rich Text Format.
Is there a way so that it goes in Plain text format.
To know whether the mail is in rich text or plain text you can inspect the body element in browser of the recipient and you will see that there are HTML contents in the mail body.
Or if you are using Outlook: you can right click the body content and there will be option called "View Source" if you click it you will see the HTML code.
Note: in outlook if the mail is in Plain text format then "View Source" option is disabled you cannot click on it, that is what i want.
SuiteScript 1.0 appears to wrap all email bodies in HTML tags.
SuiteScript 2.0 N/email module(ie: email.send() ) will format as plain text unless you include markup in the body. Mock code:
require(['N/email'],
function(email) {
function sendEmail() {
email.send({
author: 1234,
recipients: 'abc#gmail.com',
subject: 'Mail Subject',
body: 'This goes in Body',
});
}
sendEmail();
});

Resources