google-apps-script - 如何使用 Google 相册 API 方法 : mediaItems. 在 Google 应用脚本中搜索电子表格

标签 google-apps-script google-sheets google-apis-explorer google-photos-api

我真的想自己解决这个问题......

我正在尝试使用 Google Photos API 和 google apps 脚本将来自 google photos 的照片元数据加载到工作表中。

在上一个问题的大量帮助之后,我能够取得一些进展

Is it possible to load google photos metadata into google sheets?

我现在有两个功能。

函数 photoAPI_ListPhotos() - 使用方法:mediaItems.list 并提供我所有未存档的照片 function photoAPI_ListAlbums() - 使用方法:albums.list 并提供我所有的相册

我想要做的是从特定相册中检索所有照片。 Method: mediaItems.search应该这样做,但它使用 POST 协议(protocol),而我发现以前的工作示例只使用 GET。查看该页面上提供的示例,有一个 javascript 部分,但它在应用程序脚本中不起作用。

UrlFetchApp 的文档告诉我如何格式化 POST 请求,但没有告诉我如何添加身份验证参数。

external APIs也没有给我我正在寻找的例子。

我觉得我遗漏了一些重要的小信息,我希望我在这里提问不会浪费大家的时间。只是一个关于如何在应用程序脚本中将 POST 与 oauth 结合使用的可靠示例,应该可以让我到达我需要去的地方。

这是我列出所有未归档照片的工作函数。

function photoAPI_ListPhotos() {
  /*
  This function retrieves all photos from your personal google photos account and lists each one with the Filename, Caption, Create time (formatted for Sheet), Width, Height, and URL in a new sheet.
  it will not include archived photos which can be confusing if you happen to have a large chunk of archived photos some pages may return only a next page token with no media items.

  Requires Oauth scopes. Add the below line to appsscript.json
  "oauthScopes": ["https://www.googleapis.com/auth/spreadsheets.currentonly", "https://www.googleapis.com/auth/photoslibrary", "https://www.googleapis.com/auth/photoslibrary.readonly", "https://www.googleapis.com/auth/script.external_request"]

  Also requires a standard GCP project with the appropriate Photo APIs enabled.
  https://developers.google.com/apps-script/guides/cloud-platform-projects
  */

  //Get the spreadsheet object
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  //Check for presence of target sheet, if it does not exist, create one.
  var photos_sh = ss.getSheetByName("photos") || ss.insertSheet("photos", ss.getSheets().length); 
  //Make sure the target sheet is empty
  photos_sh.clear();
  var narray = []; 

  //Build the request string. Max page size is 100. set to max for speed.
  var api = "https://photoslibrary.googleapis.com/v1/mediaItems?pageSize=100";
  var headers = { "Authorization": "Bearer " +  ScriptApp.getOAuthToken() };
  var options = { "headers": headers, "method" : "GET", "muteHttpExceptions": true };

  //This variable is used if you want to resume the scrape at some page other than the start. This is needed if you have more than 40,000 photos.
  //Uncomment the line below and add the next page token for where you want to start in the quotes.
  //var nexttoken="";

  var param= "", nexttoken;
  //Start counting how many pages have been processed.
  var pagecount=0;

  //Make the first row a title row
  var data = [
    "Filename",
    "description",
    "Create Time",
    "Width",
    "Height",
    "ID",
    "URL",
    "NextPage"
  ];
  narray.push(data);

  //Loop through JSON results until a nextPageToken is not returned indicating end of data
  do {
    //If there is a nextpagetoken, add it to the end of the request string
    if (nexttoken)
      param = "&pageToken=" + nexttoken; 

    //Get data and load it into a JSON object
    var response = UrlFetchApp.fetch(api + param, options);
    var json = JSON.parse(response.getContentText());

    //Check if there are mediaItems to process.
    if (typeof json.mediaItems === 'undefined') {
      //If there are no mediaItems, Add a blank line in the sheet with the returned nextpagetoken

      //var data = ["","","","","","","",json.nextPageToken];
      //narray.push(data);
    } else {
      //Loop through the JSON object adding desired data to the spreadsheet.
      json.mediaItems.forEach(function (MediaItem) {

        //Check if the mediaitem has a description (caption) and make that cell blank if it is not present.
        if(typeof MediaItem.description === 'undefined') {
            var description = "";
          } else {
            var description = MediaItem.description;
          }

        //Format the create date as appropriate for spreadsheets.
        var d = new Date(MediaItem.mediaMetadata.creationTime);

        var data = [
          MediaItem.filename,
          "'"+description, //The prepended apostrophe makes captions that are dates or numbers save in the sheet as a string. 
          d,
          MediaItem.mediaMetadata.width,
          MediaItem.mediaMetadata.height,
          MediaItem.id,
          MediaItem.productUrl,
          json.nextPageToken
        ];
        narray.push(data);
      });
    }

    //Get the nextPageToken
    nexttoken = json.nextPageToken;    

    pagecount++;
    //Continue if the nextPageToaken is not null
    //Also stop if you reach 400 pages processed, this prevents the script from timing out. You will need to resume manually using the nexttoken variable above.
  } while (pagecount<4 && nexttoken);

    //Continue if the nextPageToaken is not null (This is commented out as an alternative and can be used if you have a small enough collection it will not time out.)
  //} while (nexttoken);

  //Save all the data to the spreadsheet.
  photos_sh.getRange(1, 1, narray.length, narray[0].length).setValues(narray);
}

