GmailThread.reply does not have original message in body - google-apps-script

I am replying to an email using GmailThread.reply(body)
But the problem is that unlike replying using gmail app on web or android, the replies do not have a copy of original message.
Here is my code:
function testreply() {
var threads = GmailApp.getInboxThreads();
Logger.log(threads[0].getFirstMessageSubject());
threads[0].reply("test reply");
}
My question is that is this the expect behaviour?
Is it possible to include the original message in the reply(just as gmail web which adds special formatting to the original message in reply)?

I found a similar question on Gmail Forum. According to this, you need to construct the entire message body to pass to the Reply method. You can get the body and headers from the original message to construct the final form.
Also try to check this for more information.

Related

Google Apps Script Gmail getPlainBody Line Breaks

With the Google Apps Script Gmail library, when I use the function GmailMessage.getPlainBody(), the API seems to take what used to be one paragraph and break it up into multiple, potentially by using a character limit. For instance, a paragraph of my email reads:
From the link you sent me, I gleaned that Gmail refers to their secure email as confidential.
But when I call this function on the email, it becomes:
From the link you sent me, I gleaned that Gmail refers to their
secure email as confidential.
And, when I split the email text on a new line delimitor and do a bit of cleanup to create an array with my output, I end up with:
['From the link you sent me, I gleaned that Gmail refers to their', 'secure email as confidential.']
I viewed this Reddit post, which seemed to deal with the similar problem. But, I tried the resolution suggested by the person who posed the question:
body = message.getPlainBody().replace(/\r\n\r\n/gm,'aaaLINEBREAKERaaa').replace(/\r\n/gm,' ').replace(/aaaLINEBREAKERaaa/gm, '\r\r').replace(/ /gm,' ')
And it didn't quite give me what I need. Has anyone else encountered this problem, and if so, do you have a suggested workaround? Thanks!
I had the same issue. In that case, I used a workaround.
When I checked the email, I noticed that the HTML body is included in the message body and the HTML body has the original paragraph, and I used this situation. So, in this workaround, the original text is retrieved from the HTML body and the HTML is converted to a text. By this, the original paragraph is obtained. The sample script is as follows.
Sample script:
This script uses Drive API for converting HTML to text. So pelase enable Drive API at Advanced Google services.
var message = // Here, please use your "message".
var html = message.getBody();
var id = Drive.Files.insert({title: "temp", mimeType: MimeType.GOOGLE_DOCS}, Utilities.newBlob(html, MimeType.HTML)).id;
var text = DocumentApp.openById(id).getBody().getText(); // or DocumentApp.openById(id).getBody().getText().trim();
DriveApp.getFileById(id).setTrashed(true);
console.log(text)
References:
getBody()
Files: insert

apps script getBody doesn't give full html contents

I get emails from a system that contains paragraphs and tables.
When I try to get full html format using getBody from email it gives me just CSS contents and not the whole html contents.
However when I copy full email body and send it to myself in a new email then getBody function gives me accurately full body in html format including all tags and contents.
Kindly guide what I am missing here?
var label = GmailApp.getUserLabelByName("INBOX/reports0");
var threads = label.getThreads();
var tempbody = threads[i].getMessages()[0].getBody();
Regards
As the logged output in the console is too large and it's being truncated you're not seeing the whole output in neither of the cases, you're getting the entire HTML you just don't see it there. You can use Stackdriver logging instead to show the whole output.

Does the Win 10 UWP EmailMessage API support having an HTML body?

