简体   繁体   English

Google Apps 脚本:MailApp.sendEmail() 除了 TEXT 和 HTML 文件之外什么都不能发送,没有别的了吗?

[英]Google Apps Script: MailApp.sendEmail() can't send anything but TEXT and HTML files, nothing else?

I'm trying to attach a file to an email I send in Google Apps Script with MailApp.sendEmail().我正在尝试将文件附加到我使用 MailApp.sendEmail() 在 Google Apps 脚本中发送的电子邮件中。 In the browser JavaScript I read in the file manually with this code because I've already processed the equivalent of the submit button in my HTML form, and it works:在浏览器 JavaScript 中,我使用此代码手动读取文件,因为我已经处理了 HTML 表单中提交按钮的等效项,并且它可以工作:

  var file = document.getElementById('myfile');
  var fileInfo = [];
  if(file.files.length)        // if there is at least 1 file
  {
    if (file.files[0].size < maxEmailAttachmentSize)  // and its size is < 25M
    {
      var reader = new FileReader();
      reader.onload = function(e)
      {
        fileInfo[0] = e.target.result;
      };
      reader.readAsBinaryString(file.files[0]);
      fileInfo[1] = file.files[0].name;
      fileInfo[2] = file.files[0].type;
      fileInfo[3] = file.files[0].size;
    }
    console.log(fileInfo);   // here I see the full file and info. All looks correct.
  }

Then I send it up to the server.然后我将它发送到服务器。

  google.script.run.withSuccessHandler(emailSent).sendAnEmail(fileInfo);

On the server I pull out the fields and send the email like so:在服务器上,我拉出字段并发送电子邮件,如下所示:

  var fname    = fileInfo[1];
  var mimeType = fileInfo[2];
  var fblob    = Utilities.newBlob(fileInfo[0], mimeType, fname);
  // all looks right in the Logger at this point

  try {
    GmailApp.sendEmail(emaiRecipient, emailSubject, emailBody, 
      {
        name: 'Email Sender',  // email sender
        attachments: [fblob]
      }
    );
  catch …

This works fine when the file is a text file or HTML file but doesn't when the file is anything else.当文件是文本文件或 HTML 文件时,这可以正常工作,但当文件是其他文件时则不行。 The file is sent but it's empty and apparently corrupt.该文件已发送,但它是空的并且显然已损坏。 Can anyone see what's wrong with this code?任何人都可以看到这段代码有什么问题吗? (It doesn't work with MailApp.sendEmail() either.) I did see in another stackoverflow post that the document has to be saved once, but that is something I definitely don't want to do. (它也不适用于 MailApp.sendEmail()。)我确实在另一个 stackoverflow 帖子中看到文档必须保存一次,但这是我绝对不想做的事情。 Isn't there any other way?没有其他办法了吗? What am I missing?我错过了什么?

Modification points:改装要点:

  • FileReader works with the asynchronous process. FileReader 与异步进程一起工作。 This has already been mentioned by Rubén's comment . 鲁本的评论中已经提到了这一点。
  • In the current stage, when the binary data is sent to Google Apps Script side, it seems that it is required to convert it to the string and byte array.在目前阶段,当二进制数据发送到Google Apps Script端时,似乎需要将其转换为字符串和字节数组。 This has already been mentioned by TheMaster's comment . TheMaster的评论已经提到了这一点
  • In order to use your Google Apps Script, in this case, I think that converting the file content to the byte array of int8Array might be suitable.为了使用您的 Google Apps 脚本,在这种情况下,我认为将文件内容转换为 int8Array 的字节数组可能是合适的。
    • For this, I used readAsArrayBuffer instead of readAsBinaryString .为此,我使用了readAsArrayBuffer而不是readAsBinaryString

When above points are reflected to your script, it becomes as follows.当以上几点反映到你的脚本中时,它变成如下。

Modified script:修改后的脚本:

HTML&Javascript side: HTML&Javascript 方面:

// Added
function getFile(file) {
  return new Promise((resolve, reject) => {
    var reader = new FileReader();
    reader.onload = (e) => resolve([...new Int8Array(e.target.result)]);
    reader.onerror = (err) => reject(err);
    reader.readAsArrayBuffer(file);
  });
}

async function main() {  // <--- Modified
  var file = document.getElementById('myfile');
  var fileInfo = [];
  if(file.files.length) {
    if (file.files[0].size < maxEmailAttachmentSize) {
      fileInfo[0] = await getFile(file.files[0]);  // <--- Modified
      fileInfo[1] = file.files[0].name;
      fileInfo[2] = file.files[0].type;
      fileInfo[3] = file.files[0].size;
    }
    console.log(fileInfo);   // here I see the full file and info. All looks correct.
    google.script.run.withSuccessHandler(emailSent).sendAnEmail(fileInfo);
  }
}
  • Although I'm not sure about your whole script from your question, at the modified script, it supposes that main() is run.尽管我不确定您的问题的整个脚本,但在修改后的脚本中,它假设main()已运行。 When main() is run, the file is converted to the byte array and put it to fileInfo[0] .main()运行时,文件被转换为字节数组并将其放入fileInfo[0]
  • At Google Apps Script side, from fileInfo , var fblob = Utilities.newBlob(fileInfo[0], mimeType, fname);在 Google Apps Script 端,从fileInfovar fblob = Utilities.newBlob(fileInfo[0], mimeType, fname); has the correct blob for Google Apps Script.具有适用于 Google Apps 脚本的正确 blob。

Google Apps Script side: Google Apps 脚本方面:

In this modification, your Google Apps Script is not modified.在此修改中,您的 Google Apps 脚本不会被修改。

References:参考:

Added:添加:

This code looks good but we can't use it because we are running on the Rhino JavaScript engine, not V8.这段代码看起来不错,但我们不能使用它,因为我们运行的是 Rhino JavaScript 引擎,而不是 V8。 We don't have support for newer JavaScript syntax.我们不支持较新的 JavaScript 语法。 Could you give us an example of how it's done with older syntax?你能给我们一个例子来说明它是如何使用旧语法完成的吗? Ref 参考

From your above comment, I modified as follows.根据您的上述评论,我修改如下。

Modified script:修改后的脚本:

HTML&Javascript side: HTML&Javascript 方面:

function main() {
  var file = document.getElementById('myfile');
  var fileInfo = [];
  if(file.files.length) {
    if (file.files[0].size < maxEmailAttachmentSize) {
      var reader = new FileReader();
      reader.onload = function(e) {
        var bytes = new Int8Array(e.target.result);
        var ar = [];
        for (var i = 0; i < bytes.length; i++) {
          ar.push(bytes[i]);
        }
        fileInfo[0] = ar;
        fileInfo[1] = file.files[0].name;
        fileInfo[2] = file.files[0].type;
        fileInfo[3] = file.files[0].size;
        console.log(fileInfo);   // here I see the full file and info. All looks correct.
        google.script.run.withSuccessHandler(emailSent).sendAnEmail(fileInfo);
      }
      reader.onerror = function(err) {
        reject(err);
      }
      reader.readAsArrayBuffer(file.files[0]);
    }
  }
}

Google Apps Script side: Google Apps 脚本方面:

In this modification, your Google Apps Script is not modified.在此修改中,您的 Google Apps 脚本不会被修改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM