Base64 encoded image sent using sendgrid not displayed in mails - node.js

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"
/>

Related

How to send base64 string as image in html body template in Node.js using nodemailer

I have nodejs request which need to embed the image base 64 string in the email html template body using nodemailer
as per the documentation
https://nodemailer.com/message/embedded-images/#example
let message = {
html: 'Embedded image: <img src="cid:unique#nodemailer.com" alt="Red dot"/>',
attachments: [{
filename: 'image.png',
content:'data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==',
cid: 'unique#nodemailer.com' //same cid value as in the html img src
}]
}
I tried sending the base64 attachment to nodemailer and htmlbody with image tag and it's cid,
but it shows broken image after receiving mail
Image base64 string using cid
but if i tried same with the, image URL then its that image showing properly in received mail
let message = {
html: 'Embedded image: <img src="cid:unique#nodemailer.com" alt="Red dot"/>',
attachments: [{
filename: 'image.png',
href: "https://upload.wikimedia.org/wikipedia/commons/5/57/Cumulus_Clouds_over_Yellow_Prairie2.jpg",
cid: 'unique#nodemailer.com' //same cid value as in the html img src
}]
}
Image href url with CID
Is there any workaround to handle same or any other syntactical changes needed to display base64 string?

Postman display base64 image as test result

I am trying to visualize a base64 img I receive in my response using the Postman Test feature.
My JSON:
{
...,
"result": {
...,
"image": "data:image/jpeg;base64,/..."
}
}
I want to do something like this:
let template = `
<img src='{{img}}'/>
`
pm.visualizer.set(template, {
img: pm.response.json().result.image
})
How can I display the base64 image inside the tag / retrieve it from the Postman pm object?
Your variant almost right, but you need to retrieve img data for the template in a proper way like following:
let template = `
<img src='{{img}}'/>
`;
pm.visualizer.set(template, {
img: pm.response.json()["result"]["image"]
});
Try console.log() on your template to see if it is resolving how you expect. I got your solution to work using a hard-coded base64 image of a little red dot
const base64ImgData = `data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==`
const template = `
<img src="{{img}}">
`
pm.visualizer.set(template, {img: base64ImgData})
Screenshot

Image src is not working when using nodemailer

Every time a user is registered to my website, I would like to send an automatic email to him with
the logo of the company, this is how I did it but for some reason, the IMG doesn't show.
mailSender.sendEmail('donotreplay#example.co.il','example#mail.com', " Hey "
+userToCreate.ownerName+" , Welcome to Example",
`
<table>
<tr style="background:black"> <img src="img/logo.png"></tr>
<tr>Check If Image Works</tr>
</table>
`
)
in nodemailer configuration you must set attachment, example:
from: '"Orange Water" <123#orange.com>', // sender address
to: getEmail, // list of receivers
subject: subject,
html: data, // html body
attachments: [{
filename: 'image.png',
path: 'your path to image',
cid: 'unique#kreata.ee' //same cid value as in the html img src
}]
});
And in your html file, img src must the same cid which already declared in nodemailer configuration. example:
<p<img src="cid:unique#kreata.ee" width="100" height="100" </p>
Hope this help.
You have to set the full URL of the image in the src attribute.
<tr style="background:black"> <img src="https://yourdomain.com/img/logo.png"></tr>

Serve both text and image data when rendering a template?

Trying to send both text and image data as local variables to a server-side rendered page using templates.
I know I have to set the Content-Type as 'image/png'.
How can I set the Content-Type for one variable when all the other variables are text?
Thank you so much!
res.render('profile.html', { locals: {
tasks: tasks,
msgExists: '',
name: req.user.name,
email: req.user.email,
photo: req.user.photo //how to set Content-Type for this variable?
}});
the template is rendered on server side, and then sent to client. this means the content type of the response is "text/html", not "image/png".
your variables do not have "Content-Type", as they are not HTML responses. if you want to embed an image in an html, and you know its raw data, it usually looks like this:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="/>
now if you have the image data (like whatever after base64 part) somehow stored in a JS variable, and want to pass it to your template renderer to embed that image in the resulting html, it would look like this:
// node js code:
imgData = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
res.render('my.template.html', {
imgData,
// whatever else ...
});
<!-- template code: -->
<img src="data:image/png;base64,{{imgData}}"/>
<!-- whatever else -->
of course this can change a bit based on the exact format you are storing the image data.

SharePoint REST show current user profile picture

When getting the URL from the current user's profile via REST, the image tag is not able to display when the src is updated:
<img id="escMyPic" src="" alt="" />
<script type="text/javascript">
$.ajax({
url: strURL + "/_api/sp.userprofiles.peoplemanager/getmyproperties",
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
},
success: MyPictureSucceeded,
error: MyPictureFailed
});
function MyPictureSucceeded(data) {
if(data.d.PictureUrl != null) {
$('#escMyPic').attr('src', data.d.PictureUrl);
}
}
function MyPictureFailed() {
alert('Error: Unexpected error loading profile picture.');
}
</script>
The return url looks like this in SharePoint Online:
https://tenant-my.sharepoint.com:443/User%20Photos/Profile%20Pictures/email_address_MThumb.jpg?t=63601764394
It redirects to:
https://tenant-my.sharepoint.com/User%20Photos/Profile%20Pictures/email_address_MThumb.jpg?t=63601764394
Using browser dev tools, you see the mime type that comes back is not image/jpg but text/plain. I've removed the query string parameter, and even placed the hard coded URL in the image tag src, but it just doesn't display. Also the response body in the dev tools is blank. It appears to be redirecting and authenticating before showing.
When placing the hard coded URL in the browser address bar, the picture shows fine, and the dev tools response header shows the picture as the contents of the URL, and the MIME type is image/jpg.
How do you get the profile image to show from a REST call?
In addition to /_api/sp.userprofiles.peoplemanager/getmyproperties endpoint which returns PersonalUrl property, user profile picture could be requested via _layouts/15/userphoto.aspx?size=<size>&accountname=<accountname> page, where
size - could be set to S/M/L which stands for Small/Medium/Large
image size
accountname - user account name
Example
var url = getMyPictureUrl(_spPageContextInfo.webAbsoluteUrl,_spPageContextInfo.userLoginName,"M");
$('#escMyPic').attr('src', url);
where
function getMyPictureUrl(webUrl,accountName,size){
return webUrl + "/_layouts/15/userphoto.aspx?size=" + size + "&accountname=" + accountName;
}

Resources