Google Apps 脚本:从 Google 驱动器导入(上传)媒体到 Google 照片?
Google Apps Scripts: import (upload) media from Google Drive to Google Photos?
我看到我们可以从 Google 驱动器导入(上传)媒体(照片、视频...)到 Google 照片。我的目标是:用代码完成这个任务。
我已成功从 Google 驱动器中获取照片列表,并将它们的 ID 存储在一个数组中。我有这个代码:
var arrId =
[
//Some image id...
];
var length = arrId.length;
var driveApplication = DriveApp;
for(var i=0;i<length;++i)
{
var file = driveApplication.getFileById(arrId[i]);
//Now I got the file, how can I programmatically import this file to Google Photos
}
我搜索了 the docs of Google Script,但找不到任何 API 的 Google 张照片。
谢谢。
上传文件并插入照片库
您需要确保这是一个 GCP 并启用驱动器 API 和照片库 API。
我正在使用以下范围:
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/photoslibrary
https://www.googleapis.com/auth/script.container.ui
https://www.googleapis.com/auth/script.external_request
https://www.googleapis.com/auth/script.scriptapp
https://www.googleapis.com/auth/spreadsheets
接下来是您无法上传到用户创建的相册。您需要通过脚本创建自己的相册。
这是我使用的:
function createAlbumByScript() {
var requestBody={"album":{"title":"Uploads1"}};
var requestHeader={Authorization: "Bearer " + ScriptApp.getOAuthToken()};
var options = {
"muteHttpExceptions": true,
"method" : "post",
"headers": requestHeader,
"contentType": "application/json",
"payload" : JSON.stringify(requestBody)
};
var response=UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/albums",options);
Logger.log(response);
}
我建立了一个上传对话框如下:
images.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('resources') ?>
<?!= include('css') ?>
</head>
<body>
<?!= include('form') ?>
<?!= include('script') ?>
</body>
</html>
resources.html:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
css.html:
<style>
body {background-color:#ffffff;}
input[type="button"],input[type="text"]{margin:0 0 2px 0;}
#msg{display:none;}
</style>
script.html:
<script>
$(function(){
google.script.run
.withSuccessHandler(function(vA) {
$('#sel1').css('background-color','#ffffff');
updateSelect(vA);
})
.getSelectOptions();
});
function updateSelect(vA,id){
var id=id || 'sel1';
var select = document.getElementById(id);
select.options.length = 0;
for(var i=0;i<vA.length;i++)
{
select.options[i] = new Option(vA[i][0],vA[i][1]);
}
}
function displayAlbum() {
var albumId=$('#sel1').val();
var aObj={id:albumId};
google.script.run
.withSuccessHandler(function(iObj){
$('#album').html(iObj.html);
$('#msg').html(iObj.message);
})
.getAlbumDisplay(iObj);
}
function uploadFile(form) {
console.log('form.elements.Destination.value= %s',form.elements.Destination.value);
console.log('format.elements.FileName.value= %s',form.elements.FileName.value);
$('#msg').css('display','block');
$('#msg').html('UpLoading...Please Wait');
const file=form.File.files[0];
const fr=new FileReader();//all this FileReader code originally came from Tanaike
fr.onload=function(e) {
const obj={FileName:form.elements.FileName.value,Destination:form.elements.Destination.value,mimeType:file.type,bytes:[...new Int8Array(e.target.result)]};//this allowed me to put the rest of the Form.elements back into the object before sending it to google scripts
google.script.run
.withSuccessHandler(function(msg){
$('#msg').css('display','block');
$('#msg').html(msg);
})
.uploadFile(obj);
}
fr.readAsArrayBuffer(file);
}
form.html:
<form>
<br /><select id="sel1" name="Destination"></select> Upload Destination
<br /><input type="text" name='FileName' /> File Name
<br /><input type="file" name='File'; />
<br /><input type="button" value="Upload" onClick="uploadFile(this.parentNode);" />
<br /><input type="button" value="Close" onclick="google.script.host.close();" />
<div id="msg"></div>
</form>
code.gs:
function listFiles() {
var files = Drive.Files.list({
fields: 'nextPageToken, items(id, title)',
maxResults: 10
}).items;
for (var i = 0; i < files.length; i++) {
var file = files[i];
Logger.log('\n%s-Title: %s Id: %s',i+1,file.title,file.id);
}
}
function uploadFile(obj) {
SpreadsheetApp.getActive().toast('Here');
var folder=DriveApp.getFolderById('1VAh2z-LD6nHPuHzgc7JlpYnPbOP_ch33');
if(!obj.hasOwnProperty('FileName'))obj['FileName']="NoFileName";
var blob = Utilities.newBlob(obj.bytes, obj.mimeType, obj.FileName);
var rObj={};
var ts=Utilities.formatDate(new Date(), Session.getScriptTimeZone(),"yyMMddHHmmss");
var file=folder.createFile(blob).setName(obj.FileName + '_' + ts);
rObj['file']=file;
rObj['filename']=file.getName();
rObj['filetype']=file.getMimeType();
rObj['id']=file.getId();
if(obj.Destination!=0){
var uObj={albumid:obj.Destination,fileid:rObj.id,filename:rObj.filename};
//Logger.log(JSON.stringify(uObj));
addFileToPhotoLibrary(uObj);
var msg=Utilities.formatString('<br/>File: %s<br />Type: %s<br />Folder: %s<br />File Added to Photo Library',rObj.filename,rObj.filetype,folder.getName());
return msg;
}else{
var msg=Utilities.formatString('<br/>File: %s<br />Type: %s<br />Folder: %s',rObj.filename,rObj.filetype,folder.getName());
return msg;
}
}
function getUploadToken_(imagefileId) {
var file=DriveApp.getFileById(imagefileId);
var headers = {
"Authorization": "Bearer " + ScriptApp.getOAuthToken(),
"X-Goog-Upload-File-Name": file.getName(),
"X-Goog-Upload-Protocol": "raw"
};
var options = {
method: "post",
headers: headers,
contentType: "application/octet-stream",
payload: file.getBlob()
};
var res = UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/uploads", options);
return res.getContentText()
}
function addFileToPhotoLibrary(uObj) {
Logger.log(JSON.stringify(uObj));
var imagefileId=uObj.fileid; // Please set the file ID of the image file.
var albumId=uObj.albumid; // Please set the album ID.
var uploadToken=getUploadToken_(imagefileId);
var requestHeader = {Authorization: "Bearer " + ScriptApp.getOAuthToken()};
var requestBody = {
"albumId": albumId,
"newMediaItems": [{
"description": "Description",
"simpleMediaItem": {
"fileName": uObj.filename,
"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);
}
function createAlbumByScript() {
var requestBody={"album":{"title":"Uploads1"}};
var requestHeader={Authorization: "Bearer " + ScriptApp.getOAuthToken()};
var options = {
"muteHttpExceptions": true,
"method" : "post",
"headers": requestHeader,
"contentType": "application/json",
"payload" : JSON.stringify(requestBody)
};
var response=UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/albums",options);
Logger.log(response);
}
function launchUploadDialog() {
loadOptionsPage();
var ui=HtmlService.createTemplateFromFile('images').evaluate();
SpreadsheetApp.getUi().showModelessDialog(ui, "Image Upload Dialog")
}
function loadOptionsPage() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Options');
sh.clearContents();
var dA=[['Destination','Id'],['Uploads Folder',0]];
var aA=listAlbums();
aA.forEach(function(a,i){
dA.push([a.title,a.id]);
});
sh.getRange(1,1,dA.length,dA[0].length).setValues(dA);
}
function getSelectOptions() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Options');
var rg=sh.getRange(2,1,sh.getLastRow()-1,2);
var vA=rg.getValues();
return vA;
}
- 您想将 Google 驱动器中的图像文件上传到 Google 照片。
- 您想使用 Google Apps 脚本实现此目的。
如果我的理解是正确的,这个答案怎么样?
在这个回答中,我想使用 GPhotoApp 的 Google Apps 脚本库来实现您的目标。此库具有将 Google 驱动器中的文件上传到 Google 照片的方法。
用法:
1。将云平台项目链接到 Google Apps 脚本项目:
关于这个,你可以在here查看详细流程。
2。安装库
- 库的项目密钥是
1lGrUiaweQjQwVV_QwWuJDJVbCuY2T0BfVphw6VmT85s9LJFntav1wzs9
.
重要的
这个库使用 V8 运行时。所以请在脚本编辑器中启用V8。
关于范围
此库使用以下 2 个范围。在这种情况下,安装库时,会自动安装这些作用域。
https://www.googleapis.com/auth/photoslibrary
https://www.googleapis.com/auth/script.external_request
示例脚本 1:
首先,请检索您要上传的相册ID。为此,请使用以下脚本。
function getAlbumList() {
const excludeNonAppCreatedData = true;
const res = GPhotoApp.getAlbumList(excludeNonAppCreatedData);
console.log(res.map(e => ({title: e.title, id: e.id})))
}
示例脚本 2:
使用检索到的相册 ID,您可以将图像文件上传到 Google 照片。在此示例脚本中,使用了您脚本的 arrId
。
function uploadMediaItems() {
const albumId = "###"; // Please set the album ID.
var arrId =
[
//Some image id...
];
const items = arrId.map(id => {
const file = DriveApp.getFileById(id);
return {blob: file.getBlob(), filename: file.getName()};
});
const res = GPhotoApp.uploadMediaItems({albumId: albumId, items: items});
console.log(res)
}
注:
- 在我的环境中,我可以确认上述脚本有效。
参考文献:
我看到我们可以从 Google 驱动器导入(上传)媒体(照片、视频...)到 Google 照片。我的目标是:用代码完成这个任务。
我已成功从 Google 驱动器中获取照片列表,并将它们的 ID 存储在一个数组中。我有这个代码:
var arrId =
[
//Some image id...
];
var length = arrId.length;
var driveApplication = DriveApp;
for(var i=0;i<length;++i)
{
var file = driveApplication.getFileById(arrId[i]);
//Now I got the file, how can I programmatically import this file to Google Photos
}
我搜索了 the docs of Google Script,但找不到任何 API 的 Google 张照片。
谢谢。
上传文件并插入照片库
您需要确保这是一个 GCP 并启用驱动器 API 和照片库 API。
我正在使用以下范围:
https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/photoslibrary https://www.googleapis.com/auth/script.container.ui https://www.googleapis.com/auth/script.external_request https://www.googleapis.com/auth/script.scriptapp https://www.googleapis.com/auth/spreadsheets
接下来是您无法上传到用户创建的相册。您需要通过脚本创建自己的相册。
这是我使用的:
function createAlbumByScript() {
var requestBody={"album":{"title":"Uploads1"}};
var requestHeader={Authorization: "Bearer " + ScriptApp.getOAuthToken()};
var options = {
"muteHttpExceptions": true,
"method" : "post",
"headers": requestHeader,
"contentType": "application/json",
"payload" : JSON.stringify(requestBody)
};
var response=UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/albums",options);
Logger.log(response);
}
我建立了一个上传对话框如下:
images.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('resources') ?>
<?!= include('css') ?>
</head>
<body>
<?!= include('form') ?>
<?!= include('script') ?>
</body>
</html>
resources.html:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
css.html:
<style>
body {background-color:#ffffff;}
input[type="button"],input[type="text"]{margin:0 0 2px 0;}
#msg{display:none;}
</style>
script.html:
<script>
$(function(){
google.script.run
.withSuccessHandler(function(vA) {
$('#sel1').css('background-color','#ffffff');
updateSelect(vA);
})
.getSelectOptions();
});
function updateSelect(vA,id){
var id=id || 'sel1';
var select = document.getElementById(id);
select.options.length = 0;
for(var i=0;i<vA.length;i++)
{
select.options[i] = new Option(vA[i][0],vA[i][1]);
}
}
function displayAlbum() {
var albumId=$('#sel1').val();
var aObj={id:albumId};
google.script.run
.withSuccessHandler(function(iObj){
$('#album').html(iObj.html);
$('#msg').html(iObj.message);
})
.getAlbumDisplay(iObj);
}
function uploadFile(form) {
console.log('form.elements.Destination.value= %s',form.elements.Destination.value);
console.log('format.elements.FileName.value= %s',form.elements.FileName.value);
$('#msg').css('display','block');
$('#msg').html('UpLoading...Please Wait');
const file=form.File.files[0];
const fr=new FileReader();//all this FileReader code originally came from Tanaike
fr.onload=function(e) {
const obj={FileName:form.elements.FileName.value,Destination:form.elements.Destination.value,mimeType:file.type,bytes:[...new Int8Array(e.target.result)]};//this allowed me to put the rest of the Form.elements back into the object before sending it to google scripts
google.script.run
.withSuccessHandler(function(msg){
$('#msg').css('display','block');
$('#msg').html(msg);
})
.uploadFile(obj);
}
fr.readAsArrayBuffer(file);
}
form.html:
<form>
<br /><select id="sel1" name="Destination"></select> Upload Destination
<br /><input type="text" name='FileName' /> File Name
<br /><input type="file" name='File'; />
<br /><input type="button" value="Upload" onClick="uploadFile(this.parentNode);" />
<br /><input type="button" value="Close" onclick="google.script.host.close();" />
<div id="msg"></div>
</form>
code.gs:
function listFiles() {
var files = Drive.Files.list({
fields: 'nextPageToken, items(id, title)',
maxResults: 10
}).items;
for (var i = 0; i < files.length; i++) {
var file = files[i];
Logger.log('\n%s-Title: %s Id: %s',i+1,file.title,file.id);
}
}
function uploadFile(obj) {
SpreadsheetApp.getActive().toast('Here');
var folder=DriveApp.getFolderById('1VAh2z-LD6nHPuHzgc7JlpYnPbOP_ch33');
if(!obj.hasOwnProperty('FileName'))obj['FileName']="NoFileName";
var blob = Utilities.newBlob(obj.bytes, obj.mimeType, obj.FileName);
var rObj={};
var ts=Utilities.formatDate(new Date(), Session.getScriptTimeZone(),"yyMMddHHmmss");
var file=folder.createFile(blob).setName(obj.FileName + '_' + ts);
rObj['file']=file;
rObj['filename']=file.getName();
rObj['filetype']=file.getMimeType();
rObj['id']=file.getId();
if(obj.Destination!=0){
var uObj={albumid:obj.Destination,fileid:rObj.id,filename:rObj.filename};
//Logger.log(JSON.stringify(uObj));
addFileToPhotoLibrary(uObj);
var msg=Utilities.formatString('<br/>File: %s<br />Type: %s<br />Folder: %s<br />File Added to Photo Library',rObj.filename,rObj.filetype,folder.getName());
return msg;
}else{
var msg=Utilities.formatString('<br/>File: %s<br />Type: %s<br />Folder: %s',rObj.filename,rObj.filetype,folder.getName());
return msg;
}
}
function getUploadToken_(imagefileId) {
var file=DriveApp.getFileById(imagefileId);
var headers = {
"Authorization": "Bearer " + ScriptApp.getOAuthToken(),
"X-Goog-Upload-File-Name": file.getName(),
"X-Goog-Upload-Protocol": "raw"
};
var options = {
method: "post",
headers: headers,
contentType: "application/octet-stream",
payload: file.getBlob()
};
var res = UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/uploads", options);
return res.getContentText()
}
function addFileToPhotoLibrary(uObj) {
Logger.log(JSON.stringify(uObj));
var imagefileId=uObj.fileid; // Please set the file ID of the image file.
var albumId=uObj.albumid; // Please set the album ID.
var uploadToken=getUploadToken_(imagefileId);
var requestHeader = {Authorization: "Bearer " + ScriptApp.getOAuthToken()};
var requestBody = {
"albumId": albumId,
"newMediaItems": [{
"description": "Description",
"simpleMediaItem": {
"fileName": uObj.filename,
"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);
}
function createAlbumByScript() {
var requestBody={"album":{"title":"Uploads1"}};
var requestHeader={Authorization: "Bearer " + ScriptApp.getOAuthToken()};
var options = {
"muteHttpExceptions": true,
"method" : "post",
"headers": requestHeader,
"contentType": "application/json",
"payload" : JSON.stringify(requestBody)
};
var response=UrlFetchApp.fetch("https://photoslibrary.googleapis.com/v1/albums",options);
Logger.log(response);
}
function launchUploadDialog() {
loadOptionsPage();
var ui=HtmlService.createTemplateFromFile('images').evaluate();
SpreadsheetApp.getUi().showModelessDialog(ui, "Image Upload Dialog")
}
function loadOptionsPage() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Options');
sh.clearContents();
var dA=[['Destination','Id'],['Uploads Folder',0]];
var aA=listAlbums();
aA.forEach(function(a,i){
dA.push([a.title,a.id]);
});
sh.getRange(1,1,dA.length,dA[0].length).setValues(dA);
}
function getSelectOptions() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Options');
var rg=sh.getRange(2,1,sh.getLastRow()-1,2);
var vA=rg.getValues();
return vA;
}
- 您想将 Google 驱动器中的图像文件上传到 Google 照片。
- 您想使用 Google Apps 脚本实现此目的。
如果我的理解是正确的,这个答案怎么样?
在这个回答中,我想使用 GPhotoApp 的 Google Apps 脚本库来实现您的目标。此库具有将 Google 驱动器中的文件上传到 Google 照片的方法。
用法:
1。将云平台项目链接到 Google Apps 脚本项目:
关于这个,你可以在here查看详细流程。
2。安装库
- 库的项目密钥是
1lGrUiaweQjQwVV_QwWuJDJVbCuY2T0BfVphw6VmT85s9LJFntav1wzs9
.
这个库使用 V8 运行时。所以请在脚本编辑器中启用V8。
关于范围此库使用以下 2 个范围。在这种情况下,安装库时,会自动安装这些作用域。
https://www.googleapis.com/auth/photoslibrary
https://www.googleapis.com/auth/script.external_request
示例脚本 1:
首先,请检索您要上传的相册ID。为此,请使用以下脚本。
function getAlbumList() {
const excludeNonAppCreatedData = true;
const res = GPhotoApp.getAlbumList(excludeNonAppCreatedData);
console.log(res.map(e => ({title: e.title, id: e.id})))
}
示例脚本 2:
使用检索到的相册 ID,您可以将图像文件上传到 Google 照片。在此示例脚本中,使用了您脚本的 arrId
。
function uploadMediaItems() {
const albumId = "###"; // Please set the album ID.
var arrId =
[
//Some image id...
];
const items = arrId.map(id => {
const file = DriveApp.getFileById(id);
return {blob: file.getBlob(), filename: file.getName()};
});
const res = GPhotoApp.uploadMediaItems({albumId: albumId, items: items});
console.log(res)
}
注:
- 在我的环境中,我可以确认上述脚本有效。