最佳答案

  • 您想使用 Google Photo API 检索特定相册的所有照片。
  • 您想知道如何使用 Google Apps 脚本使用 mediaItems.search 的方法。
  • 您已经能够使用 Google Photo API 检索数据。

如果我的理解是正确的,这个示例脚本怎么样?请将此视为几个答案之一。

示例脚本 1:

var albumId = "###"; // Please set the album ID.

var headers = {"Authorization": "Bearer " + ScriptApp.getOAuthToken()};
var url = "https://photoslibrary.googleapis.com/v1/mediaItems:search";
var mediaItems = [];
var pageToken = "";
do {
  var params = {
    method: "post",
    headers: headers,
    contentType: "application/json",
    payload: JSON.stringify({albumId: albumId, pageSize: 100, pageToken: pageToken}),
  }
  var res = UrlFetchApp.fetch(url, params);
  var obj = JSON.parse(res.getContentText());
  Array.prototype.push.apply(mediaItems, obj.mediaItems);
  pageToken = obj.nextPageToken || "";
} while (pageToken);
Logger.log(mediaItems)
  • 在 mediaItems.search 方法中,albumIdpageSizepageToken 包含在有效负载中,这些值作为application/json 的内容类型。

示例脚本 2:

当你的脚本被修改后,下面修改后的脚本怎么样?

function photoAPI_ListPhotos() {
  var albumId = "###"; // Please set the album ID.

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var photos_sh = ss.getSheetByName("photos") || ss.insertSheet("photos", ss.getSheets().length); 
  photos_sh.clear();
  var narray = []; 
  var api = "https://photoslibrary.googleapis.com/v1/mediaItems:search";
  var headers = { "Authorization": "Bearer " +  ScriptApp.getOAuthToken() };
  var nexttoken = "";
  var pagecount = 0;
  var data = ["Filename","description","Create Time","Width","Height","ID","URL","NextPage"];
  narray.push(data);
  do {
    var options = {
      method: "post",
      headers: headers,
      contentType: "application/json",
      payload: JSON.stringify({albumId: albumId, pageSize: 100, pageToken: nexttoken}),
    }
    var response = UrlFetchApp.fetch(api, options);
    var json = JSON.parse(response.getContentText());
    if (typeof json.mediaItems === 'undefined') {
      //If there are no mediaItems, Add a blank line in the sheet with the returned nextpagetoken

      //var data = ["","","","","","","",json.nextPageToken];
      //narray.push(data);
    } else {
      json.mediaItems.forEach(function (MediaItem) {
        if(typeof MediaItem.description === 'undefined') {
            var description = "";
          } else {
            var description = MediaItem.description;
          }
        var d = new Date(MediaItem.mediaMetadata.creationTime);
        var data = [
          MediaItem.filename,
          "'"+description,
          d,
          MediaItem.mediaMetadata.width,
          MediaItem.mediaMetadata.height,
          MediaItem.id,
          MediaItem.productUrl,
          json.nextPageToken
        ];
        narray.push(data);
      });
    }
    nexttoken = json.nextPageToken || "";
    pagecount++;
  } while (pagecount<4 && nexttoken);
  photos_sh.getRange(1, 1, narray.length, narray[0].length).setValues(narray);
}

备注:

  • 这个脚本假设如下。
    • 已启用 Google Photo API。
    • https://www.googleapis.com/auth/photoslibrary.readonlyhttps://www.googleapis.com/auth/photoslibrary 的范围是包括在范围内。

引用:

如果我误解了您的问题并且这不是您想要的结果,我深表歉意。

关于google-apps-script - 如何使用 Google 相册 API 方法 : mediaItems. 在 Google 应用脚本中搜索电子表格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57192192/

相关文章:

javascript - 如何使用仅返回单元格 a 的日期的公式自动填充单元格 C?

google-apps-script - 在谷歌应用程序脚本中复制一行(有条件)

google-api - 获取为特定用户创建的 Google 日历事件列表

google-apps-script - 如何避免 Google 电子表格中的 'exec maxSimultaneous' 限制?

javascript - 按钮不会在谷歌应用程序脚本 html 服务中执行点击功能

api - 通过 API 访问 “Anyone with the link” Google 电子表格

python - 如何在不提示授权我的脚本的情况下设置对 Google 表格的身份验证?

python - Google Spreadsheet Python API 或 gspread 是否允许图像或富文本?

java - 如何使用 Java 更新用户的 externalId

c# - Youtube API 无效搜索查询 invalidSearchFilter 错误