【问题标题】:0Auth2 problem to get my google photos libraries in a google sheet of mine0Auth2 问题在我的谷歌表中获取我的谷歌照片库
【发布时间】:2019-07-13 06:46:46
【问题描述】:

我正在尝试遵循文档,但从未连接 0Auth2。 顺便说一句,我正在从谷歌表格脚本页面手动运行脚本,我应该在哪里得到允许访问的提示? (我不明白所有这些 0Auth2 方案,我已经授权运行脚本并获得客户端 ID 和密码)...... 请参阅下面我的日志和脚本例程(第一次访问照片仍然是简约的,因为我还没有通过 0Auth2 步骤;-)。 提前感谢您的任何提示。我认为这将是微不足道的,因为它是我自己的工作表和谷歌照片帐户......

日志:

[19-01-06 17:50:05:809 CET] starting
[19-01-06 17:50:05:810 CET] getPhotoService
[19-01-06 17:50:05:849 CET] false
[19-01-06 17:50:05:850 CET] redirectURI=https://script.google.com/macros/d/[REMOVED]/usercallback
[19-01-06 17:50:05:864 CET] Open the following URL and re-run the script: https://accounts.google.com/o/oauth2/auth?client_id=[removed].apps.googleusercontent.com&response_type=code&redirect_uri=https%3A%2F%2Fscript.google.com%2Fmacros%2Fd%2F[removed]%2Fusercallback&state=[removed]&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fphotoslibrary.readonly&login_hint=[removed]&access_type=offline&approval_prompt=force

脚本:

function getPhotoService() {
  // Create a new service with the given name. The name will be used when
  // persisting the authorized token, so ensure it is unique within the
  // scope of the property store.
  Logger.log('getPhotoService');
  return OAuth2.createService('gPHOTOfj')

  // enable caching on the service, so as to not exhaust script's PropertiesService quotas
  .setPropertyStore(PropertiesService.getUserProperties())
  .setCache(CacheService.getUserCache())

  // Set the endpoint URLs, which are the same for all Google services.
  .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
  .setTokenUrl('https://accounts.google.com/o/oauth2/token')

  // Set the client ID and secret, from the Google Developers Console.
  .setClientId(CLIENT_ID)
  .setClientSecret(CLIENT_SECRET)

  // Set the name of the callback function in the script referenced
  // above that should be invoked to complete the OAuth flow.
  .setCallbackFunction('authCallback')
  //.setCallbackFunction('https://script.google.com/macros/d/'+SCRIPT_ID+'/authCallback')

  // Set the property store where authorized tokens should be persisted.
  .setPropertyStore(PropertiesService.getUserProperties())

  // Set the scopes to request (space-separated for Google services).
  .setScope('https://www.googleapis.com/auth/photoslibrary.readonly')

  // Below are Google-specific OAuth2 parameters.

  // Sets the login hint, which will prevent the account chooser screen
  // from being shown to users logged in with multiple accounts.
  .setParam('login_hint', Session.getActiveUser().getEmail())

  // Requests offline access.
  .setParam('access_type', 'offline')

  // Forces the approval prompt every time. This is useful for testing,
  // but not desirable in a production application.
  .setParam('approval_prompt', 'force');
}

function authCallback(request) {
  Logger.log('Called back!');
  var photoService = getPhotoService();
  var isAuthorized = photoService.handleCallback(request);
  if (isAuthorized) {
    Logger.log('Authorisation Success!');
  } else {
    Logger.log('Authorisation Denied...!');
  }
}

// Modified from http://ctrlq.org/code/20068-blogger-api-with-google-apps-script
function photoAPI() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var albums_sh = ss.getSheetByName("albums") || ss.insertSheet("albums", ss.getSheets().length); 
  albums_sh.clear(); var nrow = new Array(); var narray = new Array(); 
  Logger.log("starting");  

  var service = getPhotoService();
  Logger.log(service.hasAccess());
  Logger.log('redirectURI='+service.getRedirectUri());

  if (service.hasAccess()) {

    var api = "https://photoslibrary.googleapis.com/v1/albums";

    var headers = {
      "Authorization": "Bearer " + service.getAccessToken()
    };

    var options = {
      "headers": headers,
      "method" : "GET",
      "muteHttpExceptions": true
    };

    var response = UrlFetchApp.fetch(api, options);

    var json = JSON.parse(response.getContentText());

    for (var i in json.items) {
      nrow = []; nrow.push(json.items[i].id);  nrow.push(json.items[i].name); nrow.push(json.items[i].url); narray.push(nrow);
    }
    albums_sh.getRange(1,1,narray.length,narray[0].length).setValues(narray);


  } else {
    var authorizationUrl = service.getAuthorizationUrl();
    Logger.log("Open the following URL and re-run the script: " + authorizationUrl);
  }
}

【问题讨论】:

  • 您不需要 oAuth2 库。搜索如何直接将范围添加到清单。
  • 感谢大师的建议。我试图遵循它,但如果我不创建 oAuth2 服务,我从哪里获得授权令牌?
  • ScriptApp.getOAuthToken()
  • 我尝试了 ScriptApp.getOAuthToken(),现在它似乎可以工作了 :-)

标签: google-apps-script google-sheets google-photos-api


【解决方案1】:

所以它可以工作,如果其他人想使用它。但是速度很慢(我有 500 张专辑……):

function photoAPI() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var albums_sh = ss.getSheetByName("albums") || ss.insertSheet("albums", ss.getSheets().length); 
  albums_sh.clear();
  var narray = []; 

  var api = "https://photoslibrary.googleapis.com/v1/albums";
  var headers = { "Authorization": "Bearer " +  ScriptApp.getOAuthToken() };
  var options = { "headers": headers, "method" : "GET", "muteHttpExceptions": true };

  var param= "", nexttoken;
  do {
    if (nexttoken)
      param = "?pageToken=" + nexttoken; 
    var response = UrlFetchApp.fetch(api + param, options);
    var json = JSON.parse(response.getContentText());
    json.albums.forEach(function (album) {
      var data = [
        album.title,
        album.mediaItemsCount,
        album.productUrl
      ];
      narray.push(data);
    });
    nexttoken = json.nextPageToken;
  } while (nexttoken);
  albums_sh.getRange(1, 1, narray.length, narray[0].length).setValues(narray);
}

【讨论】:

  • 在你的情况下,增加pageSize怎么样?默认值为 20。这意味着一次 API 调用会返回 20 个值。您可以将其设置为 50,这是最大值,如 https://photoslibrary.googleapis.com/v1/albums?pageSize=50。我认为这样,它可能会变得更快一些。您可以在here查看详细信息。
  • 谢谢,我会试着看看瓶颈是否在 UrlFetch 中
  • 如果没有必需的授权范围 (https://www.googleapis.com/auth/photoslibrary.readonly),上述代码将无法工作。要添加范围,您需要使用 appsscript.json(清单文件)。在这里查看:developers.google.com/apps-script/concepts/…
  • 我是工作表和专辑的所有者,没有清单也可以正常工作(如果我记得的话,只是以交互方式要求我允许脚本一次)
  • 谢谢!通过使用 urlFetch 实现 here 记录的 2 个 API 调用,我能够获取您的代码并执行类似的功能来实际上传照片。我的 urlFetch 有点不同,因为它必须使用 POST 并且在这两种情况中的一种情况下必须使用字符串化的 JSON,但是一旦我以你的作为起点,就不难弄清楚了。我必须手动编辑清单文件中的 oauthscope,这很烦人,因为它删除了所有以交互方式获得的范围。
猜你喜欢
  • 1970-01-01
  • 2021-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
相关资源
最近更新 更多