Can I download file from URL link generated by google apps script - google-apps-script

Please help I'm learning google-apps-script for short time.
I want to download file from remote site by url generating from data that stores in my spreadsheet.
for example, i have 2 paremeters:
Cell1 = val1, val2, ... valN
Cell2 = val21, val22, ... val2N
I split string from cell data to Arrays and than generate URL. for example: http://mysite.com/files/file.val1.val22.zip
Than i need to download file from this link...
Can I do this process automaticaly ?

This example function will retrieve your zip file, and place it into your Google Drive in folder "StackOverflow". You can also download a more complete version from this gist.
function getFile(fileURL) {
// see https://developers.google.com/apps-script/class_urlfetchapp
var response = UrlFetchApp.fetch(fileURL);
var fileBlob = response.getBlob()
var folder = DocsList.getFolder('StackOverflow');
var result = folder.createFile(fileBlob);
debugger; // Stop to observe if in debugger
}
For example:
getFile( "http://mysite.com/files/file.val1.val22.zip" );
Note that you cannot download per se, since you have no access to your PC's resources (e.g. file system) from apps-script. The file is still in "the cloud"... in this case, it's been copied from the web site it was on, into Google Drive. If you're running the Drive app, though, the file will now sync to your PC.

Yes, You can.
Hope below code can solve your problem:
//Declare function
function downloadFile() {
//Getting url,existing name and new name for image from the sheet in
//variable url, name and new_name respectively
var sh = SpreadsheetApp.getActiveSheet();
var row = sh.getLastRow();
Logger.log(row);
for (var i = 2; i <= row; i++) {
var url = sh.getRange(i, 10).getValue();
Logger.log(url);
var name = sh.getRange(i, 13).getValue();
var new_name = sh.getRange(i, 4).getValue();
//Creating authentication token for downloading image, it may not be //required if image can be downloaded without login into
var user = "***************";
var password = "************";
var headers = {
"Accept": "application/xml",
"Content-Type": "application/xml",
"Authorization": "Basic " + Utilities.base64Encode(user + ":" + password)
};
//defining method to download file
var options = {
"method": "get",
"headers": headers
};
//Getting folder name where to store downloaded image
var folders = DriveApp.getFoldersByName('test');
while (folders.hasNext()) {
var folder = folders.next();
Logger.log(folder.getName());
}
//Getting response on hit of url using downloading method defined //earlier storing in Blob
var response = UrlFetchApp.fetch(url, options).getBlob();
//Creating image in folder defined with response in blob and logging same file //in log to check, if required
var file = folder.createFile(response);
Logger.log(file);
//renaming image
var images = folder.getFiles();
while (images.hasNext()) {
var image = images.next();
file.setName(new_name);
Logger.log(image.getName());
}
}
}
//Hope you get it now

It's worked for me.
function downloadFile() {
var url = "https://raw.githubusercontent.com/hoat23/VisionArtificialAndImageProcessing/master/bin/utils_imgprocessing.py"
Logger.log(url);
var response = UrlFetchApp.fetch(url);
var text = response.getContentText()
var newFile = DriveApp.createFile('testfilegoogle.txt',text);
debugger; // Stop to observe if in debugger
}
//Hope you get it now

Related

How to convert all types of files format that downloaded from url to pdf by using Apps Script