I have tried the following code to send an email from an Universal Windows Platform app. It works fine when I use EmailMessageBodyKind::PlainText. However, as indicated in the code below, EmailMessageBodyKind::Html seems to launch the email client with no content. Does anyone know what else needs to be set to get this to work - the documentation is sparse 8 (
using namespace Windows::Storage::Streams;
using namespace Windows::ApplicationModel::Email;
using namespace Windows::Security::Cryptography;
auto bin = CryptographicBuffer::ConvertStringToBinary(
L"<html><body>this <b>is</b> text</body></html>",
BinaryStringEncoding::Utf16LE);
auto memStream = ref new InMemoryRandomAccessStream();
concurrency::create_task(memStream->WriteAsync(bin)).then(
[memStream](unsigned)
{
auto email = ref new EmailMessage();
email->To->Append(ref new EmailRecipient(L"test#gmail.com"));
email->Subject = L"Email Report";
auto randomAccessStreamReference = RandomAccessStreamReference::CreateFromStream(memStream);
email->SetBodyStream(EmailMessageBodyKind::Html, randomAccessStreamReference);
EmailManager::ShowComposeNewEmailAsync(email);
}
);
Well, I got some bad news for you.
It is not possible to do so using EmailManager.ShowComposeNewEmailAsync
Regarding using SetBodyStream with EmailMessageBodyKind.Html, we have this from MSDN forum:
Currently, the EmailMessageBodyKind.Html won't work for create a new
HTML e-mail and there is no other way as a workaround, I've checked
the internal resource, this API is used for populating messages from
App server and save e-mail message into local folder.
The thing is: EmailManager.ShowComposeNewEmailAsync uses mailto to send the message and, as stated in some other question already answered here:
Section 2 of RFC 2368 says that the body field is supposed to be in
text/plain format, so you can't do HTML.
However even if you use plain text it's possible that some modern mail
clients would render the resulting link as a clickable link anyway,
though.
That being said, you're relying on the mail client to render that HTML for you.
I've tested this using Windows 10 Mail Client, Gmail and Outlook (both the later on a web browser), and all of them failed to render a simple HTML <b> tag on the mail body, showing it as plain text instead.
Now, for the alternatives (from that same MSDN forum thread):
Note that if I use the ShareDataContract (DataTransferManager), I am
able to set the HTML in the request and it will appear in the email
body if the user chooses to share via Mail. However I would like to
skip the Share UI and go directly with composing an email with
recipient already populated, HTML body, and image attachments.
One alternative is to persist the HTML body to a file and then include
that file as an additional attachment, however that is not ideal
The DataTransferManager successfully formatted the HTML message. Here's a small sample of how your sample code would look like, adapted from MSDN:
void YourView::ShareHtml()
{
DataTransferManager^ dataTransferManager = DataTransferManager::GetForCurrentView();
auto dataRequestedToken = dataTransferManager->DataRequested +=
ref new TypedEventHandler<DataTransferManager^, DataRequestedEventArgs^>(
this, &YourView::OnShareHtml);
DataTransferManager::ShowShareUI();
}
void YourView::OnShareHtml(DataTransferManager^ sender, DataRequestedEventArgs^ e)
{
DataRequest^ request = e->Request;
request->Data->Properties->Title = "Email Report";
String^ html = L"<html><body>this <b>is</b> text</body></html>";
String^ htmlFormat = HtmlFormatHelper::CreateHtmlFormat(html);
request->Data->SetHtmlFormat(htmlFormat);
}
The limitations of this approach are:
You cannot force the user to select e-mail as the sharing option
You cannot previously specify the mail recipient.

Google Spreadsheet Script Editor MailApp.sendEmail not setting replyTo?

I'm using Google Spreadsheet for customers to send in comments. When they submit a comment, it gets emailed to me. I use the MailApp.sendEmail method. It works as expected except for the replyTo "advanced argument":
var myAdvancedArgs = { htmlBody: myHtmlBody, replyTo: customerEmail };
MailApp.sendEmail("me#example.com", "Comments Form", myBody, myAdvancedArgs);
customerEmail is set properly because I have it output correctly in the body of the message. htmlBody works as I do get the HTML version of the email displaying in my GMail account. However, when I click the reply button in GMail, the To: address is myself. It appears the replyTo is not being set at all. But then I look in the headers of the email message by clicking the little triangle next to my name with the tooltip "Show Details" and it does mention the correct reply-to address:
reply-to: mycustomer#example.com
Is MailApp.sendEmail not setting the reply-to header correctly?
UPDATE: I've snipped a couple images to demonstrate what's happening. Either the reply-to header isn't set properly (maybe that's not how you do a reply to?) or GMail is not working properly for me.
First image, you see that there is a reply-to header created from my Google Spreadsheet script:
Second image, when I click the reply button in GMail, the to address is not filled in with the address in the reply-to header:
I found the reason to your (and my) problem.
What you are seeing is a Gmail bug, not an Apps Script bug. Basically,
if the reply-to is any email address that you have linked with your
address so you can send mail as that account from within gmail, then
reply-to is ignored. In other words, it will look broken to you, but
for any other users of your script it will work properly. Non-Gmail
users will see it work correctly in any case.
This is an old question, but if I needed it maybe others also need it!
From my testing the replyTo worked only when I sent the mail not to the form Acount mail.
If your form is on your#gmail.com acount send it to yourOtherMail#gmail.com
var reply = e.namedValues['Email'];
MailApp.sendEmail("NotFormMail#mail.com", "subject", "message",{"replyTo" : '"'+reply+'"'});
Just tested like this :
function myFunction() {
MailApp.sendEmail("serge----#gmail.com ", "test message",'empty body', {"replyTo" : "serge_test#yopmail.com"}); // replyTo son#insas
}
and it works as expected when I "reply" (using the reply button in gmail or in any mail client ) it shows up like this :
which is indeed the replyTo adress even if it is true that the sender is indeed the author of the script (which is also the expected behavior, see documentation about scripts)
So I'm afraid the issue you raised is invalid...

