Displaying CID Embedded Images from outlook email using the API - rest

I am collecting the content of an email from an office 365 account using the REST API, and then using this to display the email in a separate web based platform via an iframe (to avoid css conflicts).
However, the embedded images and emoticons all appear as broken images because they are CID embedded.
Here's what I get back from the API...
<img size="96043" contenttype="image/png" id="img295971" tabindex="0" style="max-width: 99.9%; -webkit-user-select: none;" src="cid:1af2f0cb-83b4-46b7-aad6-8ea69256282c">
And here's how it looks if I view the same email in office 365...
<img originalsrc="cid:1af2f0cb-83b4-46b7-aad6-8ea69256282c" data-custom="EAMkADc2ZjU0ZjU5LTVmOTAtNDZiZC05ZTMyLWFmYTBmNTBkMTc2NQBGAAAAAACbfH93Aq8QSYpfwBCQxPfnBwDmFINdPPDZS5lgCNopiLnYAAAAAAEMAADmFINdPPHZS5lgCNopiLnYAABYntBTAAABEgAQAOVziLpVtbxHtEZu7MUJkA0%3D" src="service.svc/s/GetFileAttachment?id=EAMkADc2ZjU0ZjU5LTVmOTAtNDZiZC05ZTMyLWFmYTBmNTBkMTc2NQBGAAAAAACbfH93Aq8QSYpfwBCQxPfnBwDmFINdPPDZS5lgCNopiLnYAAAAAAEMAADmFINdPPHZS5lgCNopiLnYAABYntBTAAABEgAQAOVziLpVtbxHtEZu7MUJkA0%3D&X-OWA-CANARY=Dg0nza5wGEudJBx_zc2m9bCVF8Ea6dIYZGUuP-qzYHeYA49c7Ddf2wAF8k5zVa6hpRn6AhTjnaE." id="img295971" style="display: inline; max-width: 100%;">
Any ideas about what I need to do to get these images to display?

This may not be a complete answer, but it is how we have handled it. #hom nom is right that each image is attached, with it's CID info. However, this doesn't per se give you a direct way to display it. However, the REST data does contain both the AttachmentContent AND the ContentId (CID). So we saved the content to somewhere we could refer to it, then replaced the CID image URL with our local image URL. Would love to hear if anyone had found a better solution.
Specifically:
Fetch the attachments for a message:
private List<Attachment> GetMessageAttachments(string messageId, string recipientId)
{
IMessageAttachmentsCollectionPage newAttachments = null;
List<Attachment> returnAttachments = new List<Attachment>();
var nextRequest = graphClient.Users[recipientId].Messages[messageId].Attachments.Request();
while (nextRequest != null)
{
newAttachments = nextRequest.GetAsync().Result;
returnAttachments.AddRange(newAttachments);
nextRequest = newAttachments.NextPageRequest;
}
return returnAttachments;
}
Get the content of the attachment:
public byte[] GetAttachmentBody(string userId, string messageId, string attachmentId)
{
string url = $"Users/{userId}/messages/{messageId}/attachments/{attachmentId}/$value";
RestRequest request = new RestRequest(url, Method.GET);
IRestResponse response = restClient.Execute(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK) throw new HttpRequestValidationException($"Invalid response: {response.Content}");
return Encoding.ASCII.GetBytes(response.Content);
}
Further detail at the MS Graph documentation:
Get Attachments: https://learn.microsoft.com/en-us/graph/api/attachment-get?view=graph-rest-1.0&tabs=http
File Attachment: https://learn.microsoft.com/en-us/graph/api/resources/fileattachment?view=graph-rest-1.0

You can try to get attachments list using message's id. (Do not worry about HasAttachments => false). You will get all CID Embedded Images files.

Related

Create session redirect link in content asset

