无法在Google Apps脚本中将文件附加到SendGrid电子邮件

问题描述

多年来,我一直在使用StackOverflow信息,但从未发布过,但是我终于找到了让我感到困惑的东西,而且似乎在任何地方都没有直接的回应。我使用Google Apps脚本,并且已成功将脚本与SendGrid V3 Web API集成在一起以发送电子邮件包括带有附件的电子邮件。但是由于某种原因,我无法使其与从Google云端硬盘提取的PDF一起使用。这是我创建附件的方式:

var filePath = "https://drive.google.com/file/d/19rzCtnOMWw0ZZM4FViMWVZWkRRnsWx3L/view?usp=sharing";
var response = UrlFetchApp.fetch(filePath);
var attachment = Utilities.base64Encode(response.getContent());

...这是我传递给v3 / mail / send端点的对象:

"attachments": [{"content": attachment,"type": "application/pdf","filename": "testPDF.pdf"}]

执行此操作时,我会收到一封带有PDF附件的电子邮件,该附件的大小与Google云端硬盘中的PDF文件相同。但是,当我尝试打开它时,出现一条错误消息,告诉我无法预览文件,并告诉我尝试下载它。下载并打开时,出现“错误:无法加载PDF文档”消息。显然,我正在以某种方式创建不是正确的PDF文档的附件。上面有什么可以让别人发现我做错了吗?

我是自学成才,有点骇人听闻,所以如果我遗漏了一些明显的东西,或者如果我排除了关键信息,我会提前道歉。

解决方法

  • 使用getBlob()代替base64Encode(response.getContent())
  • 使用getAs(contentType)
  • 将请求类型的变量而不是对象作为附件传递。

工作示例:

function myFunction() {
  var filePath = "https://drive.google.com/file/d/19rzCtnOMWw0ZZM4FViMWVZWkRRnsWx3L/view?usp=sharing";
  var response = UrlFetchApp.fetch(filePath);
  var attachment = response.getBlob().getAs(MimeType.PDF);
  attachment.setName("testPDF.pdf");
  GmailApp.sendEmail("recipient","subject","body",{"attachments": [attachment]})
}

旁注:

如果该文件位于您的云端硬盘上,则无需使用UrlfetchApp,您就可以使请求更加轻松:

function myFunction2() {
  GmailApp.sendEmail("recipient",{
    "attachments": [ DriveApp.getFileById("19rzCtnOMWw0ZZM4FViMWVZWkRRnsWx3L").getAs(MimeType.PDF)]}
  )
}
,

好吧,经过更多的挖掘,我找到了想要的答案。最初令我感到困惑的是,我已经使用问题中发布的相同的UrlFetchApp和base64encode模式成功地在网上检索了PDF,并将其附加到SendGrid消息中。但是通过其他一些线程,我发现UrlFetchApp与Google云端硬盘文件的工作方式不同。在试用Drive API之后,我决定更仔细地研究为什么UrlFetchApp模式在“正常” URL下成功运行,并得出结论,这是因为UrlFetchApp响应具有一个名为“ getContent()”的方法,该方法返回二进制数据。因此,我回头研究了如何从存储在Google云端硬盘中的PDF获取二进制数据,并提出了以下模式:

  var docBytes = DriveApp.getFileById("19rzCtnOMWw0ZZM4FViMWVZWkRRnsWx3L").getBlob().getBytes();
  var doc = Utilities.base64Encode(docBytes);
  var attachments = [{"content": doc,"type": "application/pdf","filename": docTitle}];  

我保持对SendGrid端点v3 / mail / send端点的调用与以前相同:

"attachments": [{"content": attachment,"filename": "testPDF.pdf"}]

...现在可以使用了!再次感谢ziganotschka对此进行了介绍,并提供了一些线索以使我走上正确的轨道。