How do you force a web browser to use POST when getting a url?

How do you force a web browser to use POST when getting a url?
Use an HTML form that specifies post as the method:
<form method="post" action="/my/url/">
...
<input type="submit" name="submit" value="Submit using POST" />
</form>
If you had to make it happen as a link (not recommended), you could have an onclick handler dynamically build a form and submit it.
<script type="text/javascript">
function submitAsPost(url) {
var postForm = document.createElement('form');
postForm.action = url;
postForm.method = 'post';
var bodyTag = document.getElementsByTagName('body')[0];
bodyTag.appendChild(postForm);
postForm.submit();
}
</script>
this is my post link
If you need to enforce this on the server side, you should check the HTTP method and if it's not equal to POST, send an HTTP 405 response code (method not allowed) back to the browser and exit. Exactly how you implement that will depend on your programming language/framework, etc.
I have a feeling from your question you were just hoping to send a post request in a browser's address bar.
Just type the following into the address bar swapping the value for 'action' to the url that you like.
data:text/html,<body onload="document.body.firstChild.submit()"><form method="post" action="http://stackoverflow.com">
It's invalid html, but the browser's (at least all the ones i've tested it in so far) know what you mean, and I wanted to keep it as short as I could.
If you want to post values, append as many inputs as you like, swapping name and value in each input for whatever you like.
<input value="hugh.mahn#person.com" name="email">
<input value="passwordsavedinhistory" name="password">
It's important to note that sensitive information you post will be visible in:
your history
your address bar
your browser's autocomplete.
possibly other sites that you visit from the same tab
probably plenty of other things too
It's a really bad way to send a post request, and all the other answers are far better, but it's still cool that you can do it.
<form method="post">
If you're GETting a URL, you're GETting it, not POSTing it. You certainly can't cause a browser to issue a POST request via its location bar.
If you're trying to test something, I'd suggest using Fiddler to craft your http requests. It will allow you to specify the action verb (GET, POST, PUT, DELETE, etc) as well as request contents. If you're trying to test a very specific request from a link but with POST instead, then you can monitor the requests your browser is making and reissue it only with the modified POST action.
you can not force any web browser to send the url with POST header. But to test a POST request url , I can suggest "POSTER" extention of chrome and mozilla
I know this question is old but someone may find this useful. You can use a command line tool like cURL (http://curl.haxx.se/) to post to a URL.
Example:
curl -v --basic --user username:password --request POST "http://www.theurltopostto.com"
The above submitAsPost() function is a good and elegant solution but it has a problem - if the URL is too long some browsers (including Firefox and IE) will return an error. Since many of us use POST in order to bypass this very limitation, I suggest this solution:
// submit a URL using post
function submitAsPost(url) {
var bodyTag = document.getElementsByTagName('body')[0];
var postForm = document.createElement('form');
bodyTag.appendChild(postForm);
postForm.method = 'POST';
var serverAndParams = url.split("?");
postForm.action = serverAndParams[0];
var params = null;
try
{
var paramsAndHash = serverAndParams[1].split("#");
params = paramsAndHash[0];
var attrList = params.split("&");
for (var i = 0; i < attrList.length; i++)
{
try
{
var keyValue = attrList[i].split("=");
var el = document.createElement('input');
el.type="hidden";
el.name=keyValue[0];
var value = keyValue[1];
value = value.replace(/\+/g, ' ');
el.value=decodeURIComponent(value);
postForm.appendChild(el);
}
catch(error){}
}
}
catch(error){}
postForm.submit();
bodyTag.removeChild(postForm);
}
Tested with Firefox, Chrome and IE.
You can use a tool to test. I'm always asking the same question as you. There is quite a few tools available online. Here is the tool that I use: http://www.hurl.it/
This is a little late in the game but I ran across this and found that HTML 5 made some changes. You can use the input tag to add formmethod (thus selecting post). This worked for me.
see : http://www.w3schools.com/tags/att_input_formmethod.asp
If you had the problem of doing:
request.open('POST',url,true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send("data="+JSON.stringify(data));
and in dev tools you still se it is doing a GET then that means that your url is in the following format:
http://example.com/folder
Meaning it should be:
http://example.com/folder/
Its a very bizarre error maybe not related with your question but I ve had it a couple of times and it should be out there as it looks seriously dangerous. This happened to me when using an apache 2 server on Ubuntu 14.04, with not much configuration.
The utility "Fiddler" by Telerik (free ware) allows you to "compose" an http request and send it using any method you choose (Get, Post, Put, Del, etc) It also will give you some very detailed information about the request and the response that can be very helpful during testing and debugging