Javascript 对的请求失败https://docs.google.com 返回代码401-保存并通过电子邮件发送来自Google Sheets的PDF文件

Javascript 对的请求失败https://docs.google.com 返回代码401-保存并通过电子邮件发送来自Google Sheets的PDF文件,javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,我基本上没有Javascript方面的经验,但对Python有一点了解,所以我想我能胜任弗兰肯斯坦的任务,把我在网上找到的两个预先制作好的脚本放在一起。我们的想法是查看数据列表,然后将相应电子表格的PDF发送到所需的电子邮件地址。我在下面复制了我的尝试 // This constant is written in for rows for which an email has been sent successfully. var EMAIL_SENT = 'EMAIL_SENT'; func

我基本上没有Javascript方面的经验,但对Python有一点了解,所以我想我能胜任弗兰肯斯坦的任务,把我在网上找到的两个预先制作好的脚本放在一起。我们的想法是查看数据列表,然后将相应电子表格的PDF发送到所需的电子邮件地址。我在下面复制了我的尝试

// This constant is written in for rows for which an email has been sent successfully.
var EMAIL_SENT = 'EMAIL_SENT';

function sendEmails2() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var startRow = 16; // First row of data to process
  var numRows = 1; // Number of rows to process
  var dataRange = sheet.getRange(startRow, 1, numRows, 6); // Fetch the range of cells
  var data = dataRange.getValues(); // Fetch values for each row in the Range.

  const token = ScriptApp.getOAuthToken();
  const ss = SpreadsheetApp.getActiveSpreadsheet(); // Get the currently active spreadsheet URL (link)
  const subject = 'Monthly Invoice'; // Subject of email message
  const url = 'https://docs.google.com/spreadsheets/d/SS_ID/export?'.replace('SS_ID', ss.getId()); // Base URL 
  const exportOptions = // Specify PDF export parameters From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
    'exportFormat=pdf&format=pdf' + // export as pdf / csv / xls / xlsx
    '&size=A4' + // paper size legal / letter / A4
    '&portrait=true' + // orientation, false for landscape
    '&fitw=true&source=labnol' + // fit to page width, false for actual size
    '&sheetnames=false&printtitle=false' + // hide optional headers and footers
    '&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
    '&fzr=false' + // do not repeat row headers (frozen rows) on each page
    '&gid='; // the sheet's Id
  const sheets = ss.getSheets();

  for (var i = 0; i < data.length; ++i) {
    var row = data[i];
    var emailAddress = row[4];
    var message = row[3];
    var emailSent = row[5];

    var client_id = row[0];
    var client_sheet = ss.getSheetByName(client_id);

    if (emailSent !== EMAIL_SENT) { // Prevents sending duplicates
      const blobs = []; // make an empty array to hold your fetched blobs

      // Convert individual worksheets to PDF
      const response = UrlFetchApp.fetch(url + exportOptions + client_sheet, {
        headers: {
          Authorization: 'Bearer ${token}'
        }
      });

      // convert the response to a blob and store in our array
      blobs[i] = response.getBlob().setName('${client_sheet}.pdf');

    // If allowed to send emails, send the email with the PDF attachment - 500 emails per day standard
    if (MailApp.getRemainingDailyQuota() > 0)
      GmailApp.sendEmail(emailAddress, subject, message, {
        attachments: [blobs[i]]
      });
    sheet.getRange(startRow + i, 6).setValue(EMAIL_SENT);
    // Make sure the cell is updated right away in case the script is interrupted
    SpreadsheetApp.flush();
  }
}
    // create new blob that is a zip file containing our blob array
    // const zipBlob = Utilities.zip(blobs).setName(`${ss.getName()}.zip`);
    // optional: save the file to the root folder of Google Drive
    // DriveApp.createFile(zipBlob);
}
然而,我现在遇到了这个错误——老实说,我迷路了

请求返回代码401失败

对的请求失败https://docs.google.com 返回代码401。截断服务器响应:未经授权的错误401使用muteHttpExceptions选项检查完整响应行39,文件发送\u电子邮件

如果有帮助,第39行是: const response=UrlFetchApp.fetchurl+exportOptions+client\u表{


请有人帮忙好吗?谢谢。

如果您在问题中使用了脚本,那么这个答案如何?请将其视为几个答案中的一个

修改点: 不幸的是,在当前阶段,ES2015中添加的模板文字无法与Google Apps脚本一起使用。我认为您出现问题的原因可能是这个。 修改脚本: 请按如下方式修改您的脚本

Authorization: `Bearer ${token}`
发件人: 致: 及

发件人: 致: 参考资料: 如果我误解了你的问题,而这不是你想要的结果,我道歉

补充: 我注意到还有一个修改点。请按如下方式修改您的脚本

Authorization: `Bearer ${token}`
发件人: 致: 为了检索gid,请使用getSheetId。 更新日期:2020年12月19日: 现在,GoogleApps脚本可以使用V8运行时。也可以使用。但有一点很重要。在这种情况下,请使用backtick grave重音,如下所示

Authorization: `Bearer ${token}`


这是说未经授权。请检查您的api信用或尝试获得以下全部响应error@Ravi这很奇怪,我对ScriptApp.getOAuthToken的调用一点都没有错误,所以它肯定得到了一些东西。muteHttpExceptions是如何工作的?我似乎无法解决这个问题。你得到了token吗?@Ravi我在第11行和第11行定义了这个标记在41上调用它以获得授权不确定。但是您不需要在fetch method Parameter中将选项作为对象传递吗?这似乎已将错误从401:Unauthorized更改为400:Bad Request错误-但我感谢您的尝试!@wonk感谢您的回复。我注意到了另一个修改点。因此我添加了它。您能确认吗m it?在这种情况下,如果var client_id的client_id=行[0];不是工作表名称,出现错误。因此请小心。@wonk感谢您的回复和测试。我很高兴您的问题得到解决。也谢谢您。我刚刚看到您在我发送评论之前编辑了您的答案以修复我的变量。您很精明,老兄。出于某种原因,它仍然没有发送正确的工作表,但您提供了我有一个坚实的基础-谢谢你,有同样的问题,第一个来自/改变为我工作
blobs[i] = response.getBlob().setName(client_sheet + '.pdf');
var client_sheet = ss.getSheetByName(client_id);
var client_sheet = ss.getSheetByName(client_id).getSheetId();
Authorization: `Bearer ${token}`
blobs[i] = response.getBlob().setName(`${client_sheet}.pdf`);