获取谷歌应用程序脚本授权融合表API



我正在构建一个数据库,希望将其托管在Fusion表中,并正在开发一些用于与Fusion API接口的测试函数。我正在使用谷歌应用程序脚本,并在很大程度上依赖于其他来源的代码。我花了一天的大部分时间研究这个问题,现在我陷入了困境。

当在脚本编辑器中运行addNewColumn()时,它会到达"fetch ready"日志条目(正如我在日志中看到的),然后(每次)通过身份验证过程,然后停止(并且永远不会到达"fetch-executed"日志条目)。没有抛出任何错误,但它从未完成fetch命令。

在调试模式下运行时,它会经过授权,然后挂在获取行。如果我点击"step-in",我会得到一个简单地说"OAuth错误"的错误。我真的不知道在这里该做什么。任何帮助都将不胜感激。

function googleAuth() {
      var scope = "https://www.googleapis.com/auth/fusiontables";
      var service = 'fusion';
      var oAuthConfig = UrlFetchApp.addOAuthService(service);
      oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/"+
                 "OAuthGetRequestToken?scope="+scope);
      oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
      oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
      oAuthConfig.setConsumerKey('{consumer key}');
      oAuthConfig.setConsumerSecret('{secret}');
      return {oAuthServiceName:'fusion', oAuthUseToken:"always"};
}
function addNewColumn(){   
      var p = {
          'name' : "newColumn",
          'type' : "NUMBER"
      };
      Logger.log(addColumn(p));
}

function addColumn(parameters) {
  var url = "https://www.googleapis.com/fusiontables/v1/";
  var fetchArgs = googleAuth(); 
  fetchArgs.method = "POST";
  fetchArgs.payload = parameters;
  //if the fetch arg payload is set to null it will add an unnamed column
  //fetchArgs.payload = null;  
  url += "tables/"+"{table id}"+"/columns";
  url += '?key='+"{key}";
  Logger.log("fetch ready");
  var result = UrlFetchApp.fetch(url, fetchArgs).getContentText();
  Logger.log("fetch executed");
  return Utilities.jsonParse(result);  
}

更新

我简化了我的函数以进行测试,我发现通过简单地在选项体的有效载荷字段中插入"null"代替"payload"变量,代码将成功地在融合表中创建一个无名称列。但是,当我重新插入有效负载变量时,它停止工作。

当不工作时,它要么:每次我从编辑器运行它时都要求重新授权,要么在从web应用程序运行时声明"遇到错误:执行该操作需要授权"。有效载荷如何更改授权?我已经将完全相同的有效负载剪切并粘贴到OAuth2.0游乐场中,它运行得非常好。请帮忙。

function googleAuth() {
      var oAuthConfig = UrlFetchApp.addOAuthService(service);
      oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/"+
                 "OAuthGetRequestToken?scope=" + scope);
      oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
      oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
      oAuthConfig.setConsumerKey(clientId);
      oAuthConfig.setConsumerSecret(clientSecret);
      return {oAuthServiceName:service, oAuthUseToken:"always"};
}
function addColumn() {
  googleAuth();
  var payload = 
    {
      name : "IT WORKED",
      type : "STRING"
    };
  var options =
    {
      "oAuthUseToken":"always",
      "oAuthServiceName":service,
      "method" : "post",
      "payload":payload
    };
  var url = fetchUrl + "tables/" + fusionId + "/columns" + "?key=" + apiKey;
  var fetchResult = UrlFetchApp.fetch(url, options);
  Logger.log(fetchResult.getContentText());
  return Utilities.jsonParse(fetchResult.getContentText());
}

更新#2

我找到了一种方法,可以让它在没有任何错误的情况下运行,但它仍然不会将请求的名称和类型分配给新列。最近添加的是指定内容类型,如下所示。通过将contentType强制为"application"或"json",它将运行,但仍不能按预期传递有效负载。

  var options =
    {
      "oAuthUseToken":"always",
      "oAuthServiceName":service,
      "method" : "POST",
      "payload" : payload,
      'contentType' : 'application'
    };

我遇到了同样的问题,试图从融合表中获取和操作数据。

谷歌著名的脚本库中有一个融合表库:https://developers.google.com/apps-script/notable-script-libraries?hl=pt-BR

我链接了那个图书馆,但它似乎有问题。因此(出于调试原因)我将源代码复制到我的项目中,并使其正常工作:

https://sites.google.com/site/scriptsexamples/new-connectors-to-google-services/fusion-tables-class/fusion-source

也许你在那里找到了答案。

已解决!!!解决方案有两个:

  1. 负载必须通过JSON.stringify()转换为字符串
  2. contentType必须手动设置为"application/json"

这与我在网上找到的多个教程非常不同,但我想分享我的工作解决方案。

function addColumn(authToken) {
  googleAuth();
  var payload =
    {
      name : 'YES',
      type : 'STRING'
    };
  var options =
    {
      payload : JSON.stringify(payload),
      oAuthUseToken : "always",
      oAuthServiceName : service,
      method : "POST",
      contentType : "application/json"
    };
  var url = fetchUrl + "tables/" + fusionId + "/columns";// + "?key=" + apiKey;
  var fetchResult = UrlFetchApp.fetch(url, options);
  Logger.log(fetchResult.getHeaders());
  Logger.log(fetchResult.getContentText());
  return Utilities.jsonParse(fetchResult.getContentText());
}
  • 这似乎与其他urlFetch POST不同的原因示例是因为Fusion表服务需要一个实际的JSON有效载荷作为请求"BODY"。添加JSON对象时(没有Stringify)作为"有效负载",UrlFetchApp将转换每个名称/值对转换为Url编码的请求字符串(即名称=YES和类型=String)。但是,当Payload是字符串时(在您使用的情况下stringify),UrlFetch将只对您提供的字符串进行URL编码(在在这种情况下是JSON字符串)。如果您正在"张贴"服务预期的名称/值参数,则不会使用Stringify
  • 注意:只是为了让你知道并澄清你的其他相关信息你在这里发布的问题,你在这里使用的是Oauth 1.0示例(addOAuthService仅支持Oauth1.0端点和协议)
  • 还有一个注意:您正在混合Utilities.jsonParse和JSON.stringify.我会使用JSON.parse来保持一致

最新更新