Our company has multiple brands and each brand has its own host name, but they are all part of the same site. We can let customers share baskets and other session information when they switch between brands via a redirect link using URLUtils.sessionRedirect.
But URLUtils is not available in content assets. Is it possible to form a session redirect link in content asset keeping all the session information?
Thanks in advance.
You can include dynamic content in Content Assets with the $include('Controller-Name', 'name1', 'value1', 'name2', 'value2', ...)$ syntax. See the MarkupText Class Documentation for more info on that syntax. The 'name1' and 'value1' parameters are mapped as query string attributes eg: Controller-Name?name1=value1&name2=value2
Create a controller that outputs the session redirect link you need, and call it via that syntax like: $include(Util-RenderSessionLink, 'siteID', 'foo')$
The controller would need to use a response Content-Type header of text/plain or something like that so that nothing is injected into the response. (eg: Storefront toolkit or tracking tags) For example:
response.setContentType('text/plain');
Alternatively, you could process the content asset for some sorts of keys that you perform find & replace operations on. For example, the following code does a find & replace on a Content Asset's body content for the key: '%%SessionLink%%'.
var ContentMgr = require('dw/content/ContentMgr');
var URLUtils = require('dw/web/URLUtils');
if (!empty(content) {
var content = ContentMgr.getContent('my-content-id');
var contentOut = "";
var viewData = {};
contentOut = content.custom.body.getMarkup()
.replace('%%SessionLink%%', URLUtils.sessionRedirect(...));
viewData.content = contentOut;
// then output your `pdict.content` key within a template with the appropriate encoding
}
If anybody else is running into this, we added a bit of client-side javascript that pickups up all outbound links and if it's one of our domains it sends them through a session redirect. This way we don't need content managers to fix very link between domains:
var domains = ["domaina.com", "domainb.com", "domainc.com"]
var sessionRedirectBase = '/s/Our-Site/dw/shared_session_redirect';
$(document).on("click.crossSite", "a", (e) => {
const href = $(e.currentTarget).attr("href");
if (href) { //does the link have a href
if (href.match(/^(http(s)?:)?\/\//)) { //is href an absolute url
const url = new URL(href);
if (url.hostname != window.location.hostname && domains.indexOf(url.hostname) > -1) { //is hostname not the current one and part of the domains array
e.preventDefault();
const sessionRedirect = `${sessionRedirectBase}?url=${encodeURIComponent(href)}`
window.location = sessionRedirect;
}
}
}
});

GmailApp.sendEmail() doesn't parse plain text when sending HTML mail. How can I make it to show plain text?

I have a document with email body content. I am using Apps Script to fetch the document from URL and send it as an HTML mail.
var url = "address of the document";
var param = {method : "get",
headers : {"Authorization": "Bearer " +ScriptApp.getOAuthToken()}, muteHttpExceptions:true,
};
var html = UrlFetchApp.fetch(url,param).getContentText();
MailApp.sendEmail(
emailId, // recipient
tempSubject, // subject
body,
{ // body
htmlBody: html, // advanced options
});
However, if my document has text like this for example:
Hi
username: rml#gmail.com
password : <aSrD9nn
Happy browsing!
In the resultant email, the text after password: is blank. It does not show in the mail body of the email sent. Apparently, it considers < as an opening tag, I think.
Is there a way to solve this? I tried with other text and it works fine.
How do I overcome this problem? Any help will be much appreciated.

How to insert an emoji into an email sent with GmailApp?

I have a GAS script that sends automated emails and would like to include a couple of emojis. I've tried using shortcodes and copying/pasting, but nothing so far seems to have worked. Just wanted to see if there was anything I was missing.
Edit: Here's the code:
var title = rowData.publicationTitle;
var journal = rowData.journalTitle;
var url = rowData.publicationUrl;
//Emoji goes here in the body:
var body = "Hi " + firstName + "!<br><br>I noticed your article <a href='" + url + "'>“" + title + "”</a> was recently published in <i>" + journal + "</i>. Congratulations! This is just a friendly reminder to please upload your original document and a PDF version to our publications app when you have time.<br><br>To upload your publication, you can <a href='http://support.cpes.vt.edu/publishing'>click here</a>.<br><br>Thanks!<br><br>🤖 CB<br><br><hr style='background-color: #d8d8d8; border: 0 none; color: #d8d8d8; height: 1px;'><span style='font-size:12px'><b>CPES Publications Reminders</b> | <a href='mailto:leshutt#vt.edu' style='text-decoration:none'>Feedback</a> | <a href='http://support.cpes.vt.edu/publishing' style='text-decoration:none;'>Publication uploads</a></span>";
var emailSubject = "Just a reminder to upload your article!";
var me = Session.getActiveUser().getEmail();
var aliases = GmailApp.getAliases();
if (emailStatus == "Pending" && emailData !== "No emails found") {
GmailApp.sendEmail(email, emailSubject, body, {
from: aliases[2],
name: "CPES Bot",
htmlBody: body
});
}
I've noticed that sending a star ("⭐") works, but the normal smiley ("😊") shows up as a black-and-white, Unicode-esque icon and everything else I've tried are question marks. Can you only use emojis up to a certain Unicode release?
You want to send an email with HTML body including the emoji. If my understanding is correct, how about this modification?
About GmailApp and MailApp :
Unfortunately, GmailApp cannot use the recent emoji characters. At GmailApp
emoji less than Unicode 5.2 can be used for this situation.
emoji more than Unicode 6.0 can NOT be used for this situation.
MailApp can use all versions of emoji.
"⭐" is Unicode 5.1. But "😊" is Unicode 6.0. By this, in your script using GmailApp, you can see the former, but you cannot see the latter. At a sample script of Michele Pisani, the latter is sent using MailApp. So the character is not broken. "🤖" is Unicode 8.0.
Modification points :
So in the case of your script, the modification points are as follows.
Use MailApp instead of GmailApp.
OR
Use Gmail API.
From your comments to Michele Pisani, I worry about that MailApp might not work for your situation. So I would like to also propose the method using Gmail API.
1. Modified your script
Please modify as follows.
From :
GmailApp.sendEmail(email, emailSubject, body, {
To :
MailApp.sendEmail(email, emailSubject, body, {
2. Using Gmail API
In order to use this, please enable Gmail API at Advanced Google Services and API console as follows.
Enable Gmail API v1 at Advanced Google Services
On script editor
Resources -> Advanced Google Services
Turn on Gmail API v1
Enable Gmail API at API console
On script editor
Resources -> Cloud Platform project
View API console
At Getting started, click Enable APIs and get credentials like keys.
At left side, click Library.
At Search for APIs & services, input "Gmail". And click Gmail API.
Click Enable button.
If API has already been enabled, please don't turn off.
If now you are opening the script editor with the script for using Gmail API, you can enable Gmail API for the project by accessing this URL https://console.cloud.google.com/apis/api/gmail.googleapis.com/overview
Sample script :
function convert(email, aliase, emailSubject, body) {
body = Utilities.base64Encode(body, Utilities.Charset.UTF_8);
var boundary = "boundaryboundary";
var mailData = [
"MIME-Version: 1.0",
"To: " + email,
"From: CPES Bot <" + aliase + ">",
"Subject: " + emailSubject,
"Content-Type: multipart/alternative; boundary=" + boundary,
"",
"--" + boundary,
"Content-Type: text/plain; charset=UTF-8",
"",
body,
"",
"--" + boundary,
"Content-Type: text/html; charset=UTF-8",
"Content-Transfer-Encoding: base64",
"",
body,
"",
"--" + boundary,
].join("\r\n");
return Utilities.base64EncodeWebSafe(mailData);
}
function myFunction() {
// Please declare email and firstName.
var title = rowData.publicationTitle;
var journal = rowData.journalTitle;
var url = rowData.publicationUrl;
//Emoji goes here in the body:
var body = "Hi " + firstName + "!<br><br>I noticed your article <a href='" + url + "'>“" + title + "”</a> was recently published in <i>" + journal + "</i>. Congratulations! This is just a friendly reminder to please upload your original document and a PDF version to our publications app when you have time.<br><br>To upload your publication, you can <a href='http://support.cpes.vt.edu/publishing'>click here</a>.<br><br>Thanks!<br><br>🤖 CB<br><br><hr style='background-color: #d8d8d8; border: 0 none; color: #d8d8d8; height: 1px;'><span style='font-size:12px'><b>CPES Publications Reminders</b> | <a href='mailto:leshutt#vt.edu' style='text-decoration:none'>Feedback</a> | <a href='http://support.cpes.vt.edu/publishing' style='text-decoration:none;'>Publication uploads</a></span>";
var emailSubject = "Just a reminder to upload your article!";
var me = Session.getActiveUser().getEmail();
var aliases = GmailApp.getAliases();
if (emailStatus == "Pending" && emailData !== "No emails found"){
// Added script
var raw = convert(email, aliases[2], emailSubject, body);
Gmail.Users.Messages.send({raw: raw}, "me");
}
}
Note :
When you use this sample, Please declare email and firstName.
Please run myFunction().
References :
Emojipedia
Advanced Google Services
Gmail API
If I misunderstand your question, I'm sorry.
I tried to copy the emoji (https://www.emojicopy.com/) and paste it directly into the script editor:
and after sending the email I received it in my mailbox:
Edit:
Be careful that some emoji are one character length (like the star) but other are 2 characters (like the smile) for those with 2 characters you can think of writing immediately after the smile but instead you are writing inside the smile so you break it therefore turns in question mark.
If you try to run this code, you will see that the first has length 2 and the second one has length 1:
If you try to move the pointer (in the apps script editor) on those 2 emoticons, from before to after the emoticon, you will see that in the case of the star just one step but for the smile you need 2 steps.
The easiest complete answer that also works with SMS recipients is this:
function testNewMail() {
MailApp.sendEmail({
to: "yourphonenumbergoeshere#mymetropcs.com",
subject: "Logos",
htmlBody: "😊 hi todd happy day"
});
}
Use code points (💎) in the value of your cell and send your message as HTML:
var sheet = SpreadsheetApp.getActiveSheet();
var value = sheet.getRange("A1").getValue();
GmailApp.sendEmail(
"recipient#example.com",
"subject",
"",
{
from: "sender#example.com",
htmlBody: value
}
);

Meteor : Email a Template in Client using Mailgun

I have a Template in client
<template name="sendThis">
<img src="logo.png"><br>
<h3>Welcome to Meteor NewBie</h3>
Dear {{name}},
<p>You received this Email because you have subscribed to http://www.example.com</p>
</template>
I would like to send this Template(sendThis) as HTML body in my Email to subscribers.
I am using Mailgun as my Email Client. What are the steps I should take to make this happen as a subscriber clicks a button with an id "subscribe".
PS: I have multiple helpers in this template, multiple in the sense more than 20.
Thanks in advance.
Mahesh B.
One way to solve this is to use Blaze.toHTMLWithData to render your template (with a context) to an HTML string. You can then call a method on your server which emails the user with the appropriate subject and address. Here's an example:
client
var sendSignupEmail = function() {
// This assumes this first email address is the one you want.
// In some cases you may want the first verified email, but not
// during signup.
var address = Meteor.user().emails[0].address;
var subject = 'Thanks for signing up!';
// Here I used username - replace this with the appropriate data
// like Meteor.user().profile.firstName or something.
var body = Blaze.toHTMLWithData(Template.sendThis, {
name: Meteor.user().username
});
Meteor.call('sendEmail', address, subject, body);
};
server
Meteor.methods({
sendEmail: function(to, subject, html) {
check([to, subject, html], [String]);
this.unblock();
return Email.send({
to: to,
from: 'something#example.com',
subject: subject,
html: html
});
}
});
Also make sure your MAIL_URL environment variable has been defined.

Update URL in Email body dynamically in mvc/c#

Working on sending the account verification email in mvc. I created a format for email body such as below and kept in html file inside solution called "EmailFormat.html".
<body>
Dear [Name],
<p>Thanks for registration.To activate your account please follow the link below:</p>
<p> click here for verification </p>
<p>if you are not Name or didn't register on abc.com you can ignore this email.</p>
<p>Regards,</p>
<p>www.abc.com</p>
</body>
I have a c# class handling email send.I get the above mentioned html file as email body and try to replace the [Name] and [url] with actual runtime paramaters.
string name = myclass.FirstName + " " + myclass.LastName;
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("abc." + "EmailFormat.html"))
using (StreamReader reader = new StreamReader(stream))
{
body = reader.ReadToEnd();
}
body.Replace("[Name]", name);
string url = HttpUtility.HtmlEncode("http://localhost/Controller/Method/uniqueid")
body.Replace("[url]",url);
emailutility.send();//ignore this send code.
I receive email just fine but the problem is the on clicking "click here for verification", it takes me to %5Burl%5D instead of actual url.
Please help.
Thanks
My Bad. it was unable to update the body after body.Replace("[Name]", name);
I changed it to as follows :-
body = body.Replace("[Name]", name);
body = body.Replace("[url]",url);
Resolved!!!!