使用带有更改收件人的AppScript回复Gmail中的电子邮件最终会在新主题中结束 [英] Reply to an email in Gmail with AppScript with changed recipients ends up in a new thread

查看:146
本文介绍了使用带有更改收件人的AppScript回复Gmail中的电子邮件最终会在新主题中结束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的邮箱中有一封电子邮件,我希望AppScript程序只使用我和一个特殊的Google群组作为收件人来回复它。这样做的目的是与程序进行通信,因为一旦程序处理了有关回复正文中处理的必要细节,程序就会回复该消息。原始邮件中除了我之外可能还有其他收件人,我不希望程序将回复发送给他们。

I have an email in my mailbox and I want the AppScript program to reply to it with just me and a special google group as the recipients. The purpose of this is communication of the program with me as the program replies to the message once it has processed it with necessary details about the processing in the reply body. There might also be other recipients apart from me in the original message and I don't want the program to send the reply to them.

所以我需要回复一个更改了一组收件人。当我在Gmail GUI中执行它时它工作得很好,我点击回复,更改收件人,发送邮件,回复最终在原始帖子中。但是,当我在脚本中执行此操作时,回复始终以新线程结束。最初我认为Gmail会根据电子邮件的主题做出决定,但似乎还有更多内容(也许它最近发生了变化,因为我认为它曾经以这种方式工作)。

So I need to reply with a changed set of recipients. When I do it in the Gmail GUI it works just fine, I hit reply, change the recipients, send the message and the reply ends up in the original thread. However when I do it in the script the reply always ends up in a new thread. Originally I thought Gmail decides based on the subject of the email but it seems there's more to it (perhaps it has recently changed as I think it used to work that way).

我尝试了多种略有不同的方法,其中一种是:

I tried multitude of slightly different approached, one of them being:

var messageBody = "foo";
var newRecipients = "me@gmail.com, my-group@gmail.com";
var messageToReplyTo = ...;
var advancedParams = {from : "my-alias@gmail.com"};

var replyDraft = messageToReplyTo.createDraftReply(messageBody);
var replySubject = replyDraft.getMessage().getSubject();
var replyBody = replyDraft.getMessage().getBody();

replyDraft.update(newRecipients, replySubject, replyBody, advancedParams);

replyDraft.send();


推荐答案

您需要做几件有趣的事情为了达到这个目的,你可以毫不费力地做到这一点。您一定要查看草稿指南。

There are a couple fun things you need to do in order to achieve this, but you can do it without too much trouble. You should definitely review the guide to Drafts.

根据API规范:


要成为线程的一部分,消息或草稿必须符合以下条件:

In order to be part of a thread, a message or draft must meet the following criteria:


  1. 必须在消息或<$ c $上指定所请求的 threadId c> Draft.Message 您提供了请求。

  2. 参考 In-Reply-To 标题必须符合RFC 2822标准。

  3. 主题标题必须匹配。

  1. The requested threadId must be specified on the Message or Draft.Message you supply with your request.
  2. The References and In-Reply-To headers must be set in compliance with the RFC 2822 standard.
  3. The Subject headers must match.


首先,您需要获得对要更新的草稿的引用。这可能是最简单的使用 GmailApp

To start, you need to get a reference to the draft you want to update. This is probably simplest by using GmailApp:

const thread = /** get the thread somehow */;
const newBody = /** your plaintext here */;
const reply = thread.createDraftReply(newBody);

Gmail&草稿是草稿是服务器资源的不可变消息。如果您更改了其中任何一项,则会更改所有内容。因此,要更改标头值(如收件人地址),您需要完全重建邮件。这就是使用的原因 GmailApp 更新草稿的方法无法维护现有的线程信息 - 您无法将其指定为构建新邮件的高级选项之一。因此,您必须使用Gmail REST API执行此任务:

The primary issue with Gmail & Drafts is that a Draft is an immutable message to server resources. If you change any of it, you change all of it. Thus, to change a header value such as the recipient address, you need to completely rebuild the message. This is why using the GmailApp methods to update a draft fail to maintain the existing thread information - you can't specify it as one of the advanced options for building the new message. Thus, you must use the Gmail REST API for this task:

const rawMsg = Gmail.Users.Drafts.get("me", reply.getId(), {format: "raw"}).message;

要更新草稿,您需要提供以base64编码的RFC 2822格式的消息。如果您愿意将丰富的格式邮件部分转换为此类有效字符串,则无论如何都要使用非原始格式,因为您可以直接访问 message.payload

To update a draft, you need to supply an RFC 2822 formatted message encoded in base64. If you are comfortable converting the rich format message parts into such a valid string, by all means work with the non-raw format, as you have direct access to the headers in the message.payload.

要处理原始消息,请知道Apps Script将描述的base64编码字符串转换为上述调用中的字节数组。然后飞跃将字节数组视为字符串字节,具体而言, charCode s:

To work with the raw message, know that Apps Script casts the described base64 encoded string to a byte array in the above call. The leap is then to treat that byte array as string bytes, specifically, charCodes:

const msg_string = rawMsg.raw.reduce(function (acc, b) { return acc + String.fromCharCode(b); }, "");
console.log({message: "Converted byte[] to str", bytes: rawMsg.raw, str: msg_string});

将消息作为字符串后,您可以使用正则表达式更新所需的标题:

Once you have the message as a string, you can use regular expressions to update your desired headers:

const pattern = /^To: .+$/m;
var new_msg_string = msg_string.replace(pattern, "To: <....>");
// new_msg_string += ....

由于Gmail API端点为 update a 草稿 需要一个base64网络安全编码字符串,你可以计算:

Since the Gmail API endpoint to update a Draft expects a base64 web-safe encoded string, you can compute that:

const encoded_msg = Utilities.base64EncodeWebSafe(new_msg_string);

唯一剩下的是执行调用(和/或 发送 更新后的草稿)。

And the only remaining bit is to perform the call (and/or send the updated draft).

const resource = {
  id: <draft id>, // e.g. reply.getId()
  message: {
    threadId: <thread id>, // e.g. thread.getId()
    raw: encoded_msg
  }
}
const resp = Gmail.Users.Drafts.update(resource, "me", reply.getId());
const sent_msg = Gmail.Users.Drafts.send({id: resp.id}, "me");
console.log({message: "Sent the draft", msg: sent_msg});

我不声称处理字节 Message.raw 属性返回的$ c>数组是100%正确的,只是看起来正确并且没有导致我发送的测试消息中的任何错误。可能还有一种更简单的方法,因为Apps脚本服务有 Drafts.update 端点,它接受 Blob 输入我没有调查过如何使用它。

I don't claim that the handling of the Byte array returned from the Message.raw property is 100% correct, only that it seems correct and didn't result in any errors in the test message I sent. There may also be an easier approach, as the Apps Script service has a Drafts.update endpoint which accepts a Blob input and I have not investigated how one would use that.

这篇关于使用带有更改收件人的AppScript回复Gmail中的电子邮件最终会在新主题中结束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