1

我正在构建一个希望在 Fusion Table 中托管的数据库,并且正在开发一些用于与 Fusion API 交互的测试函数。我正在使用 Google Apps 脚本,并且严重依赖其他来源的代码。我花了一天的大部分时间研究这个问题,现在我陷入了困境。

在脚本编辑器中运行 addNewColumn() 时,它会进入“获取就绪”日志条目(正如我在日志中看到的那样),然后它会通过身份验证过程(每次),然后停止(并且永远不会到达“获取执行”日志条目)。没有抛出任何错误,但它永远不会完成 fetch 命令。

在调试模式下运行时,它会通过授权,然后挂在 fetch 行。如果我单击“步入”,我会收到一个简单地说“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'
    };
4

3 回答 3

0

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

谷歌著名的脚本库中有一个融合表库: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

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

于 2013-02-20T08:49:14.507 回答
0

解决了!!!解决方案是双重的:

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

}
于 2013-03-16T08:45:01.647 回答
0
  • 这似乎与其他 urlFetch POST 示例不同的原因是因为 Fusion Table Service 需要一个实际的 JSON 有效负载作为请求“BODY”。当您添加一个 JSON 对象(没有 Stringify)作为“有效负载”时,UrlFetchApp 会将每个名称/值对转换为 Url 编码的请求字符串(即 name=YES&type=STRING)。但是,当 Payload 是一个字符串时(在您使用 stringify 的情况下),UrlFetch 只会对您提供的字符串进行 URL 编码(在这种情况下为 JSON 字符串)。如果您“发布”到服务预期的名称/值参数,那么您将不会使用 Stringify。
  • 注意:为了让您知道并澄清您在此处发布的其他相关问题,您在此示例中使用的是 Oauth 1.0(addOAuthService 仅支持 Oauth1.0 端点和协议)
  • 另一个注意事项:您正在混合 Utilities.jsonParse 和 JSON.stringify。我会使用 JSON.parse 来保持一致。
于 2013-03-17T12:31:59.210 回答