问题
Trying to use Google Apps Script and Google Photos API to add photos to Google Photos. Upload seems to work / returns a token, but then adding the photo to the library fails. The process consists of two steps: 1. Upload the photo data as described here, then 2. Add the photo to photo library as described here.
Step 1. works for me, as I get an upload token, but step 2 with source code below, throws an error, but my call has the one media item it needs.
{
"error": {
"code": 400,
"message": "Request must have at least one newMediaItem.",
"status": "INVALID_ARGUMENT"
}
}
My code after the upload step below. I have tried to stringify request body and have passed it to payload instead of body, but nothing worked. As the error seems specific enough, I've the feeling I'm just overlooking a tiny thing, but what??? Who has a working piece of code, preferably in apps script that I can have a look at?
requestHeader = {
"authorization": "Bearer " + photos.getAccessToken(),
"Content-Type": "application/json"
}
var requestBody = {
"newMediaItems": [
{
"description": "Photo description",
"simpleMediaItem": {
"fileName": fileName,
"uploadToken": uploadToken
}
}
]
}
var options = {
"muteHttpExceptions": true,
"method" : "post",
"headers": requestHeader,
"body" : requestBody
};
var response = UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate", options);
Logger.log("raw: " + response);
回答1:
- You want to add an image file to the album using Photo API with Google Apps Script.
- You have already enabled Google Photo API at API console. And yout access token can be used for using the method of mediaItems.batchCreate.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Usage:
1. Linking Cloud Platform Project to Google Apps Script Project:
About this, you can see the detail flow at here.
2. Add scope:
In this case, please addt the scope of https://www.googleapis.com/auth/photoslibrary
to the manifest file (appsscript.json
).
Although I think that from your question, above step 1 and 2 have already been done, I added them because I thought that this might be useful for other users.
3. Sample script:
In your script, I cannot see the detail of uploadToken
. But in your question, I could confirm that you have alredy retrieved the value of uploadToken
. So when you want to use your script for retrieving uploadToken
, please replace uploadToken
to yours. As the modification point of your script, 1. Include the album ID. 2. There is no body
property of UrlFetchApp. 3. Please use JSON.stringify()
to the payload.
function getUplaodToken_(imagefileId) {
var headers = {
"Authorization": "Bearer " + ScriptApp.getOAuthToken(),
"X-Goog-Upload-File-Name": "sampleFilename",
"X-Goog-Upload-Protocol": "raw",
};
var options = {
method: "post",
headers: headers,
contentType: "application/octet-stream",
payload: DriveApp.getFileById(imagefileId).getBlob()
};
var res = UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/uploads", options);
return res.getContentText()
}
// Please run this.
function myFunction() {
var imagefileId = "###"; // Please set the file ID of the image file.
var albumId = "###"; // Please set the album ID.
var uploadToken = getUplaodToken_(imagefileId);
var requestHeader = {Authorization: "Bearer " + ScriptApp.getOAuthToken()};
var requestBody = {
"albumId": albumId,
"newMediaItems": [{
"description": "Photo description",
"simpleMediaItem": {
"fileName": "sampleName",
"uploadToken": uploadToken
}}]
};
var options = {
"muteHttpExceptions": true,
"method" : "post",
"headers": requestHeader,
"contentType": "application/json",
"payload" : JSON.stringify(requestBody)
};
var response = UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate", options);
Logger.log(response);
}
- In this script, it supposes that the image file is put in Google Drive.
Note:
If the error of
No permission to add media items to this album.
occurs, please create the album by the script. The official document says as follows.Media items can be created only within the albums created by your app.
In this case, please create new album by the following script, and please retrieve the album ID.
function createNewAlbum() { var options = { headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}, payload: JSON.stringify({album: {title: "sample title"}}), contentType: "application/json", method: "post" }; var res = UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/albums", options); Logger.log(res); }
References:
- Class UrlFetchApp
- Upload media
- Creating a media item
- Method: mediaItems.batchCreate
If I misunderstood your question and this was not the direction you want, I apologize.
回答2:
Found it! Not shown in the code I submitted, but still adding the fix, as it might help others making the same mistake I did. I directly assigned the response from UrlFetchApp to be the upload token, like so:
uploadToken = UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/uploads", options);
but needed to call .getContentText() on it to get it as string, like so:
uploadToken = UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/uploads", options).getContentText();
来源:https://stackoverflow.com/questions/60367240/google-photos-api-adding-photos-not-working-upload-seems-to-work