So, I have a case that I need to change all types of format (JPEG, PNG, doc, etc) from file that has been downloaded from url to pdf.
The process that I want:
First, there is a url that being generated by some application to the spreadsheet.
This url contain a file with not specified format (So, it can be JPEG, png, doc, pdf, etc). I need to download the file from the url and convert it to pdf format. After convert the file to pdf format, then the converted file will be saved in google drive and the file link from google drive will be inserted on spreadsheet.
Notes:
So, If this kind of thing is impossible to do, then you can make the other way like if the file format is .csv, .xlsx, .xls, .png, .jpeg, .pdf, or .doc, then it will convert the file to .pdf.
This is the illustration of the spreadsheet that I want to make:
Url File
Drive link
https://..../file1.jpeg
https://drive/.../file1.pdf
https://..../file2.csv
https://drive/..../file2.pdf
I have already made the code, but my code is still get the error because I only change the format (.doc) from the filename (filename.doc -> filename.pdf) and when I download the file it will not open because of that. If you guys have any suggestion to fix my code or have any different answer, It can be very helpful! Thank you
Here is the code that I've made:
function convert() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("");
var data = sheet.getDataRange().getValues();
var folder_id = '';
var array = [];
for (let i in data.length) {
if (data[i][2] != "" && data[i][16] == "") { //condition for if column 3 is having a url and the drive link is still empty, then get the url
array.push([data[i][2]]);
var get_name = array.toString().split("/")[7]; //to get the file name
var deleteformat= get_name .toString().split(".")[0]; //to delete the format
var response = UrlFetchApp.fetch(array, { muteHttpExceptions: true });
var rc = response.getResponseCode();
if (rc == 200) {
var fileBlob = response.getBlob().setName(deleteformat+ '.pdf');
var folder = DriveApp.getFolderById(folder_id );
if (folder != null) {
var file = folder.createFile(fileBlob);
var fileName = file.getName();
}
}
var file = DriveApp.getFolderById(folder_id ).getFiles();
while (file.hasNext()) {
var xfile = file.next();
if (xfile.getName() == fileName) {
var file_id = xfile.getId();
var url = DriveApp.getFileById(file_id ).getUrl();
}
}
sheet.getRange(i + 1, 17).setValue(url);
sheet.getRange(i + 1, 3).clearContent();
}
}
}
Use Blob.getAs(), like this:
var fileBlob = response.getBlob().getAs('application/pdf').setName(deleteformat + '.pdf');
You will also have to fix the UrlFetchApp.fetch() line so that it references a URL rather an array.

Fetch file from external URL and upload to Google Drive using Apps Script

