I'm using the search API for Google Photos documented here. I'd like the results in the response to be sorted from newest to oldest, but by default, the results are sorted from oldest to newest. Is there a way to reverse the sorting?
1 Answers
I believe your goal as follows.
- You want to sort the result values from the method of "Method: mediaItems.search".
- You want to sort the values from oldest to newest.
Issue and workaround:
Unfortunately, in the current stage, it seems that there is no parameter for sorting the returned values for the the method of "Method: mediaItems.search" in Google Photos API. Also, it seems that such parameter is not existing in the method of "mediaItems.list".
By the way, it was found that when albumId
is used in the request body for the method of "Method: mediaItems.search", the returned values are sorted as the ascending order. If you use the albumn ID, I think that your goal can be achieve by this.
On the other hand, when albumId
is NOT used in the request body, the returned values are sorted as the descending order. And also, it seems that when filteres
is used in the request body, the returned values are sorted as the descending order.
From your question, I thought that in your situation, albumId
might be not used. So in this case, as the current workaround, how about sorting the values using a script after the values are retrieved? In this answer, I would like to propose to use the Web Apps created by Google Apps Script as a wrapper API.
Usage:
1. Create new project of Google Apps Script.
Sample script of Web Apps is a Google Apps Script. So please create a project of Google Apps Script.
If you want to directly create it, please access to https://script.new/. In this case, if you are not logged in Google, the log in screen is opened. So please log in to Google. By this, the script editor of Google Apps Script is opened.
2. Linking Cloud Platform Project to Google Apps Script Project.
About this, you can see the detail flow at here.
And also, please enable Google Photos API at API console.
3. Add scope.
In this case, please addt the scope of https://www.googleapis.com/auth/photoslibrary
to the manifest file (appsscript.json
).
4. Script.
Please copy and paste the following script (Google Apps Script) to the script editor. This script is for the Web Apps. This Web Apps is used as an API.
function doGet(e) {
const key = "sampleKey"; // This is used for using this Web Apps.
try {
if (e.parameter.key != key) throw new Error("Invalid key.");
const albumId = e.parameter.albumId;
const filters = e.parameter.filters;
const sort = e.parameter.sort;
const headers = {"Authorization": "Bearer " + ScriptApp.getOAuthToken()};
const url = "https://photoslibrary.googleapis.com/v1/mediaItems:search";
let mediaItems = [];
let pageToken = "";
const metadata = {pageSize: 100, pageToken: pageToken};
if (albumId) metadata.albumId = albumId;
if (filters) metadata.filters = JSON.parse(filters);
do {
const params = {
method: "post",
headers: headers,
contentType: "application/json",
payload: JSON.stringify(metadata),
}
const res = UrlFetchApp.fetch(url, params);
const obj = JSON.parse(res.getContentText());
mediaItems = mediaItems.concat(obj.mediaItems);
pageToken = obj.nextPageToken || "";
} while (pageToken);
if (mediaItems.length > 0) {
if (sort && sort == "ascending") {
mediaItems.sort((a, b) => new Date(a.mediaMetadata.creationTime) < new Date(b.mediaMetadata.creationTime) ? -1 : 1);
}
return ContentService.createTextOutput(JSON.stringify({values: mediaItems}));
}
return ContentService.createTextOutput(JSON.stringify({error: "No values."}));
} catch(err) {
return ContentService.createTextOutput(JSON.stringify({error: err.message}));
}
}
5. Deploy Web Apps.
The detail information can be seen at the official document.
- On the script editor, at the top right of the script editor, please click "click Deploy" -> "New deployment".
- Please click "Select type" -> "Web App".
- Please input the information about the Web App in the fields under "Deployment configuration".
- Please select "Me" for "Execute as".
- This is the important of this workaround.
- Please select "Anyone" for "Who has access".
- In this case, the user is not required to use the access token. So please use this as a test case.
- When you want to use the access token, please set it to
Anyone with Google account
orOnly myself
. By this, the user can access to the Web Apps using the access token. When you use the access token, please include the scope ofhttps://www.googleapis.com/auth/drive.readonly
orhttps://www.googleapis.com/auth/drive
.
- Please click "Deploy" button.
- When "The Web App requires you to authorize access to your data" is shown, please click "Authorize access".
- Automatically open a dialog box of "Authorization required".
- Select own account.
- Click "Advanced" at "This app isn't verified".
- Click "Go to ### project name ###(unsafe)"
- Click "Allow" button.
- Copy the URL of Web App. It's like
https://script.google.com/macros/s/###/exec
.- When you modified the Google Apps Script, please redeploy as new version. By this, the modified script is reflected to Web Apps. Please be careful this.
6. Testing.
As the test of this Web Apps, I would like to propose to use the following curl command. Please replace https://script.google.com/macros/s/###/exec
with your Web Apps URL.
In this curl command, the result value is returned as the ascending order of oldest to newest
.
$ curl -GL -d "key=sampleKey" -d "sort=ascending" https://script.google.com/macros/s/###/exec
Use albumId:
When you want to use the album ID, please use the following curl command.
$ curl -GL -d "albumId=###" -d "key=sampleKey" -d "sort=ascending" https://script.google.com/macros/s/###/exec
- In this case, even when
-d "sort=ascending"
is not used, the result value is returned as the ascending order ofoldest to newest
.
When you want to use the filters, please use the following curl command.
$ curl -GL -d 'filters={"dateFilter":{"ranges":[{"startDate":{"year":2020},"endDate":{"year":2021}}]}}' -d "key=sampleKey" -d "sort=ascending" https://script.google.com/macros/s/###/exec
- In this command, the values of 2020 - 2021 are returned as the ascending order of
oldest to newest
.
Note:
- Although when I searched this at the Google issue tracker, I couldn't find about it. So how about reporting this as the future request? Ref
References:

