我正在使用Google应用程序脚本,并希望创建一个脚本,从草稿中提取邮件并在标签为“明天发送”时发送。 查找带有特定标签的草稿非常简单:
var threads = GmailApp.search('in:draft label:send-tomorrow');
但是我没有看到发送消息的API! 我看到的唯一选择是: - 打开信息 - 提取身体/附件/标题/从/到/ cc / bcc - 发送带有上述参数的新消息 - 破坏以前的草案
这看起来很烦人,而且我不确定它是否适用于嵌入式图像,多个附件等......
任何提示?
答案 0 :(得分:10)
我看到的唯一选择是: - 打开邮件 - 提取正文/附件/ title / from / to / cc / bcc - 发送带有上述参数的新邮件 - 销毁之前的草稿
这是Amit Agarawal this blog的确切主题。他的脚本完全符合您的描述,但不处理内联图像。对于那些,您可以调整this article的代码。
但你是对的 - 如果你不能发送愚蠢的东西,即使有一条草稿信息是什么意思?!
我们可以使用Google Apps脚本中的GMail API Users.drafts: send发送草稿。以下独立脚本执行此操作,并处理必要的授权。
完整脚本位于this gist。
/*
* Send all drafts labeled "send-tomorrow".
*/
function sendDayOldDrafts() {
var threads = GmailApp.search('in:draft label:send-tomorrow');
for (var i=0; i<threads.length; i++) {
var msgId = threads[0].getMessages()[0].getId();
sendDraftMsg( msgId );
}
}
/**
* Sends a draft message that matches the given message ID.
* Throws if unsuccessful.
* See https://developers.google.com/gmail/api/v1/reference/users/drafts/send.
*
* @param {String} messageId Immutable Gmail Message ID to send
*
* @returns {Object} Response object if successful, see
* https://developers.google.com/gmail/api/v1/reference/users/drafts/send#response
*/
function sendDraftMsg( msgId ) {
// Get draft message.
var draftMsg = getDraftMsg(msgId,"json");
if (!getDraftMsg(msgId)) throw new Error( "Unable to get draft with msgId '"+msgId+"'" );
// see https://developers.google.com/gmail/api/v1/reference/users/drafts/send
var url = 'https://www.googleapis.com/gmail/v1/users/me/drafts/send'
var headers = {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
};
var params = {
method: "post",
contentType: "application/json",
headers: headers,
muteHttpExceptions: true,
payload: JSON.stringify(draftMsg)
};
var check = UrlFetchApp.getRequest(url, params)
var response = UrlFetchApp.fetch(url, params);
var result = response.getResponseCode();
if (result == '200') { // OK
return JSON.parse(response.getContentText());
}
else {
// This is only needed when muteHttpExceptions == true
var err = JSON.parse(response.getContentText());
throw new Error( 'Error (' + result + ") " + err.error.message );
}
}
/**
* Gets the current user's draft messages.
* Throws if unsuccessful.
* See https://developers.google.com/gmail/api/v1/reference/users/drafts/list.
*
* @returns {Object[]} If successful, returns an array of
* Users.drafts resources.
*/
function getDrafts() {
var url = 'https://www.googleapis.com/gmail/v1/users/me/drafts';
var headers = {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
};
var params = {
headers: headers,
muteHttpExceptions: true
};
var check = UrlFetchApp.getRequest(url, params)
var response = UrlFetchApp.fetch(url, params);
var result = response.getResponseCode();
if (result == '200') { // OK
return JSON.parse(response.getContentText()).drafts;
}
else {
// This is only needed when muteHttpExceptions == true
var error = JSON.parse(response.getContentText());
throw new Error( 'Error (' + result + ") " + error.message );
}
}
/**
* Gets the draft message ID that corresponds to a given Gmail Message ID.
*
* @param {String} messageId Immutable Gmail Message ID to search for
*
* @returns {String} Immutable Gmail Draft ID, or null if not found
*/
function getDraftId( messageId ) {
if (messageId) {
var drafts = getDrafts();
for (var i=0; i<drafts.length; i++) {
if (drafts[i].message.id === messageId) {
return drafts[i].id;
}
}
}
// Didn't find the requested message
return null;
}
/**
* Gets the draft message content that corresponds to a given Gmail Message ID.
* Throws if unsuccessful.
* See https://developers.google.com/gmail/api/v1/reference/users/drafts/get.
*
* @param {String} messageId Immutable Gmail Message ID to search for
* @param {String} optFormat Optional format; "object" (default) or "json"
*
* @returns {Object or String} If successful, returns a Users.drafts resource.
*/
function getDraftMsg( messageId, optFormat ) {
var draftId = getDraftId( messageId );
var url = 'https://www.googleapis.com/gmail/v1/users/me/drafts'+"/"+draftId;
var headers = {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
};
var params = {
headers: headers,
muteHttpExceptions: true
};
var check = UrlFetchApp.getRequest(url, params)
var response = UrlFetchApp.fetch(url, params);
var result = response.getResponseCode();
if (result == '200') { // OK
if (optFormat && optFormat == "JSON") {
return response.getContentText();
}
else {
return JSON.parse(response.getContentText());
}
}
else {
// This is only needed when muteHttpExceptions == true
var error = JSON.parse(response.getContentText());
throw new Error( 'Error (' + result + ") " + error.message );
}
}
要使用Google的API,我们需要为当前用户提供OAuth2令牌 - 就像我们为高级服务所做的那样。这是使用ScriptApp.getOAuthToken()
完成的。
将代码复制到您自己的脚本后,打开Resources - &gt;高级Google服务,打开Google Developers Console的链接,并为您的项目启用Gmail API。
只要脚本包含至少一个需要用户权限的GMailApp方法,就会为OAuthToken正确设置身份验证范围。在此示例中,由GmailApp.search()
中的sendDayOldDrafts()
处理;但是对于保险,您可以使用API直接在函数中包含不可访问的函数调用。
答案 1 :(得分:4)
我是使用GmailMessage.forward方法完成的。
它适用于上传图片和附件,但我必须设置主题以避免前缀&#34; Fwd:&#34;和用户名,因为它只向收件人显示用户电子邮件。
我没有办法处理草稿,所以我只是删除标签以防止再次发送。
<强>脚本:强>
function getUserFullName(){
var email = Session.getActiveUser().getEmail();
var contact = ContactsApp.getContact(email);
return contact.getFullName();
}
function testSendTomorrow(){
var threads = GmailApp.search('in:draft label:send-tomorrow');
if(threads.length == 0){
return;
}
var labelSendTomorrow = GmailApp.getUserLabelByName("send-tomorrow");
for(var i = 0; i < threads.length; i++){
var messages = threads[i].getMessages();
for(var j = 0; j < messages.length; j++){
var mssg = messages[j];
if(mssg.isDraft()){
mssg.forward(mssg.getTo(), {
cc: mssg.getCc(),
bcc: mssg.getBcc(),
subject: mssg.getSubject(),
name: getUserFullName()
});
}
}
threads[i].removeLabel(labelSendTomorrow);
}
}
答案 2 :(得分:1)
您可以搜索所有草稿,然后毫无问题地发送该特定草稿。
function sendMessage(id){
GmailApp.getDrafts().forEach(function (draft) {
mes = draft.getMessage()
if (mes.getId() == id) {
draft.send()
}
})
}
答案 3 :(得分:0)
更简单的替代方法是使用gmail api而不是gmailApp:
col
上面的函数示例在https://script.google.com的gs脚本中使用。 它需要draftId(而不是消息Id),草稿将被发送。图像和附件都可以! 信息:https://developers.google.com/gmail/api/v1/reference/users/drafts/send
答案 4 :(得分:0)
我在这里很陌生,没有足够的“信誉”来发表评论,因此无法评论Mogsdad的原始答案,因此我必须创建一个新答案:
我已经调整了Mogsdad的解决方案,使其不仅支持全新消息,还支持答复/转发现有线程。
要在现有线程上使用它,应首先创建答复/转发,然后才标记该线程。我的代码还支持多个标签并设置这些标签。
我为此创建了一个新的要点,分叉了莫格斯达德(Mogsdad),https://gist.github.com/hadasfester/81bfc5668cb7b666b4fd6eeb6db804c3
我仍然需要在文档中添加一些屏幕快照链接,但否则可以使用了,我自己一直在使用它。希望您觉得有用。
也在此内联:
/**
* This script allows you to mark threads/drafts with a predetermined label and have them get sent the next time your trigger
* sets off.
*
* Setup instructions:
* 1. Make a copy of this script (File -> Make a copy)
* 2. Follow the "Authorization" instructions on https://stackoverflow.com/a/27215474. (If later during setup/testing you get
* another permissions approval dialog, approve there as well).
* 2. I created two default labels, you can edit/add your own. See "TODO(user):" below. After that, to create them in gmail,
* choose "setUpLabel" function above and click the play button (TODO: screenshot). Refresh your gmail tab, you should see
* the new labels.
* 3. Click the clock icon above (TODO: screenshot) and set time triggers, e.g. like so: (TODO: screenshot)
* 4. I recommend also setting up error notifications: (TODO: screenshot).
*
* Testing setup:
* When you're first setting this up, if you want to test it, create a couple
* of drafts and label them. Then, in this
* script, select "sendWeekStartDrafts" or "sendTomorrowDrafts" in the function dropdown
* and press play. This manually triggers the script (instead of relying on the
* timer) so you can see how it works.
*
* Usage instructions:
* 1. To get a draft sent out on the next trigger, mark your draft with the label you chose.
* NOTE: If your draft is a reply to a thread, make sure you first create the draft and only then set the label on the
* thread, not the other way around.
* That's it! Upon trigger your draft will be sent and the label will get removed from the thread.
*
* Some credits and explanation of differences/improvements from other existing solutions:
* 1. This script was adapted from https://stackoverflow.com/a/27215474 to also support replying existing threads, not only
* sending brand new messages.
* 2. Other solutions I've run into are based on creating a new message, copying it field-by-field, and sending the new one,
* but those have many issues, some of which are that they also don't handle replies and forwards very elegantly.
*
* Enjoy!
**/
var TOMORROW_LABEL = '!send-tomorrow';
var WEEK_START_LABEL = '!send-week-start';
// TODO(user): add more labels here.
/**
* Set up the label for delayed send!
**/
function setUpLabels() {
GmailApp.createLabel(TOMORROW_LABEL);
GmailApp.createLabel(WEEK_START_LABEL);
// TODO(user): add more labels here.
}
function sendTomorrowDrafts() {
sendLabeledDrafts(TOMORROW_LABEL);
}
function sendWeekStartDrafts() {
sendLabeledDrafts(WEEK_START_LABEL);
}
// TODO(user): add more sendXDrafts() functions for your additional labels here.
/*
* Send all drafts labeled $MY_LABEL.
* @param {String} label The label for which to send drafts.
*/
function sendLabeledDrafts(label) {
var threads = GmailApp.search('in:draft label:' + label);
for (var i=0; i<threads.length; i++) {
var thread = threads[i];
var messages = thread.getMessages();
var success = false;
for (var j=messages.length-1; j>=0; j--) {
var msgId = messages[j].getId();
if (sendDraftMsg( msgId )) {
success = true;
}
}
if (!success) { throw Error( "Failed sending msg" ) };
if (success) {
var myLabel = GmailApp.getUserLabelByName(label);
thread.removeLabel(myLabel);
}
}
}
/**
* Sends a draft message that matches the given message ID.
* See https://developers.google.com/gmail/api/v1/reference/users/drafts/send.
*
* @param {String} messageId Immutable Gmail Message ID to send
*
* @returns {Object} Response object if successful, see
* https://developers.google.com/gmail/api/v1/reference/users/drafts/send#response
*/
function sendDraftMsg( msgId ) {
// Get draft message.
var draftMsg = getDraftMsg(msgId,"json");
if (!getDraftMsg(msgId)) return null;
// see https://developers.google.com/gmail/api/v1/reference/users/drafts/send
var url = 'https://www.googleapis.com/gmail/v1/users/me/drafts/send'
var headers = {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
};
var params = {
method: "post",
contentType: "application/json",
headers: headers,
muteHttpExceptions: true,
payload: JSON.stringify(draftMsg)
};
var check = UrlFetchApp.getRequest(url, params)
var response = UrlFetchApp.fetch(url, params);
var result = response.getResponseCode();
if (result == '200') { // OK
return JSON.parse(response.getContentText());
}
else {
// This is only needed when muteHttpExceptions == true
return null;
}
}
/**
* Gets the current user's draft messages.
* Throws if unsuccessful.
* See https://developers.google.com/gmail/api/v1/reference/users/drafts/list.
*
* @returns {Object[]} If successful, returns an array of
* Users.drafts resources.
*/
function getDrafts() {
var url = 'https://www.googleapis.com/gmail/v1/users/me/drafts';
var headers = {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
};
var params = {
headers: headers,
muteHttpExceptions: true
};
var check = UrlFetchApp.getRequest(url, params)
var response = UrlFetchApp.fetch(url, params);
var result = response.getResponseCode();
if (result == '200') { // OK
return JSON.parse(response.getContentText()).drafts;
}
else {
// This is only needed when muteHttpExceptions == true
var error = JSON.parse(response.getContentText());
throw new Error( 'Error (' + result + ") " + error.message );
}
}
/**
* Gets the draft message ID that corresponds to a given Gmail Message ID.
*
* @param {String} messageId Immutable Gmail Message ID to search for
*
* @returns {String} Immutable Gmail Draft ID, or null if not found
*/
function getDraftId( messageId ) {
if (messageId) {
var drafts = getDrafts();
for (var i=0; i<drafts.length; i++) {
if (drafts[i].message.id === messageId) {
return drafts[i].id;
}
}
}
// Didn't find the requested message
return null;
}
/**
* Gets the draft message content that corresponds to a given Gmail Message ID.
* See https://developers.google.com/gmail/api/v1/reference/users/drafts/get.
*
* @param {String} messageId Immutable Gmail Message ID to search for
* @param {String} optFormat Optional format; "object" (default) or "json"
*
* @returns {Object or String} If successful, returns a Users.drafts resource.
*/
function getDraftMsg( messageId, optFormat ) {
var draftId = getDraftId( messageId );
var url = 'https://www.googleapis.com/gmail/v1/users/me/drafts'+"/"+draftId;
var headers = {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
};
var params = {
headers: headers,
muteHttpExceptions: true
};
var check = UrlFetchApp.getRequest(url, params)
var response = UrlFetchApp.fetch(url, params);
var result = response.getResponseCode();
if (result == '200') { // OK
if (optFormat && optFormat == "JSON") {
return response.getContentText();
}
else {
return JSON.parse(response.getContentText());
}
}
else {
// This is only needed when muteHttpExceptions == true
return null;
}
}
答案 5 :(得分:0)
首先,GmailDraft
现在具有您可以直接调用的send()
函数。参见:https://developers.google.com/apps-script/reference/gmail/gmail-draft#send()
他们的代码示例:
var draft = GmailApp.getDrafts()[0]; // The first draft message in the drafts folder
var msg = draft.send(); // Send it
Logger.log(msg.getDate()); // Should be approximately the current timestamp
第二,既然Google已经发布了预定的发送,甚至可能甚至不需要它。
Send
旁边的箭头