javascript - https ://docs. 的请求失败 google.com 返回代码 401 - 从 Google 表格保存并通过电子邮件发送 PDF 文件

标签 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';

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);
}

但是,我目前遇到了这个错误 - 老实说,我迷路了。

Request failed for https://docs.google.com returned code 401

Request failed for https://docs.google.com returned code 401. Truncated server response: <HTML> <HEAD> <TITLE>Unauthorized</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF" TEXT="#000000"> <H1>Unauthorized</H1> <H2>Error 401</H2> </BODY> </HTML> (use muteHttpExceptions option to examine full response) (line 39, file "send_emails")

如果有帮助的话,第 39 行是: const response = UrlFetchApp.fetch(url + exportOptions + client_sheet, {

有人可以帮忙吗?谢谢。

最佳答案

如果您在问题中使用脚本,这个答案怎么样?请将此视为多个答案之一。

修改点:

  • 遗憾的是,在当前阶段,ES2015 添加的模板文字无法与 Google Apps 脚本一起使用。我认为您的问题的原因可能是这样的。

修改后的脚本:

请按如下方式修改您的脚本。

来自:

Authorization: 'Bearer ${token}'

致:

Authorization: 'Bearer ' + token

还有

来自:

blobs[i] = response.getBlob().setName('${client_sheet}.pdf');

致:

blobs[i] = response.getBlob().setName(client_sheet + '.pdf');

引用文献:

如果我误解了您的问题并且这不是您想要的结果,我深表歉意。

添加:

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

来自:

var client_sheet = ss.getSheetByName(client_id);

致:

var client_sheet = ss.getSheetByName(client_id).getSheetId();
  • 要检索 gid,请使用 getSheetId()

更新日期:2020 年 12 月 19 日:

现在,Google Apps 脚本可以使用 V8 运行时。 Ref所以the template literals可以使用。但有一点很重要。在这种情况下,请使用反引号(重音符号),如下所示。

Authorization: `Bearer ${token}`

blobs[i] = response.getBlob().setName(`${client_sheet}.pdf`);

关于javascript - https ://docs. 的请求失败 google.com 返回代码 401 - 从 Google 表格保存并通过电子邮件发送 PDF 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58503256/

相关文章:

excel - 将数据从 Excel 文件提取到 Google 表格的应用程序脚本

google-sheets - 带有问号符号的COUNTIF

javascript - 将 mongoDB View 的结果发送到另一个集合( INSERT....SELECT from SQL )

javascript - 精确匹配字符串

google-apps-script - Google 幻灯片元素选择顺序问题

javascript - 为什么我不能使用 Google Apps 脚本对包含空格的字符串执行 .split() ?

javascript - 如果 Google 表格行不包含字符串,则删除或过滤该行

javascript - 正则表达式 javascript 未按预期工作

javascript - 从同一行获取最接近复选框列的 html 值

google-apps-script - 如何在 onEdit 触发器上执行 copyTo 后附加时间戳?