Fixed
Status Update
Comments
as...@google.com <as...@google.com> #2
Thanks for your feedback!
The request has been filed.
In the mean time you could simply email yourself first and then forward that to your boss.
Best,
Anton
The request has been filed.
In the mean time you could simply email yourself first and then forward that to your boss.
Best,
Anton
da...@gmail.com <da...@gmail.com> #6
This facility would make it far simpler to operate a real-world workflow scenario where only some of the information for the body of the email will come from automated processes. Once the drafts are saved, they can be worked upon until ready to be sent.
I understand that there are workarounds, but these complicate things, and mean that someone "more technical" has to step in to configure things.
I understand that there are workarounds, but these complicate things, and mean that someone "more technical" has to step in to configure things.
de...@lafurniturestore.com <de...@lafurniturestore.com> #7
I would like to specify that this should include all kinds of functionality related to Drafts, like being able to get Drafts messages easily and then send them via script.
it...@gmail.com <it...@gmail.com> #8
Was this app completed ??
[Deleted User] <[Deleted User]> #9
I am also very interested in this functionality.
It would make my workflow considerably smoother.
It would make my workflow considerably smoother.
ke...@gmail.com <ke...@gmail.com> #10
Really shooting yourselves in the foot by both not supporting this feature and http://code.google.com/p/google-apps-script-issues/issues/detail?id=674 . There is no viable way to "mail merge" professionally with google apps.
he...@gmail.com <he...@gmail.com> #11
I could use this functionality as well. Best Regards,
Gary
Gary
bo...@sardiniayoga.com <bo...@sardiniayoga.com> #12
It is unbelievable that this is not a high priority enhancement. The workflow implications are huge and would add so much for small businesses trying to use the GMail, Drive, Docs etc suite to run their business.
am...@gmail.com <am...@gmail.com> #13
I am keen on this functionality too. I use Gmail to generate invoices I can email them directly but I would prefer to create a draft, review it and then send manually.
[Deleted User] <[Deleted User]> #14
I am also looking for this functionality, the company I work for could use this on a daily basis for workflow.
jo...@gmail.com <jo...@gmail.com> #15
I need this solution to perform a HTML mail merge so that my clients can perform these tasks all in one place, cleanly and efficiently.
vi...@gmail.com <vi...@gmail.com> #16
I expected to see GmailApp.createDraft when I saw GmailApp.sendemail. Needs for such a function seem more than obviously to me. Can't believe that this isn't available after almost 2.5 year after it's been suggested.
zi...@cloudware360.com.pe <zi...@cloudware360.com.pe> #17
I dont see the point of complaining that this should be supported. Doesnt seem that important and can be easily implemented by the programmer in all the cases here that have complained.
If u (coder) need to review the message or add comments simply implement the workflow yourself. From code. What stops u from doing that? Once all involved approve, send the email from code.
If u (coder) need to review the message or add comments simply implement the workflow yourself. From code. What stops u from doing that? Once all involved approve, send the email from code.
vi...@gmail.com <vi...@gmail.com> #18
actually there are many use cases where a msg should be eternally a draft(editable/accessible through gui/gas)
ri...@parker.edu.au <ri...@parker.edu.au> #19
This would be a useful feature to allow to to compensate for the existing limitations in GAS.
For example, generating a Table-of-Contents cannot be done using script.
Having a document generated and attached to an e-mail as a draft would enable us to manually open the document and insert the ToC, rather than have to open the document, re-save, create an e-mail, attach the document and then send.
With the amount of students we process this would save us on average 20 minutes a day (and reduce the human transcription errors)
For example, generating a Table-of-Contents cannot be done using script.
Having a document generated and attached to an e-mail as a draft would enable us to manually open the document and insert the ToC, rather than have to open the document, re-save, create an e-mail, attach the document and then send.
With the amount of students we process this would save us on average 20 minutes a day (and reduce the human transcription errors)
sa...@gmail.com <sa...@gmail.com> #20
There has not been any updates from a person from Google on this issue since March, 2012.
Waiting eagerly to hear back from them. Is this feature going to be available sometime soon?
Waiting eagerly to hear back from them. Is this feature going to be available sometime soon?
[Deleted User] <[Deleted User]> #21
Very interested by this functionality as well!
cu...@gmail.com <cu...@gmail.com> #22
Highly expect this function!
ko...@gmail.com <ko...@gmail.com>
so...@specevents.net <so...@specevents.net> #23
We would really love to see this functionality added in order to draft messages that need reviewing and editing before sending, but which contain common information that is unwieldy to repeatedly copy, paste and format correctly from a Spreadsheet.
[Deleted User] <[Deleted User]> #24
Time for this to come to fruition as the last piece of work flow process that I can develop with your other sevices.
ki...@gmail.com <ki...@gmail.com> #25
+1 : My scenario is distributing draft e-mails to our sales team that they can then customize before sending.
wy...@gmail.com <wy...@gmail.com> #26
This has been an extended ticket. Is there any update from a developer on this?
yu...@gmail.com <yu...@gmail.com> #27
Well, with the announced at the I/O new Gmail API, I was able to create Draft. Although I didn't played much with format, only plain text email.
Note - first you have to open developer console (through Advanced Services menu) and enable Gmail API!
function createDraft() {
var forScope = GmailApp.getInboxUnreadCount(); // needed for auth scope
var raw =
'Subject: testing Draft\n' +
//'To: test@test.com\n' +
'Content-Type: multipart/alternative; boundary=1234567890123456789012345678\n' +
'testing Draft msg\n' +
'--1234567890123456789012345678--\n';
var draftBody = Utilities.base64Encode(raw);
var params = {method:"post",
contentType: "application/json",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions:true,
payload:JSON.stringify({
"message": {
"raw": draftBody
}
})
};
var resp = UrlFetchApp.fetch("https://www.googleapis.com/gmail/v1/users/me/drafts ", params);
Logger.log(resp.getContentText());
/*sample resp: {
"id": "r3322255254535847929",
"message": {
"id": "146d6ec68eb36de8",
"threadId": "146d6ec68eb36de8",
"labelIds": [
"DRAFT"
]
}
}*/
}
Note - first you have to open developer console (through Advanced Services menu) and enable Gmail API!
function createDraft() {
var forScope = GmailApp.getInboxUnreadCount(); // needed for auth scope
var raw =
'Subject: testing Draft\n' +
//'To: test@test.com\n' +
'Content-Type: multipart/alternative; boundary=1234567890123456789012345678\n' +
'testing Draft msg\n' +
'--1234567890123456789012345678--\n';
var draftBody = Utilities.base64Encode(raw);
var params = {method:"post",
contentType: "application/json",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions:true,
payload:JSON.stringify({
"message": {
"raw": draftBody
}
})
};
var resp = UrlFetchApp.fetch("
Logger.log(resp.getContentText());
/*sample resp: {
"id": "r3322255254535847929",
"message": {
"id": "146d6ec68eb36de8",
"threadId": "146d6ec68eb36de8",
"labelIds": [
"DRAFT"
]
}
}*/
}
da...@gmail.com <da...@gmail.com> #28
v. nice, thank you
wi...@gmail.com <wi...@gmail.com> #29
Great post on using Gmail API -- tested and working.
Any tips or ideas on how one would go about adding an attachment (e.g. .pdf document from drive) to the draft?
Any tips or ideas on how one would go about adding an attachment (e.g. .pdf document from drive) to the draft?
ag...@gmail.com <ag...@gmail.com> #30
Good news, thanks.
am...@gmail.com <am...@gmail.com> #31
Brilliant yurec!
Works for me too!
Someone asked about attaching a PDF. When I started playing with this API a while back I found I could attach a PDF from drive but then when the recipient received the mail it wasn't really attached it was just a link to the shared document. That wasn't what I wanted.
However for me creating a draft is good enough as I want to check the mail and add the the attachment manually before sending but just want to automate creation and accompanying text.
So automating the PDF creation and download would be a nice next step for me.
Cheers
Works for me too!
Someone asked about attaching a PDF. When I started playing with this API a while back I found I could attach a PDF from drive but then when the recipient received the mail it wasn't really attached it was just a link to the shared document. That wasn't what I wanted.
However for me creating a draft is good enough as I want to check the mail and add the the attachment manually before sending but just want to automate creation and accompanying text.
So automating the PDF creation and download would be a nice next step for me.
Cheers
vi...@gmail.com <vi...@gmail.com> #32
Hello everyone.
Save mail as draft works like a charm for the plain text but my problem is to save HTML format message.
I can't work with the code to save mail as draft for the HTML body.
I got following error.
{ "error": { "errors": [ { "domain": "global", "reason": "invalid", "message": "Invalid value for ByteString:..............................
So can anyone help me for this matter?
Thanks in advance.
Vipul
Save mail as draft works like a charm for the plain text but my problem is to save HTML format message.
I can't work with the code to save mail as draft for the HTML body.
I got following error.
{ "error": { "errors": [ { "domain": "global", "reason": "invalid", "message": "Invalid value for ByteString:..............................
So can anyone help me for this matter?
Thanks in advance.
Vipul
in...@guttergeeks.co.nz <in...@guttergeeks.co.nz> #33
I'm hesitant to ask this but I would really like Draft functionality too. So the big question: How does one use Yurec's code with normal GAS gmail script? An example would be great.
I send email like:
MailApp.sendEmail(emailTo, subject, body, {'bcc':'bob@example.com', 'name':'Bob from Example Ltd', htmlBody: body});
...although I understand that it doesn't work with HTML mail.
Cheers.
I send email like:
MailApp.sendEmail(emailTo, subject, body, {'bcc':'bob@example.com', 'name':'Bob from Example Ltd', htmlBody: body});
...although I understand that it doesn't work with HTML mail.
Cheers.
ch...@gmail.com <ch...@gmail.com> #34
I'm getting the same errors as Vipul sometimes. Sometimes it works fine and creates a draft, and others I get an error. It does at least seem consistent that the same email addresses have errors every time, but I really have no idea where to even begin to look on this.
Here's my error:
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "Invalid value for ByteString: c4OTAxMjM0NTY3OC0tCg==",
"locationType": "other",
"location": "message.raw"
}
],
"code": 400,
"message": "Invalid value for ByteString: c4OTAxMjM0NTY3OC0tCg=="
}
}
I do find it interesting that my other case that errored ends in an "=" as well. Could just be coincidental, but that seems suspicious. Not sure what that would mean right off, though.
Any ideas where to look on this?
Thanks,
Alan
Here's my error:
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "Invalid value for ByteString: c4OTAxMjM0NTY3OC0tCg==",
"locationType": "other",
"location": "message.raw"
}
],
"code": 400,
"message": "Invalid value for ByteString: c4OTAxMjM0NTY3OC0tCg=="
}
}
I do find it interesting that my other case that errored ends in an "=" as well. Could just be coincidental, but that seems suspicious. Not sure what that would mean right off, though.
Any ideas where to look on this?
Thanks,
Alan
am...@gmail.com <am...@gmail.com> #35
I got that error when I have certain characters in the email.
Try miniming the message to isolate the problem.
In my case it was either tilde ~ or two consecutive CR LF which I had to
improve formatting. In the latter case just separate with a space.
Good luck
Try miniming the message to isolate the problem.
In my case it was either tilde ~ or two consecutive CR LF which I had to
improve formatting. In the latter case just separate with a space.
Good luck
le...@leciak.pl <le...@leciak.pl> #36
The thing is that it must be a base64 url safe text. I have the very same issue with coding the string that has two tilds in two rows. For some reason it's dropped with the 400 error just like in your cases above. The string is coded properly by Utilities.Base64Encoding as I copied the coded string from logger and managed to properly decoded it in any decoder taken from google.com .
Is there any way to pass the draft in some other format? (text/plain or smth?)
Is there any way to pass the draft in some other format? (text/plain or smth?)
le...@leciak.pl <le...@leciak.pl> #37
Update: I've managed to pass this error by simply adding the code below under the "var draftBody [...]":
draftBody = draftBody.replace(/\//g,'_').replace(/\+/g,'-');
draftBody = draftBody.replace(/\//g,'_').replace(/\+/g,'-');
ch...@gmail.com <ch...@gmail.com> #38
Oh, I think I finally found the problem characters. Seems to be that it doesn't like the "<" and ">" at the beginning and end of the email address. So "blah@gmail.com" works, and "<blah@gmail.com>" works for some email addresses, but not for others, for some reason. So easiest thing is to just remove them for all addresses. Thanks for the pointer!
am...@gmail.com <am...@gmail.com> #39
That's good. Thanks for the follow up.
ch...@gmail.com <ch...@gmail.com> #40
So taking off the "<" and ">" chars helped for a simple email, but when I have anything like "?" or "!" it still dies (though only in some cases, oddly enough). Any idea on how to maybe escape those characters or make them usable somehow? It seems like we're missing a function, like "escape()", that would make writing an email less fragile. It doesn't make sense that you have to just take out anything that's not an alphanumeric char. But I'm not immediately finding anything that can do that kind of sanitizing.
le...@leciak.pl <le...@leciak.pl> #41
Maybe I wasn't clear enough. The code that I used:
"draftBody = draftBody.replace(/\//g,'_').replace(/\+/g,'-');"
operates on already encoded message. So the trick is to replace the unwanted chars from the encoded output, not from the source plain text message.
"draftBody = draftBody.replace(/\//g,'_').replace(/\+/g,'-');"
operates on already encoded message. So the trick is to replace the unwanted chars from the encoded output, not from the source plain text message.
ch...@gmail.com <ch...@gmail.com> #42
Ooooh, I hadn't tried it that way. That works perfectly! Awesome - thank you so much!
ag...@gmail.com <ag...@gmail.com> #43
Thanks everyone, work great. Just having problems with this chars: ÁÉÍÓÚ. Any clues?
in...@guttergeeks.co.nz <in...@guttergeeks.co.nz> #44
Is this still unresolved? I have set up scripted draft emails but without being able to put HTML in the draft I have to manually create hyperlinks or script-create a doc, the contents of which are sent via email after any required editing of the content.
I don't get why Google seem to have ignored such a basic piece of functionality, but that's another discussion...
I don't get why Google seem to have ignored such a basic piece of functionality, but that's another discussion...
am...@gmail.com <am...@gmail.com> #45
Yurec's solution works for me
function createDraftHTMLEmail(/* parameters for when working on recipient, subject, body, htmlBody */ )
{
var subject = "testing createDraftHTMLEmail";
var forScope = GmailApp.getInboxUnreadCount(); // needed for auth scope
var htmlBody = '<html><body>' + '<h1>World</h1>' + '</body></html>';
// myEmailAddress defined elsewhere
var message = 'From: Me <' + myEmailAddress + '>\r\n' +
'To: Me <'+ myEmailAddress +'>\r\n' +
'Subject: ' + subject + '\r\n' +
'Content-Type: text/html; charset=utf-8\r\n' +
'Content-Transfer-Encoding: quoted-printable\r\n\r\n' +
htmlBody;
Logger.log(message);
var draftBody = Utilities.base64Encode(message)
// replace some characters from the encoded output otherwise mail message is not valid.
draftBody = draftBody.replace(/\//g,'_').replace(/\+/g,'-');
var params = {method:"post",
contentType: "application/json",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions:true,
payload:JSON.stringify(
{ "message":
{ "raw": draftBody }
} )
};
var resp = UrlFetchApp.fetch("https://www.googleapis.com/gmail/v1/users/me/drafts ", params);
Logger.log(resp.getContentText());
}
function createDraftHTMLEmail(/* parameters for when working on recipient, subject, body, htmlBody */ )
{
var subject = "testing createDraftHTMLEmail";
var forScope = GmailApp.getInboxUnreadCount(); // needed for auth scope
var htmlBody = '<html><body>' + '<h1>World</h1>' + '</body></html>';
// myEmailAddress defined elsewhere
var message = 'From: Me <' + myEmailAddress + '>\r\n' +
'To: Me <'+ myEmailAddress +'>\r\n' +
'Subject: ' + subject + '\r\n' +
'Content-Type: text/html; charset=utf-8\r\n' +
'Content-Transfer-Encoding: quoted-printable\r\n\r\n' +
htmlBody;
Logger.log(message);
var draftBody = Utilities.base64Encode(message)
// replace some characters from the encoded output otherwise mail message is not valid.
draftBody = draftBody.replace(/\//g,'_').replace(/\+/g,'-');
var params = {method:"post",
contentType: "application/json",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions:true,
payload:JSON.stringify(
{ "message":
{ "raw": draftBody }
} )
};
var resp = UrlFetchApp.fetch("
Logger.log(resp.getContentText());
}
in...@guttergeeks.co.nz <in...@guttergeeks.co.nz> #46
Thanks ampl, that's awesome and works for a simple HTML message; really appreciated. When I add a hyperlink though, it isn't retained in the draft email (blue link-style text but no hyperlink), which is really annoying. Anyone know how to get a hyperlink to work in a draft email?
in...@guttergeeks.co.nz <in...@guttergeeks.co.nz> #48
Oshliaer, I can only take my hat off to you; you are Boss. This will make my like sooo much easier now that we'll have automated links in draft emails (mainly review requests post invoice). Adding them by hand really sucks! Truly, thank you; this will make our small business' admin cycle so much smoother.
mi...@gmail.com <mi...@gmail.com> #49
Hi, I would like to know if it's possible to attach a pdf file, which is in drive, to a draft email and how to do it.
Thank you!
Thank you!
lu...@gmail.com <lu...@gmail.com> #50
I'm not sure, but what I would do to find out would be to send a message with such attachment to myself and then check the message source. Then to paste it into your script, maybe with some necessary formatting or encoding...
ma...@gmail.com <ma...@gmail.com> #51
Hi guys,
Did anyone try to add a draft into an existing thread?
The given script here works good, but it creates a draft in it's own thread. And we need to create it in a thread that was already started before.
I've found this description in the documentation about Gmail REST API:
In order to be part of a thread, a message or draft must meet the following criteria:
- The requested threadId must be specified on the Message or Draft.Message you supply with your request.
- The References and In-Reply-To headers must be set in compliance with the RFC 2822 standard.
- The Subject headers must match.
(https://developers.google.com/gmail/api/guides/threads )
How can I specify these threadId, In-Reply-To and References values for a draft?
I tried dozens of different variations of the script from #29 from here inserting these parameters in different places, but the draft is still created in a new thread with the same name.
Any information about it would be useful, e.g. links on similar cases or descriptions.
Thanks a lot for your help!
Did anyone try to add a draft into an existing thread?
The given script here works good, but it creates a draft in it's own thread. And we need to create it in a thread that was already started before.
I've found this description in the documentation about Gmail REST API:
In order to be part of a thread, a message or draft must meet the following criteria:
- The requested threadId must be specified on the Message or Draft.Message you supply with your request.
- The References and In-Reply-To headers must be set in compliance with the RFC 2822 standard.
- The Subject headers must match.
(
How can I specify these threadId, In-Reply-To and References values for a draft?
I tried dozens of different variations of the script from #29 from here inserting these parameters in different places, but the draft is still created in a new thread with the same name.
Any information about it would be useful, e.g. links on similar cases or descriptions.
Thanks a lot for your help!
am...@gmail.com <am...@gmail.com> #52
Agree, that is my next step too.
am...@gmail.com <am...@gmail.com> #53
+1 thanks to Oshliaer. His script has fixed a bug I have been wrestling with - THANKS!!
pt...@gmail.com <pt...@gmail.com> #54
Been struggling to include the threadId and force the draft into an existing thread. I was able to do it in Python:
new = MIMEText(body)
new["Subject"] = msg_subject
new["To"] = msg_to
new["From"] = msg_from
#new["Content-Type"] = "text/html"
raw = base64.urlsafe_b64encode(new.as_string())
message = {'message': {'raw': raw, 'threadId': thread_id}} #"154f6c4099c66966"
draft = service.users().drafts().create(userId="me", body=message).execute()
Anyone able to replicate in apps script?
new = MIMEText(body)
new["Subject"] = msg_subject
new["To"] = msg_to
new["From"] = msg_from
#new["Content-Type"] = "text/html"
raw = base64.urlsafe_b64encode(new.as_string())
message = {'message': {'raw': raw, 'threadId': thread_id}} #"154f6c4099c66966"
draft = service.users().drafts().create(userId="me", body=message).execute()
Anyone able to replicate in apps script?
pe...@gmail.com <pe...@gmail.com> #55
Hi ,
I have found a solution which force Draft message in the needed thread.
Below is the code
function findEmail(){
var thread = GmailApp.getInboxThreads();
for (var i = 0; i < thread.length; i++){
var threadIn = thread[i].getMessages()[0] ;
var SEARCH1 = "";// replace with proper string subject to find the needed thread
var SEARCH2 = "";// replace with proper string FROM email to find the needed thread
if(threadIn.getSubject().indexOf(SEARCH1) > -1 && threadIn.getFrom().indexOf( SEARCH2) > -1){
Logger.log( thread[i].getId() );
var htmlBody = '<html><body>' + '<h1>World</h1>' + '</body></html>';
new1 = htmlBody
new1["Subject"] = threadIn.getSubject()
new1["To"] = threadIn.getTo();
new1["From"] = threadIn.getFrom();
raw = Utilities.base64Encode(new1.toString())
raw = raw.replace(/\//g,'_').replace(/\+/g,'-');
message = {'message': {'raw': raw, 'threadId': thread[i].getId()}} //"154f6c4099c66966"
Gmail.Users.Drafts.create(message, "me");
}
}
}
I have found a solution which force Draft message in the needed thread.
Below is the code
function findEmail(){
var thread = GmailApp.getInboxThreads();
for (var i = 0; i < thread.length; i++){
var threadIn = thread[i].getMessages()[0] ;
var SEARCH1 = "";// replace with proper string subject to find the needed thread
var SEARCH2 = "";// replace with proper string FROM email to find the needed thread
if(threadIn.getSubject().indexOf(SEARCH1) > -1 && threadIn.getFrom().indexOf( SEARCH2) > -1){
Logger.log( thread[i].getId() );
var htmlBody = '<html><body>' + '<h1>World</h1>' + '</body></html>';
new1 = htmlBody
new1["Subject"] = threadIn.getSubject()
new1["To"] = threadIn.getTo();
new1["From"] = threadIn.getFrom();
raw = Utilities.base64Encode(new1.toString())
raw = raw.replace(/\//g,'_').replace(/\+/g,'-');
message = {'message': {'raw': raw, 'threadId': thread[i].getId()}} //"154f6c4099c66966"
Gmail.Users.Drafts.create(message, "me");
}
}
}
pe...@gmail.com <pe...@gmail.com> #56
Seems like Google forgot to update status of this issue. I would propose to close this as API and documentation has been updated https://developers.google.com/gmail/api/v1/reference/users/drafts/create
am...@gmail.com <am...@gmail.com> #57
I have been playing around with this but it's not working as I would have thought. Interested to hear from anyone else looking into this.
My workflow is:
1. GAS creates a draft Gmail and stores the thread ID - works ok as I get what looks like a thread ID number.
2. Next I manually edit the email and press send. If I get the email thread ID from the sent folder it has changed to a new thread ID number.
Not sure if I am doing something wrong or my understand of message threading is not quite correct.
The background reason that I am trying to do this is to scan email messages sent and received and update a lead status tracking sheet. I do this manually at the moment.
My workflow is:
1. GAS creates a draft Gmail and stores the thread ID - works ok as I get what looks like a thread ID number.
2. Next I manually edit the email and press send. If I get the email thread ID from the sent folder it has changed to a new thread ID number.
Not sure if I am doing something wrong or my understand of message threading is not quite correct.
The background reason that I am trying to do this is to scan email messages sent and received and update a lead status tracking sheet. I do this manually at the moment.
fa...@thexs.ca <fa...@thexs.ca> #58
Comment on previous #59-2
Every time you edit a draft message, it changes the ID. That's the normal behavior.
Every time you edit a draft message, it changes the ID. That's the normal behavior.
am...@gmail.com <am...@gmail.com> #59
ek...@google.com <ek...@google.com>
al...@gmail.com <al...@gmail.com> #60
Would like this.
mi...@googlemail.com <mi...@googlemail.com> #61
make sure to use Utilities.base64EncodeWebSafe instead of base64Encode if you get an "invalid-value-for-bytestring-error"
Description
It's useful if GmailApp can create a draft message and store it in draft box of gmail GUI.
Notes:
Provide any additional information which might be useful here.
I am developing a sending daily report script. The story is ...
1. The script run by time trigger.
2. Get the list of items which were done today from Tasks API.
3. Create a draft mail message from the list and store it in draft box.
4. Put additional comment into the draft message manually by gmail GUI.
5. Send it to my boss.