I'm not sure if this is even possible. I'm trying to fetch file that being uploaded to formfacade server via the add-on in google form. I'm using it to allow other non-gmail users to upload file without having to sign-in.
I referred to answer from Mogsdad and dheeraj raj in
Can I download file from URL link generated by google apps script to use UrlFetchApp to meet this objective. Below are my codes:
Method 1 :
function UrlFile2gdrive() {
var sheet=SpreadsheetApp.getActiveSheet();
var lrow=sheet.getLastRow();
//var fileURL=sheet.getRange(lrow,2).getValue();
var fileURL='https://formfacade.com/uploaded/1FAIpQLSfscYq_sbYcT2P3Sj3AvSD2zYKalIM0SKdPTESf1wE9Rq8qew/'
+'97dc1ee0-f212-11ea-95c3-bdb6c5ab13b3/2124651919/A%20Sample%20PDF.pdf'
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
var response=UrlFetchApp.fetch(fileURL,params);
Logger.log(response.getContentText());
var fileBlob=response.getBlob();
var folder='0B2b-M7h6xF-Mflk3dGswano2TnJ3dGlmZG8wOUREMFg4blM5SHBuM3lqYmdPOThZSTBTSWs'
var filename=fileURL.split("/").pop();
//var filename=fileURL.split("%2F").pop();
var file=decodeURIComponent(filename);
Logger.log("filename : "+file);
var newfile=DriveApp.getFolderById(folder).createFile(fileBlob.setName(file));
//var newfile=DriveApp.getFolderById(folder).createFile(response.setName(filename));
}
Method 2
//api-key : AIzaSyCcbdBCI-Kgcz3tE1N4paeF9a-vdi3Uzz8
//Declare function
function URL2gdriveWithPswd() {
//Getting url,existing name and new name for image from the sheet in
//variable url, name and new_name respectively
var sh = SpreadsheetApp.getActiveSheet();
var row = sh.getLastRow();
Logger.log(row);
//for (var i = 2; i <= row; i++) {
/*var url = sh.getRange(i, 2).getValue();
Logger.log(url);
var name = sh.getRange(i, 3).getValue();
var new_name = sh.getRange(i, 4).getValue();*/
var url = sh.getRange(row, 2).getValue();
Logger.log(url);
var filenm=url.split("/").pop();
var new_name=decodeURIComponent(filenm);
var name = sh.getRange(row, 3).getValue();
//var new_name = sh.getRange(row, 4).getValue();
//Creating authentication token for downloading image, it may not be //required if image can be downloaded without login into
var user = "dtestsys#gmail.com";
var password = "1851235656";
var headers = {
"Accept": "application/xml",
"Content-Type": "application/xml",
"Authorization": "Basic " + Utilities.base64Encode(user + ":" + password)
};
//defining method to download file
var options = {
"method": "get",
"headers": headers
};
//Getting folder name where to store downloaded image
var folders = DriveApp.getFoldersByName('File Uploader (File responses)');
while (folders.hasNext()) {
var folder = folders.next();
Logger.log(folder.getName());
}
//Getting response on hit of url using downloading method defined //earlier storing in Blob
var response = UrlFetchApp.fetch(url, options).getBlob();
//Creating image in folder defined with response in blob and logging same file //in log to check, if required
var file = folder.createFile(response);
Logger.log(file);
//renaming image
var images = folder.getFiles();
while (images.hasNext()) {
var image = images.next();
file.setName(new_name);
Logger.log("imagename : "+image.getName());
}
//}
}
However, both methods managed to get a file into my gdrive but the content consists of the html codes only (https://drive.google.com/file/d/1NYQoMmCQEoP3z6L8niq1mpvIx7xl83zu/view?usp=sharing), which I think the URL passed in google response sheet is just a "mask". I noticed that inside the file has some lines that mentioned api-key and code (next to user email address). Is it possible to achieve my objective? Are those api-key and code would be useful to get authorized to access the file and download it in gdrive?
I rechecked.The link produced and passed into my google sheet response is only the login page that redirects to another XML file. When I copied back the final URL after the original file content is displayed, the URL is as below:
https://storage.googleapis.com/formfacade-public/1FAIpQLSfscYq_sbYcT2P3Sj3AvSD2zYKalIM0SKdPTESf1wE9Rq8qew%2F97dc1ee0-f212-11ea-95c3-bdb6c5ab13b3%2F2124651919%2FA%20Sample%20PDF.pdf?GoogleAccessId=firebase-adminsdk-pve0p%40formfacade.iam.gserviceaccount.com&Expires=1599671507&Signature=fBzWej0fEgF6Aw7oCHX%2FTTUfHbcep%2Bj%2B%2FhB3fYFUDeq0SFTuyJ6jTnLWQJmldD6XkVug0%2BNki7ZPNo2ESufvIfQjhVLKXgvp7UiQheJ4GYL%2BtXgFLaUyglgemmfp7KSvIvPxpMcpC2lR8em3E5YIvMRr9tcfzagvusQYHEb9mlD7k833bVoqFUVWuP%2FkP8tl%2BHYVL15kSXAjtFif4QZpu%2FFHwSik89Keo78LKTm0U8hZiAMeYDQZWF6w1pcKpy04md3xKtDPwZYCoUWOOtKkCI6JLskE5HweDvMCGnDbxW8o6SWD%2BIC%2FlaNC6%2BJ81OB10cuRqwQPEc9LnfgCZK7b1A%3D%3D
When I pasted the above link, I got to see as per screenshot below:-
. So, I'm guessing they don't share direct access link to the uploaded file so that we are left with the option to buy/subscribe the paid version.
Would anyone knows if there's any better altrnative(s) I could use to achieve this objective? Like maybe a link with API-key just like what I learnt from #Tanaike in his previous answer on Convert-API to convert pdf file to PNG? Of course it has some limits for the free version but it still is a very helpful solution.
You are not assigning content-type of the blob anywhere. But if you do the naming right it would not matter. In method 1 you are trying to set a name on the blob when you should be setting it on the file created from the Blob.
Try setting the name on the file after creating it.
Example:
function myFunction() {
var url ="http://www.africau.edu/images/default/sample.pdf";
var response = UrlFetchApp.fetch(url);
console.log(response.getResponseCode());
var blob=response.getAs('application/pdf');
var folder = "<SOME-FOLDER-ID>";
var fileName=decodeURIComponent(url.split("/").pop());
console.log("File named : "+fileName);
var file=DriveApp.getFolderById(folder).createFile(blob);
// Set the name to the created file after creating it!
file.setName(fileName);
}
For reference see class File.

Google Apps Script how to export specific sheet as csv format

In MIT Inventor II, I use web component to get SpreadsheetID and SheetID through doGet() of google apps script. After I get the information I use another web component to set url as below to get csv-formatted file from specific sheet. My question is how to make GAS to get SpreadsheetID & SheetID and then export csv file at one time, so that I don't have to use 2 web components in Inventor side?
GAS codes is as below. This is to "return" spreadsheetID and sheetID.
function doGet(e) {
filename = e.parameter.account;
fileList = DriveApp.getFilesByName(filename);
while (fileList.hasNext()) {
var fileID = fileList.next().getId()
}
var file = SpreadsheetApp.openById(fileID) ;
sheet = file.getSheetByName("Message").activate()
var messageID = sheet.getSheetId();
return ContentService.createTextOutput([fileID,messageID]);
After I got SpreadsheetID & SheetID, I have to set 2nd web component from Inventor side to get csv file, see below.
https://docs.google.com/spreadsheets/d/xxxxSpreadsheetIDxxxx/edit#gid=sheetID
Here is how you can create a csv file of a selected sheet in google drive:
function sheetToCsv()
{
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheet_Name = "Sheet1"
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheet_Name)
var sheetNameId = sheet.getSheetId().toString();
params= ssID+"/export?gid="+sheetNameId +"&format=csv"
var url = "https://docs.google.com/spreadsheets/d/"+ params
var result = UrlFetchApp.fetch(url, requestData);
var resource = {
title: sheet_Name+".csv",
mimeType: "application/vnd.csv"
}
var fileJson = Drive.Files.insert(resource,result)
}
The code creates a csv file that has the content of Sheet1.
In order to run the aforementioned function you need to activate the Advanced Drive Service.
Explanation:
Go to Resources => Advanced Google Services => activate Drive API
Another option is to create the csv file to a particular folder, then you need to replace the resource part of the code with this:
var folder_id ='id';
var resource = {
title: sheet_Name+".csv",
mimeType: "application/vnd.csv",
parents: [{ id: folder_id }]
}
My application was how to save a tab of a Google sheets spreadsheet to a CSV file in a shared drive. Doing it to the default "My Drive" was relatively easy based on Marios' answer in this post, but I struggled with this for a shared drive while until I came across ziganotschka's example which solved my problem.
Code for my simple App Script is:
function sheetToCsv()
{
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheet_Name = "[Your sheet name goes here]";
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheet_Name);
var sheetNameId = sheet.getSheetId().toString();
params= ssID+"/export?gid="+sheetNameId +"&format=csv";
var url = "https://docs.google.com/spreadsheets/d/"+ params;
var result = UrlFetchApp.fetch(url, requestData);
var resource = {
title: sheet_Name+".csv",
mimeType: "MimeType.CSV",
parents:[{
"id": "[Your Shared Drive Folder ID goes here]"
}]
}
var optionalArgs={supportsAllDrives: true};
var fileJson = Drive.Files.insert(resource, result, optionalArgs);
}
I added a timestamp to the file name and a trigger to cause the script to execute daily via a timer.

