Google 脚本中具有服务帐户凭据的 UrlFetchApp 使用 post、put、patch 抛出错误

UrlFetchApp with Service Account credentials in Google script throws errors with post, put, patch

我有一个私人测试传播sheet,共享到 GAS 项目的服务帐户电子邮件。下面是:

  1. 使用具有服务帐户 oAuth2 凭据的 UrlFetchApp 从该传播中“获取”数据的函数sheet。 (获取具有范围值:“'sName'!A1:B3”;sheet 具有第 1 行列标题:A - “uId”;B - “标题”)。它与服务帐户电子邮件的 spreadsheet 共享(具有编辑权限)一起工作正常。如果没有该共享,它会因缺乏授权而失败。因此,oAuth 凭证 似乎 是正确的,具有传播范围 sheet。 (我正在与 Spencer Easton 的 this code 合作,为服务帐户生成 oAuth clientToken。)

  2. 用于更新(post、放置、补丁)相同测试传播的函数sheet。这三种方法都失败了,但有不同的错误消息如下:

Put:“接收到无效 JSON 负载。未知名称“title”:无法绑定查询参数。在请求中找不到字段 'title'信息。”如果 contentType:'application/json' 包含在选项中,错误将更改为:“收到无效的 JSON 负载。意外的令牌。\nuId=id3&title=Update\n^” (获取更新范围值:“'sName'!A3:B3”或“'sName'!A4:B4”)

Post:“在此服务器上找不到请求的 URL /v4/spreadsheets/[actual ssId]/values/'sName'!A4:B4。这就是我们所知道的。”

补丁:与Post相同,updateRange= "'sName'!A3:B3"

我已经完成了与这些错误相关的 SO 问答 postings。有人说问题是在选项中包含 contentType(或 Content-Type: 在 headers 中)。如上所述,这并没有解决问题,但确实使用“put”方法更改了错误消息。 Google UrlFetchApp 文档说更新不需要它(因此下面显示为注释掉)。

我希望我只是忽略了使用 UrlFetchApp 正确配置范围或更新选项的一些基本知识。

感谢您提供解决此更新问题的任何指导。

  1. GET DATA -- 正确获取数据
function getData(ssId,range) {
   if (!clientToken) { return "Authorization Failed";}
      var url= `https://sheets.googleapis.com/v4/spreadsheets/${ssId}/values/${range}`
      var options = {
             method:  'get',    
             contentType: 'application/json',
         headers: { Authorization: 'Bearer ' + clientToken }
          };
      response = UrlFetchApp.fetch(url,options);
      return response;
    
 } //end getData function
 var fetchData = getData(ssId,range);
  1. 更新数据 -- post、放置和补丁
  2. 的错误

更新数据object: var updateData = {'uId':'id3', 'title':'Update Title'}

function postData(ssId,updateRange,updateData) {
    if (!clientToken) {return "Authorization Failed";}
    var url= `https://sheets.googleapis.com/v4/spreadsheets/${ssId}/values/${updateRange}`
        var options = {
    //           contentType: 'application/json',  
             valueInputOption: 'RAW',
             method:   'put',     //patch, post, or put 
             payload: updateData,     
             headers: { Authorization: 'Bearer ' + clientToken }
             };
     var response= UrlFetchApp.fetch(url,options);
     var responseCode = response.getResponseCode();
     var responseBody = response.getContentText();
    if (responseCode === 200) {
                var responseJson = JSON.parse(responseBody);
                return responseJson; 
      } else {
             Logger.log(Utilities.formatString("Request failed. Expected 200, got %d: %s", responseCode, responseBody))
                 return responseCode;
                 }      
   } //end postData function
 var dataUpdate = postData(ssId,updateRange,updateData);

很遗憾,我无法确认您要在第二个脚本中使用的方法。但是,从您的端点来看,我猜您可能想要“方法:spreadsheets.values.update”。 Ref

如果我的理解是正确的,

  • var updateData = {'uId':'id3', 'title':'Update Title'}不能直接在该方法中使用
  • UrlFetchApp.fetch()中没有valueInputOption的属性。

如果 header 行在“A”和“B”列中有 uIdtitle,并且您想将 id3Update Title改为updateRange,下面的修改如何?

发件人:

var url= `https://sheets.googleapis.com/v4/spreadsheets/${ssId}/values/${updateRange}`
    var options = {
//           contentType: 'application/json',  
         valueInputOption: 'RAW',
         method:   'put',     //patch, post, or put 
         payload: updateData,     
         headers: { Authorization: 'Bearer ' + clientToken }
         };

收件人:

// var updateData = [['uId', 'title'], ['id3', 'Update Title']]; // If you want to include the header row, please use this.
var updateData = {values: [['id3', 'Update Title']]};

var url = `https://sheets.googleapis.com/v4/spreadsheets/${ssId}/values/${updateRange}?valueInputOption=RAW`;
var options = {
  contentType: 'application/json',
  method: 'put',
  payload: JSON.stringify(updateData),
  headers: { Authorization: 'Bearer ' + clientToken }
};

注:

  • 我认为,如果您的访问令牌可用于将值放入 Google 电子表格,则此修改后的脚本有效。

参考文献: