update google sheet script with another script - google-apps-script

I have a folder with approximately 140 google sheets and a main standalone google script that I call with a library script from each sheet but need to add/update all of the scripts attached to each google sheet script. Currently the only way I have found is to open each sheet script and add the library script save and move on but 140 sheets takes a long time. I know all my sheets that i need scripts adding or updating are in one folder so thinking I could use something like this to loop through all the gsheets but can't find away to edit the scripts from here...
function scriptupdate() {
var folder = DriveApp.getFolderById('FOLDER CONTAINING THE GSHEETS ID');
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
Logger.log("File Name is "+file.getName());
Logger.log("File ID is "+file.getId());
}
}
I'm not sure if what I'm trying to do is possible but trying to save a lot of time if this is doable but really appreciate any help and guidance offered

Answer
You can create and update projects and its content using the projects resource methods. As these have no built-in service in Apps Script they must be called with urlFetchApp.fetch.
When writing functions, remember to put them between grave accents (`). You can use the key combination Ctrl + Shift + I to fix all the indentation and spacing in the whole script file.
Code
function scriptupdate() {
// GET FILES
var folder = DriveApp.getFolderById('FOLDER CONTAINING THE GSHEETS ID');
var files = folder.getFiles();
while (files.hasNext()) {
// GET FILE INFORMATION
var file = files.next();
var name = file.getName()
var fileId = file.getId()
// CREATE CONTAINER-BOUND SCRIPT
var url = 'https://script.googleapis.com/v1/projects'
var formData = {
'title': name,
'parentId': fileId
};
var options = {
method: 'post',
headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() },
payload: formData,
muteHttpExceptions: true
};
var res = JSON.parse(UrlFetchApp.fetch(url, options).getContentText())
var scriptId = res["scriptId"]
// UPDATE PROJECT CONTENT
var url = 'https://script.googleapis.com/v1/projects/' + scriptId + '/content';
var formData = {
"files": [
{
"name": "appsscript",
"type": "JSON",
"source": `{
"timeZone": "America/New_York",
"dependencies": {},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}`
},
{
"name": "main",
"source":
`function main() {
console.log('hello world')
}`,
"type": "SERVER_JS"
}
]
}
var options = {
method: 'put',
contentType: 'application/json',
payload: JSON.stringify(formData),
headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() },
muteHttpExceptions: true
};
var res = UrlFetchApp.fetch(url, options).getContentText()
console.log(res)
}
}
Reference
projects
projects: create
projects: updateContent
urlFetchApp.fetch

Related

Google App script connecting to JAMF to pull data on smart group automated in google sheet?

Can anyone help me please am managed to connect the Google app script to JAMF however, when I try to pull the data to save on google sheers am unable to do this could someone please show me what I am missing.
function NAME() {
var url = 'JAMF URL';
var jamfXml = UrlFetchApp.fetch(url, {
"method": "GET",
"headers": {
"Authorization": "",
"x-api-key": "",
"cache-control": "",
"Content-Type": ""
},
}).getContentText();
var ss = SpreadsheetApp.openById('SheetID');
var sheet = ss.getSheetByName("NAME of Sheet");
var document = XmlService.parse(jamfXml)
var root = document.getRootElement()
// console.log(root)
var computers = root.getChildren("Name of your smart group")
var attribues = root.getAttribute("Name of your smart group")
console.log(attribues)
var list=[]
computers.forEach(function(item){
var computer=[]
item.getChildren().forEach(function(details){
computer.push(details.getValue())
})
list.push(computer);
})
var sheet = SpreadsheetApp.openById('Add in your own SheetID');
}
I have managed to connected it however the data doesn’t seem to auto create in google sheet even after connecting the cgoogle sheet ID to this code block also how can we get the data to be readabl and not just random objects in google sheets?
Thank you so much for whoeever helps me.

Get the blob of a drive file using Drive api

I used below script to get the blob of abc.dat file which is generated via my Apps Script project. With the Drive service, it is easy.
Used oauthScope is https://www.googleapis.com/auth/drive.readonly
function ReadData() {
var files;
var folders = DriveApp.getFoldersByName("Holder");
if (folders.hasNext()) {
var folder = folders.next();
var files = folder.getFiles();
while (files.hasNext()){
file = files.next();
if(file.getName()=='abc.dat'){
var content = file.getBlob().getDataAsString();
return content;
}
}
}
return '';
}
In order to reduce the authentication scope, Now I am modifying the code to fully remove the https://www.googleapis.com/auth/drive.readonly oauthScope and use only the https://www.googleapis.com/auth/drive.file oauthScope.
Using the Drive api, I didn't found a direct way to get the blob of a file.
I used this below script to get the blob of a word document file. But it is not working for the .dat file with error fileNotExportable, Export only supports Docs Editors files, code 403
function getBlob(fileID, format){
var url = "https://www.googleapis.com/drive/v3/files/" + fileID + "/export?mimeType="+ format;
var blob = UrlFetchApp.fetch(url, {
method: "get",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
}).getBlob();
return blob;
}
Found this article and tried changing the export with get in the url. The returning blob.getDataAsString() gives "Not found" now.
The mimeType I used when creating the abc.dat file is application/octet-stream .dat. But when check the generated file, its mimeType is text/plain. So I used the 'text/plain' as the input for 'format' parameter in getBlob function.
.dat file creation code :
var connectionsFile = {
title: filename,
mimetype: "application/octet-stream .dat",
parents: [{'id':folder.getId()}],
};
var blobData = Utilities.newBlob(contents);
file = Drive.Files.insert(connectionsFile,blobData);
}
How can I modify this code to get the blob from the file? or is there any other way around?
Thanks in advance!
I think that in your situation, it is required to use get method instead of export method. Because export method is used for Google Docs files (Document, Spreadsheet, Slides and so on). When your script is modified, how about the following modification?
Modified script:
function getBlob(fileID) {
var url = "https://www.googleapis.com/drive/v3/files/" + fileID + "?alt=media";
var blob = UrlFetchApp.fetch(url, {
method: "get",
headers: { "Authorization": "Bearer " + ScriptApp.getOAuthToken() },
muteHttpExceptions: true
}).getBlob();
return blob;
}
Reference:
Download files

Google Apps Scripts: import (upload) media from Google Drive to Google Photos?

I see that we can import (upload) media (photos, videos,...) from Google Drive to Google Photos. My goal is: do this task with code.
I have successfully got a list of photos from Google Drive, and I store their IDs in an Array. I have this code:
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
}
I have searched the docs of Google Script, but I couldn't find any API of Google Photos.
Thanks.
You want to upload an image file in Google Drive to Google Photo.
You want to achieve this using Google Apps Script.
If my understanding is correct, how about this answer?
In this answer, I would like to achieve your goal using a Google Apps Script library of GPhotoApp. This library has the method for uploading a file in Google Drive to Google Photo.
Usage:
1. Linking Cloud Platform Project to Google Apps Script Project:
About this, you can see the detail flow at here.
2. Install library
Install this library.
Library's project key is 1lGrUiaweQjQwVV_QwWuJDJVbCuY2T0BfVphw6VmT85s9LJFntav1wzs9.
IMPORTANT
This library uses V8 runtime. So please enable V8 at the script editor.
About scopes
This library use the following 2 scopes. In this case, when the library is installed, these scopes are automatically installed.
https://www.googleapis.com/auth/photoslibrary
https://www.googleapis.com/auth/script.external_request
Sample script 1:
At first, please retrieve the album ID you want to upload. For this, please use the following script.
function getAlbumList() {
const excludeNonAppCreatedData = true;
const res = GPhotoApp.getAlbumList(excludeNonAppCreatedData);
console.log(res.map(e => ({title: e.title, id: e.id})))
}
Sample script 2:
Using the retrieved album ID, you can upload the image files to Google Photo. In this sample script, arrId of your script is used.
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)
}
Note:
In my environment, I could confirm that the above scripts worked.
References:
Photos Library API
GPhotoApp
Upload File and Insert into Photo Library
You will need to insure that this is a GCP and have the Drive API and Photo Library API enabled.
I'm using the following scopes:
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
The next thing is that you cannot upload to albums created by a User. You need to create you own albums from a script.
Here's what I used:
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);
}
I built an upload dialog as follows:
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;
}

Changing json file creation destination from dropbox to google drive

i need to have this code have the create the json file inside of google drive instead of drop box
I have experimented with a few things but i am not quite knowledgeable enough to make this change, i would show less code but i do not know where the problem lies
function main(spreadsheet_id) {
var json_dict = fillDict(spreadsheet_id)
var json_obj = convertDictToJSON(json_dict)
sendJSONToDropbox(json_obj)
};
function sendJSONToDropbox(json_object) {
var timestamp = timeStamp()
var parameters = {
"path": "/json_jobs/rhino" + "-" + timestamp + ".json",
"mode": "add", // do not overwrite
"autorename": true,
"mute": false // notify Dropbox client
};
var headers = {
"Content-Type": "application/octet-stream",
'Authorization': 'Bearer ' + 'dropbox_access_token',
"Dropbox-API-Arg": JSON.stringify(parameters)
};
var options = {
"method": "POST",
"headers": headers,
"payload": json_object
};
var API_url = "https://content.dropboxapi.com/2/files/upload";
var response = JSON.parse(UrlFetchApp.fetch(API_url, options).getContentText());
Using the DriveApp class, it is not too difficult:
function sendJSONToGDrive(json_object) {
var timestamp = timeStamp();
var fileName = "rhino" + "-" + timestamp + ".json";
var fileContent = JSON.stringify(json_object);
var myFolder = DriveApp.getFolderById('YOUR_FOLDER_ID');
myFolder.createFile(fileName, fileContent, 'application/json');
}
You just have to replace YOUR_FOLDER_ID for your actual destination folder's id.
For more information on how to use the Drive API from Google Apps Script, I recommend you check out the following link: https://developers.google.com/apps-script/reference/drive

Save Document without closing

How do I save the current document as docx without closing through saveAndClose() first? I want to create multiple docx files from the same original Google Docs document on which my Script is running.
You can export a docs to docx with URL fetch:
function myFunction() {
var doc_id = 'YOUR DOCUMENT ID';
var url = 'https://docs.google.com/feeds/download/documents/export/Export?id=' + doc_id + '&exportFormat=docx';
var options = {
headers: {
Authorization: "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true
}
var response = UrlFetchApp.fetch(url, options);
var doc = response.getBlob();
DriveApp.createFile(doc).setName('myDocxFile1');
DriveApp.createFile(doc).setName('myDocxFile2');
}