- 181,128
- 11
- 97
- 165
-
Thanks for this extremely detailed response! I've been accessing the API through an HTTP request. When I do so with the URL `https://script.google.com/macros/s/[letters+numbers_for_my_script]/exec`, and the query parameters of `key:[myGooglePhotosAPIkey],albumId:[myAlbumID]`, I get the following response: `Script function not found: doGet`. Any suggestions as to what the problem is? As you might be able to tell, I don't do this a lot, so it's probably some stupid mistake. – tlewis3348 Feb 27 '21 at 12:31
-
1@tlewis3348 Thank you for replying. I apologize for the inconvenience. About ` When I do so with the URL https://script.google.com/macros/s/[letters+numbers_for_my_script]/exec, and the query parameters of key:[myGooglePhotosAPIkey],albumId:[myAlbumID],`, if you are using `key:[myGooglePhotosAPIkey],albumId:[myAlbumID]` as the query parameter, I think that this is not correct. In this case, it's `https://script.google.com/macros/s/[letters+numbers_for_my_script]/exec?key=###&albumId=###`. How about this? – Tanaike Feb 27 '21 at 13:07
-
1@tlewis3348 But, from your error message, I'm worry that in your situation, the Web Apps might not be able to be correctly deployed. Because when I tested above flow, no error occurs. I deeply apologize for this. If above modification was not the direct solution of your current issue, in order to correctly understand about your current situation, can you share your current script? By this, I would like to confirm it. – Tanaike Feb 27 '21 at 13:07
-
Not a problem. It sounds like there is a problem with the deployment because the URL you suggested (i.e. `https://script.google.com/macros/s/[letters+numbers_for_my_script]/exec?key=###&albumId=###`) isn't working either. I'm not sure it's a good idea to share the URL to the project publicly. Could you email me at tlewis3348 [at symbol] gmail.com? – tlewis3348 Feb 27 '21 at 19:24
-
1@tlewis3348 Thank you for replying. I have to apologize for my poor English skill. About `Could you email me at tlewis3348 [at symbol] gmail.com?`, what should I do? For example, when you want to show the URL of your GAS project using an email, you can see my contact at https://tanaikech.github.io/contact/ – Tanaike Feb 27 '21 at 23:54
-
Tanaike, no need to apologize. You've been a huge help. I'll send you an email. Thanks! – tlewis3348 Mar 01 '21 at 11:18
-
@tlewis3348 Thank you for replying. I could confirm your situation from your GAS project. In your script, it seems that your setting of Web Apps is `Execute as: User accessing the web app` and `Who has access: Anyone with Google account`. In my answer, I wrote the setting as `Execute as: Me` and `Who has access: Anyone`. And I said `please use this as a test case.`. Can I ask you about your setting? If I misunderstood your situation, I apologize. **As the test, please redeploy the Web Apps with `Execute as: Me` and `Who has access: Anyone` as new version and test it again.** – Tanaike Mar 01 '21 at 12:06
-
Sorry, I think I was trying several different options. I tried the options you specified first, then I changed them to something else to see if that would work. In any case, I just changed them to what you specify above, and it is still giving me the same result: `Script function not found: doGet`. – tlewis3348 Mar 04 '21 at 11:16
-
@tlewis3348 Thank you for replying. I apologize for the inconvenience. Unfortunately, I cannot replicate your situation of `Script function not found: doGet`. When I tested above flow, no error occurred. And, the results at "Testing" section are obtained. I deeply apologize for this situation. In order to correctly understand about your current situation, can you explain about your detail flow for replicating your issue? When you can do, please add it to your question. By this, I would like to confirm it. – Tanaike Mar 04 '21 at 13:24