如何在GAS中使用高级Gmail服务发送Gmail邮件?

时间:2018-06-24 13:09:22

标签: google-apps-script gmail-api

我的目标是使用GAS中的Gmail高级服务检索现有的收件箱邮件,修改主题行,然后调用Gmail.Users.Messages.insert()将新邮件粘贴到收件箱中。 我知道我可以通过上传到Gmail API端点来实现此结果,但是我试图了解高级服务的工作原理并减少代码的详细程度。

根据文档,“ insert()”方法接受消息资源作为编码字符串。格式如下

Gmail.Users.Messages.insert({"raw":Utilities.base64EncodeWebSafe(message)}, "me");

传递给编码功能的'message'参数应该是表示消息内容的Byte数组。我可以通过检查其“原始”属性来获取现有收件箱邮件的字节。

var message = Gmail.Users.Messages.get("me", messageId, {format:"raw"});
var bytes = message.raw;

问题是,当您将{format:“ raw”}作为可选参数传递给'get()'方法时,您将无法再检查邮件的属性并访问'payload'属性。如果改为传递{format:“ full”},则有效负载在那里,但不包括“ raw”属性。

您可以使用Gmail.newMessage()构造新消息并手动设置属性,但是我不知道如何通过“ insert()”和“ get()”方法使用它。 “ newMessage()”方法的返回类型为“消息”,但高级Gmail服务中似乎没有哪个方法可以接受这种类型的参数。我仍然需要获取消息的字节并对其进行编码。但是,

var message = Gmail.newMessage();
(Logger.log(message.raw));  // logs  undefined

也许我错过了一些东西,但看起来像是一个巨大的22。我不明白,即使您无法轻松地将邮件生成器Gmail.newMessage()方法与应该被Gmail API封装的其他方法一起使用,为什么也不存在。

3 个答案:

答案 0 :(得分:3)

高级服务中以new为前缀的方法用于生成空的 资源 对象。它们仅出于在Apps脚本编辑器中完成代码的目的而存在。为了有效地使用它们,您必须在这些方法产生的对象上设置所需的属性,然后将它们传递给需要该资源的方法。

因此,在您的情况下,您将创建如下消息:

var messageResource = Gmail.newMessage();

messageResource.raw = Utilities.base64EncodeWebSafe([messageData]);

然后将其传递给insert方法:

Gmail.Users.Messages.insert(messageResource, "me");

它们似乎是多余的,但有些人可能会发现这些资源对象上的代码完成很有价值。

就个人而言,我倾向于避免使用它们,而只是根据需要传入对象(就像您在初始示例中一样)。一旦知道了这些资源对象的必要属性,就可以放下那些“训练轮”,而只需使用嵌入式对象即可。

关于此问题:

  

问题是,当您将{format:“ raw”}作为可选参数传递给'get()'方法时,您将无法再检查邮件的属性并访问'payload'属性。如果您改为传递{format:“ full”},则有效负载就在其中,而不是“ raw”属性。

使用Gmail.Users.Messages.get()方法的情况。如果查看documentation,您会发现必须设置format参数,因此一次调用无法获得所需的所有信息。但是,您要做的就是打两个电话。一种将格式设置为“完整” ,另一种将格式设置为“原始” ,然后您将拥有所需的内容。该代码可能不是最优雅的,但可以实现您的目标。


要解决您评论中提到的问题;我怀疑您可能需要利用media uploads。插入方法具有多个签名,如以下屏幕截图所示: enter image description here 您可能需要利用第二个或第三个选项来上载消息数据。编辑有效负载对象并更改主题行,并将其传递到消息资源中,然后将原始数据转换为blob Utilities.newBlob([raw Byte[]])(在转换之前,需要将原始base64编码的字符串转换为字节数组)到Blob对象),然后将其作为第三个参数传入。不确定是否可以,但是值得一试。

答案 1 :(得分:1)

我能够使用Regex找到快捷快捷的快捷方式。支持Dimu的解决方案,因为从长远来看它可能会更好,但是我需要更深入地研究。

var message = GmailApp.getMessageById(messageId);
var rawContent = message.getRawContent();
// Regex logic for matching the subject line
rawContent = rawContent.replace(oldSubjectLine, newSubjectLine);
var encodedMsg = Utilities.base64EncodeWebSafe(rawContent);

var message = Gmail.newMessage();
message.raw = encodedMsg;

Gmail.Users.Messages.insert(message, "me");

答案 2 :(得分:0)

仅基于此处评论者之间共同创建的内容,我将共享创建的代码,以便通过其ID成功获取草稿,修改收件人并使用中的“高级Gmail服务”发送邮件加油站。这个解决方案花了我几天的时间。

function sendFromDraft (id, recipient) {
  // get the draft by ID and its raw content
  var message = GmailApp.getMessageById(id);
  var rawContent = message.getRawContent();
  
  // determines if recipient is already defined in draft, routes accordingly, updates with new recipient
  var addRecipient = 'To: <' + recipient + '>';
  var recipientFromTemplate = rawContent.match(/To:.[^>]+>/);
  if (recipientFromTemplate === null) {
    var fromField = rawContent.match(/From:.[^>]+>/);
    var updateWithRecipient = fromField + '\n' + addRecipient;
    rawContent = rawContent.replace(fromField, updateWithRecipient);    
  } else {
    rawContent = rawContent.replace(recipientFromTemplate, addRecipient);
  }
  
  var message = Gmail.newMessage();
  var encodedMsg = Utilities.base64EncodeWebSafe(rawContent);

  message.raw = encodedMsg;
  
  Gmail.Users.Messages.send(message, "me", Utilities.newBlob(rawContent, "message/rfc822"));
};

我必须大喊Romain Vialard和上面的注释者,以添加使我能够开发工作代码的关键信息。我希望这对以后的其他开发人员有帮助。