Downloading a Google Slides presentation as PowerPoint doc using Google Apps Script?

The GUI of Google Slides offers to download a GSlides presentation as a Powerpoint (myFile.pptx). I could not find the equivalent in the Google Apps Script documentation - any pointer?
EDIT
Thanks to comments and answers, I tried this snippet:
function testFileOps() {
// Converts the file named 'Synthese' (which happens to be a Google Slide doc) into a pptx
var files = DriveApp.getFilesByName('Synthese');
var rootFolder = DriveApp.getRootFolder();
while (files.hasNext()) {
var file = files.next();
var blobPptx = file.getBlob().getAs('application/vnd.openxmlformats-officedocument.presentationml.presentation');
var result = rootFolder.createFile(blobPptx);
}
}
It returns an error:
Converting from application/vnd.google-apps.presentation to
application/vnd.openxmlformats-officedocument.presentationml.presentation
is not supported. (line 7, file "Code")
SECOND EDIT
As per another suggestion in comments, I tried to make an http call from Google App Script, that would directly convert the gslides into pptx, without size limit. It produces a file on G Drive, but this file is corrupted / unreadable. The GAS script:
function convertFileToPptx() {
// Converts a public Google Slide file into a pptx
var rootFolder = DriveApp.getRootFolder();
var response = UrlFetchApp.fetch('https://docs.google.com/presentation/d/1Zc4-yFoUYONXSLleV_IaFRlNk6flRKUuAw8M36VZe-4/export/pptx');
var blobPptx = response.getContent();
var result = rootFolder.createFile('test2.pptx',blobPptx,MimeType.MICROSOFT_POWERPOINT);
}
Notes:
I got the mime type for pptx here
using the mime type 'pptx' returns the same error message
How about this modification?
Modification point:
response.getContent() returns byte array. So please use response.getBlob().
Modified script:
function convertFileToPptx() {
var fileId = "1Zc4-yFoUYONXSLleV_IaFRlNk6flRKUuAw8M36VZe-4";
var outputFileName = "test2.pptx";
var url = 'https://docs.google.com/presentation/d/' + fileId + '/export/pptx';
var rootFolder = DriveApp.getRootFolder();
var response = UrlFetchApp.fetch(url);
var blobPptx = response.getBlob();
var result = rootFolder.createFile(blobPptx.setName(outputFileName));
}
Note:
If you want to convert Google Slides, which are not published, in your Google Drive, please use access token. At that time please modify url as follows.
var url = 'https://docs.google.com/presentation/d/' + fileId + '/export/pptx?access_token=' + ScriptApp.getOAuthToken();
DriveApp.createFile() creates a file on root folder as the default.
References:
Class HTTPResponse
getOAuthToken()
As mentioned by tehhowch, you could get the Google Slide file from your Drive and get it as a .pptx. (Not sure of mime type.)
File#getAs:
I add all modifications with token part and specific folder
function convertFileToPptx() {
var fileId = "Your File ID";
var outputFileName = "name.pptx";
var url = 'https://docs.google.com/presentation/d/' + fileId + '/export/pptx';
//var rootFolder = DriveApp.getRootFolder();
var rootFolder = DriveApp.getFolderById("Your Folder ID")
var params = {method:"GET", headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
var response = UrlFetchApp.fetch(url,params);
var blobPptx = response.getBlob();
var result = rootFolder.createFile(blobPptx.setName(outputFileName));
}
To get the byte[] do:
function downloadAsPPTX(){
var presentation = SlidesApp.getActivePresentation();
var fileId = presentation.getId();
var url = 'https://docs.google.com/presentation/d/' + fileId + '/export/pptx';
var response = UrlFetchApp.fetch(url);
var blobPptx = response.getBlob();
Logger.log("size: "+blobPptx.getBytes().length);
}

Appscript API for fetching access permissions of team drive

I am trying to generate a report of all access permissions currently various users have in Team Drive. Is there any API in Appscript to Fetch this data?
There doesn't seem to be any method for getting Drive permissions sorted by username, so you will need to implement this business logic yourself. According to the documentation, sending a GET request to the API endpoint below will get you the list of permissions for the Team Drive (use Team Drive ID instead of file id):
https://www.googleapis.com/drive/v3/files/fileId/permissions
I don't have any Team Drives set up - the example below is based on getting permissions for a single file using Drive REST API. Before the code can be executed, you must prove your identity by including API key in URL parameters and passing OAuth token in the headers of your 'GET'request.
The API key can be obtained from Google Cloud console. Enable the Drive API and click the key icon in the left menu to set up credentials. Choose "API key" from the drop-down and copy the value.
Your script must pass the token that includes all required authorization scopes to the API endpoint. OAuth scopes are set explicitly in the manifest file. In Script Editor, select "View - Show manifest file" and add relevant scopes. Scopes used in my manifest file are for accessing Drive Files and calling external services via UrlFetchApp:
"oauthScopes": [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/script.external_request"]
Finally, get the list of permissions for the file:
var fileId = "FILE_ID";
var apiKey = "API_KEY";
var apiUrl = "https://www.googleapis.com/drive/v3/files/fileId/permissions";
var token = ScriptApp.getOAuthToken();
var header = {"Authorization":"Bearer " + token};
var options = {
"method":"GET",
"headers": header,
"muteHttpExceptions": true
};
var res = UrlFetchApp.fetch(apiUrl.replace("fileId", fileId) + "?key=" + apiKey, options)
.getContentText();
var permissions = JSON.parse(res);
Logger.log(permissions);
Updates with help from Anton's answer. (Working with Appmaker as well).
Here's how I have achieved it,
function fileExport(folderId) //pass folder id or drive/team drive id to fetch permissions
{
var parent = DriveApp.getFolderById(folderId);
var path = DriveApp.getFolderById(folderId).getName();
var fileName = 'Permisssions_' + new Date(); //define file name
var newExport = SpreadsheetApp.create(fileName); // create new spreadsheet
var header = ["Path","Folder","File Name","Email","Role","Name","DocUrl"]; //define header
newExport.appendRow(header); // append header to spreadsheet
newExport.setFrozenRows(1);
newExport.getRange("A1:H1").setFontWeight("bold");
//traverse through each folder under current folder
getChildFolders(parent,newExport,path);
//appned files associated with current folder
var files = parent.getFiles();
while (files.hasNext()) {
var file = files.next();
var permitFile= makeRestCall(file.getId());
for(var j=0; j<permitFile.length;j++)
{
newExport.appendRow([path,'',file.getName(),permitFile[j].emailAddress, permitFile[j].role,permitFile[j].displayName,file.getUrl()]);
}
}
return 'File exported successfully to this path:'+ newExport.getUrl();
}
//Iterate through child folders using recursive call
function getChildFolders(parent,newExport,path) {
var childFolders = parent.getFolders();
while (childFolders.hasNext()) {
var childFolder = childFolders.next();
path = path +'--'+childFolder.getName();
var permit= makeRestCall(childFolder.getId());
for(var i=0; i<permit.length;i++)
{
newExport.appendRow([path,childFolder.getName(),'',permit[i].emailAddress, permit[i].role,permit[i].displayName,childFolder.getUrl()]);
}
var files = childFolder.getFiles();
while (files.hasNext()) {
var file = files.next();
var permitFile= makeRestCall(file.getId());
for(var j=0; j<permitFile.length;j++)
{
newExport.appendRow([path,'',file.getName(),permitFile[j].emailAddress, permitFile[j].role,permitFile[j].displayName,file.getUrl()]);
}
}
// Recursive call for any sub-folders
getChildFolders(childFolder,newExport,path);
}
}
function makeRestCall(fileOrFolderId) //make rest call to fetch permissions
{
var apiUrl = "https://www.googleapis.com/drive/v3/files/fileId/permissions";
var token = ScriptApp.getOAuthToken();
var header = {"Authorization":"Bearer " + token};
var options = {
"method":"GET",
"headers": header
};
var response = UrlFetchApp.fetch(apiUrl.replace("fileId", fileOrFolderId) + "?supportsTeamDrives=true&fields=*", options)
.getContentText();
var dataAll = JSON.parse(response);
var permit = dataAll.permissions;
return permit;
}