javascript - 对 https://docs.google.com 的请求失败,返回代码 401 - 从 Google 表格保存 PDF 文件并通过电子邮件发送
问题描述
我基本上没有 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);
}
但是,我目前正在遇到此错误-老实说,我迷路了。
对https://docs.google.com的请求失败,返回代码 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 Script 一起使用。我认为您的问题的原因可能是这个。
修改后的脚本:
请按如下方式修改您的脚本。
从:
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所以可以使用模板文字。但有一点很重要。在这种情况下,请如下使用反引号(重音)。
Authorization: `Bearer ${token}`
和
blobs[i] = response.getBlob().setName(`${client_sheet}.pdf`);
推荐阅读
- python - 如何使用 Python 将 csv 的第一行替换为标题?
- angular - Angular App 无法与 Nginx Docker 容器中的 API 通信
- visual-studio - 找出 Visual Studio 使用的 Windows SDK
- reporting-services - SSRS 不良结果
- javascript - 无法读取未定义的属性 myFunction
- python - 有没有办法改变普通代码或文本的特定字符的颜色
- apache-kafka - kafka rest api和confulent rest代理之间的区别?
- android - Withings API 断开/撤销令牌
- dask - dask dataframe,to_parquet 首先创建一个 10 kb 文件,然后创建其余文件
- c++ - 如何编写一个将被扩展以定义具有模板参数的对象的宏