Google script Data Uri Download not initalising automatically - google-chrome

I am trying to make a href-link (dataUri) work in my google sheet on our Company Terminals' Chrome Browser.
The below code works fine on my private PC Chrome Browser, but not in the Company Browser.
I used the code from User TheMaster seen at the following link:
How to download single sheet as PDF (not export to Google Drive)
Chrome Browser Version in Company: Version 83.0.4103.61 (Official Build) (64-Bit)
The problem is, that the automatic download is not initialised. The clickable link does not work on left button press, but one can save the PDF with right click "save under".
Is there any setting that needs to be changed in order to make the automatic download work?
Thank you very much.
function downloadPdfToDesktop() {
var ss = SpreadsheetApp.getActive(),
id = ss.getId(),
sht = ss.getActiveSheet(),
shtId = sht.getSheetId(),
url =
'https://docs.google.com/spreadsheets/d/' +
id +
'/export' +
'?format=pdf&gid=' +
shtId;
var val = 'PDFNAME';//custom pdf name here
val += '.pdf';
//can't download with a different filename directly from server
//download and remove content-disposition header and serve as a dataURI
//Use anchor tag's download attribute to provide a custom filename
var res = UrlFetchApp.fetch(url, {
headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() },
});
SpreadsheetApp.getUi().showModelessDialog(
HtmlService.createHtmlOutput(
'<a target ="_blank" download="' +
val +
'" href = "data:application/pdf;base64,' +
Utilities.base64Encode(res.getContent()) +
'">Click here</a> to download, if download did not start automatically' +
'<script> \
var a = document.querySelector("a"); \
a.addEventListener("click",()=>{setTimeout(google.script.host.close,10)}); \
a.click(); \
</script>'
).setHeight(50),
'Downloading PDF..'
);
}

Related

Google Slides to PNG with Apps Script [duplicate]

Good Morning All. I have written a short script which batch-creates [single page] Google Slides based on rows from a spreadsheet. While in the loop for each creation, I would like to create a PNG of the Slide in Google Drive (or download on the user's desktop). These pictures should be the same specs as if a user clicked File>Download>PNG - the heavy small text requires full projector HD - so I don't believe I can use the "Thumbnail" function which appears limited to 1600 pixels.
My code below generates the error "Converting from text/html to image/png is not supported" - so I'm not sure if this is a limitation of the API or a problem with my coding. Thank you in advance.
var options =
{
"contentType" : "image/PNG"
};
var url = 'https://docs.google.com/presentation/d/' + presentationCopyId + '/export/PNG';
var response = UrlFetchApp.fetch(url, options);
var image = response.getAs(MimeType.PNG);
image.setName(SlideName);
DriveApp.createFile(image);
Yes, It is possible.
You can use Google slide API and make a PNG file of every page of Google slide.
Here is the code,
BUT first you have to enable API as following
open script editor
click on resources-> Advanced Google Services
Enable Google slide API and Drive API .
click on ok
now copy and paste this code,
and write your slide ID in presentationID.
function generateScreenshots() {
var presentationId = "***ADD YOUR Google Slide ID Only***";
var presentation = SlidesApp.openById(presentationId);
var baseUrl =
"https://slides.googleapis.com/v1/presentations/{presentationId}/pages/{pageObjectId}/thumbnail";
var parameters = {
method: "GET",
headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() },
contentType: "application/json",
muteHttpExceptions: true
};
// Log URL of the main thumbnail of the deck
Logger.log(Drive.Files.get(presentationId).thumbnailLink);
// For storing the screenshot image URLs
var screenshots = [];
var slides = presentation.getSlides().forEach(function(slide, index) {
var url = baseUrl
.replace("{presentationId}", presentationId)
.replace("{pageObjectId}", slide.getObjectId());
var response = JSON.parse(UrlFetchApp.fetch(url, parameters));
// Upload Googel Slide image to Google Drive
var blob = UrlFetchApp.fetch(response.contentUrl).getBlob();
DriveApp.createFile(blob).setName("Image " + (index + 1) + ".png");
screenshots.push(response.contentUrl);
});
return screenshots;
}
This answer is outdated, leaving up for documentation purposes but please see other answer.
Answer:
Unfortunately it is not possible to export a Slides as a PNG file using the the Slides nor Drive APIs.
More Information:
According to the documentation, there are only four available MimeTypes for exporting Presentations files:
application/vnd.openxmlformats-officedocument.presentationml.presentation
application/vnd.oasis.opendocument.presentation
application/pdf
text/plain
Attempting to export to the image/png MIME Type results in the following error:
Converting from text/html to image/png is not supported
For testing purposes, I tried using the /export/pdf endpoint and making a second conversion to PNG from there like so:
function slidesAsPngAttempt() {
var presentationCopyId = "1Loa...pQs";
var options =
{
"contentType" : "application/pdf"
};
// for exporting to pdf the /export/pdf needs to be all lower case to avoid 404
var url = 'https://docs.google.com/presentation/d/' + presentationCopyId + '/export/pdf';
var response = UrlFetchApp.fetch(url, options);
var pdfAsblob = response.getBlob();
var image = pdfAsblob.getAs('image/png');
image.setName(DriveApp.getFileById(presentationCopyId).getName());
DriveApp.createFile(image);
}
Unfortunately, a similar error occurs when running var image = pdfAsblob.getAs('image/png'):
Converting from application/pdf to image/png is not supported.
From the same export MIME types reference documentation, the only export types available for PDF files are:
text/csv
text/tab-separated-values
application/zip
References:
G Suite documents and corresponding export MIME types
Google Apps Script - method Blob.getAs(contentType)

How do I download a Sheets file then send it to a server in .XLSX format?

I have a Drive with my files and would like to send them to my server for backing up. I would like to convert all Sheets to Excel format (.xlsx). So, I select my file and then click upload button and it goes to myfunction(). In myfunction, I download the .xlsx file and then send the text to my server but then I try to open it with Open Office and I get an error saying the file is corrupted. (I print off the url in the console and when I open that url in the browser it works correctly, though). I download the file in Scripts so that I can make sure it opens, as doing so offline on my server may not open it since it doesn't have proper permissions.
function myfunction(file, ext){
var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + file.getId() + "&exportFormat=xlsx";
var params = {
method : "get",
headers : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
};
console.log("url: "+url);
var txt = UrlFetchApp.fetch(url, params).getContentText();
var options = {
'method': 'POST',
'payload': {
file: file.getName() + '.xlsx',
file_body: txt,
},
};
var response = UrlFetchApp.fetch('https://example.com', options).getContentText();
console.log("upload response: "+response);
}
What am I doing wrong? Also, I am worried about Sheets that are on a team drive or are shared and want to make sure I can download those also.
EDIT:
I've also tried the getAs(contentType) but, unfortunately, it tells me that I can only download it as a PDF.

Embed google spreadsheets without publishing

I wan't to Embed google spreadsheets without publishing, this file set only me access.
I try like this :
function viewSheet(idSheet){
var ss = SpreadsheetApp.openById(idSheet);
var idSheet2 = ss.getSheetByName("Sheet2").getSheetId();
var url = "https://docs.google.com/spreadsheets/d/" + idSheet + "/pubhtml#gid=" + idSheet2;
return url ;
}
i don't wan't like this.
i wan't like this, this is i use publish in menu: "FILE -> Publish to the web" and i have URL not use code above !
P/s: Sorry my english is a bit poor, please guide me fix it !!!
How to publish to the Web with Apps Script
Your code attempts to retrieve the link to the published to the web version of the spreadsheet
However, before using this link, you need to enable the publishing first
This can be done with specifying the respective parameters of Drive revisions
Once you enabled publishing you can retrieve the link as you did before, however you should change the URL from
var url = "https://docs.google.com/spreadsheets/d/" + idSheet + "/pubhtml#gid=" + idSheet2;
to
var url = "https://docs.google.com/spreadsheet/pubhtml?key=" + idSheet + "&gid=" + idSheet2 + "&single=true";
Sample:
function viewSheet(idSheet){
var revisionsList = Drive.Revisions.list(idSheet);
var revisions = revisionsList.items;
var revisionId =revisions[revisions.length-1].id;
var lastRevision = Drive.Revisions.get(idSheet, revisionId);
lastRevision.published = true;
lastRevision.publishAuto = true;
lastRevision.publishedOutsideDomain = true;
Drive.Revisions.update(lastRevision, idSheet, revisionId);
var ss = SpreadsheetApp.openById(idSheet);
var idSheet2 = ss.getSheetByName("Sheet2").getSheetId();
var url = "https://docs.google.com/spreadsheet/pubhtml?key=" + idSheet + "&gid=" + idSheet2 + "&single=true";
return url ;
}
Be aware that for accessing Drive revisions you need to enable the advanced service Drive

Google Suite - Apps Script - Download Slides as PNG files via API

Good Morning All. I have written a short script which batch-creates [single page] Google Slides based on rows from a spreadsheet. While in the loop for each creation, I would like to create a PNG of the Slide in Google Drive (or download on the user's desktop). These pictures should be the same specs as if a user clicked File>Download>PNG - the heavy small text requires full projector HD - so I don't believe I can use the "Thumbnail" function which appears limited to 1600 pixels.
My code below generates the error "Converting from text/html to image/png is not supported" - so I'm not sure if this is a limitation of the API or a problem with my coding. Thank you in advance.
var options =
{
"contentType" : "image/PNG"
};
var url = 'https://docs.google.com/presentation/d/' + presentationCopyId + '/export/PNG';
var response = UrlFetchApp.fetch(url, options);
var image = response.getAs(MimeType.PNG);
image.setName(SlideName);
DriveApp.createFile(image);
Yes, It is possible.
You can use Google slide API and make a PNG file of every page of Google slide.
Here is the code,
BUT first you have to enable API as following
open script editor
click on resources-> Advanced Google Services
Enable Google slide API and Drive API .
click on ok
now copy and paste this code,
and write your slide ID in presentationID.
function generateScreenshots() {
var presentationId = "***ADD YOUR Google Slide ID Only***";
var presentation = SlidesApp.openById(presentationId);
var baseUrl =
"https://slides.googleapis.com/v1/presentations/{presentationId}/pages/{pageObjectId}/thumbnail";
var parameters = {
method: "GET",
headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() },
contentType: "application/json",
muteHttpExceptions: true
};
// Log URL of the main thumbnail of the deck
Logger.log(Drive.Files.get(presentationId).thumbnailLink);
// For storing the screenshot image URLs
var screenshots = [];
var slides = presentation.getSlides().forEach(function(slide, index) {
var url = baseUrl
.replace("{presentationId}", presentationId)
.replace("{pageObjectId}", slide.getObjectId());
var response = JSON.parse(UrlFetchApp.fetch(url, parameters));
// Upload Googel Slide image to Google Drive
var blob = UrlFetchApp.fetch(response.contentUrl).getBlob();
DriveApp.createFile(blob).setName("Image " + (index + 1) + ".png");
screenshots.push(response.contentUrl);
});
return screenshots;
}
This answer is outdated, leaving up for documentation purposes but please see other answer.
Answer:
Unfortunately it is not possible to export a Slides as a PNG file using the the Slides nor Drive APIs.
More Information:
According to the documentation, there are only four available MimeTypes for exporting Presentations files:
application/vnd.openxmlformats-officedocument.presentationml.presentation
application/vnd.oasis.opendocument.presentation
application/pdf
text/plain
Attempting to export to the image/png MIME Type results in the following error:
Converting from text/html to image/png is not supported
For testing purposes, I tried using the /export/pdf endpoint and making a second conversion to PNG from there like so:
function slidesAsPngAttempt() {
var presentationCopyId = "1Loa...pQs";
var options =
{
"contentType" : "application/pdf"
};
// for exporting to pdf the /export/pdf needs to be all lower case to avoid 404
var url = 'https://docs.google.com/presentation/d/' + presentationCopyId + '/export/pdf';
var response = UrlFetchApp.fetch(url, options);
var pdfAsblob = response.getBlob();
var image = pdfAsblob.getAs('image/png');
image.setName(DriveApp.getFileById(presentationCopyId).getName());
DriveApp.createFile(image);
}
Unfortunately, a similar error occurs when running var image = pdfAsblob.getAs('image/png'):
Converting from application/pdf to image/png is not supported.
From the same export MIME types reference documentation, the only export types available for PDF files are:
text/csv
text/tab-separated-values
application/zip
References:
G Suite documents and corresponding export MIME types
Google Apps Script - method Blob.getAs(contentType)

Uploading to Dropbox from Google Drive

As a test case, I'm trying to copy a file from Google Drive to Dropbox using Google Scripts
function pushBuild() {
// Setup OAuthServiceConfig
var oAuthConfig = UrlFetchApp.addOAuthService("dropbox");
oAuthConfig.setAccessTokenUrl("https://api.dropbox.com/1/oauth/access_token");
oAuthConfig.setRequestTokenUrl("https://api.dropbox.com/1/oauth/request_token");
oAuthConfig.setAuthorizationUrl("https://www.dropbox.com/1/oauth/authorize");
oAuthConfig.setConsumerKey(ScriptProperties.getProperty("dropboxKey"));
oAuthConfig.setConsumerSecret(ScriptProperties.getProperty("dropboxSecret"));
var fileName = "blah.zip"
var folderName = "upload_dir"
var docs = DocsList.getFolder(folderName).find(fileName);
for(n=0;n<docs.length;++n){
if(docs[n].getName() == fileName){
var ID = docs[n].getId();
var options = {
"oAuthServiceName" : "dropbox",
"oAuthUseToken" : "always",
"method" : "put",
"payload" : docs[n].getBlob().getBytes(),
"contentType" : "application/zip"
};
var response = UrlFetchApp.fetch("https://api-content.dropbox.com/1/files_put/sandbox/upload_dir/" + fileName, options);
Logger.log(response);
}
}
}
The authorization request for the application in Dropbox appears and it tells me that I've successfully authorized my app, but when I check, the app is not in the list of "My Apps", the file has not been uploaded and there are no entries in the log. The directory "upload_dir" exists on both GD and DB. I've tried the same code with "App Folder" and "Full Dropbox" app types, but get the same result.
Additionally, running the script again once again triggers the Authorization page, similar to
to appear, clicking "Allow" then shows the success screen but the application is not listed in "My Apps". Running the script again repeats the process.
Can anyone point out what I've done wrong?
Update
So, I've now tried to implement this using the individual api calls and am still not having any success.
function testOAuth() {
var timestamp = getTimestamp();
var nonce = getNonce(timestamp);
var authString = 'OAuth oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_signature="' + encodeURIComponent(ScriptProperties.getProperty("dropboxSecret") + '&') + '", oauth_consumer_key="' + ScriptProperties.getProperty("dropboxKey") + '"';
Logger.log(authString)
var options = {
method : "POST",
headers : {"Authorization" : authString}
}
var response = UrlFetchApp.fetch("https://api.dropbox.com/1/oauth/request_token",options);
var params = response.getContentText().split("&");
var map = new Map;
for(i = 0; i < params.length; i++){
var param = params[i].split("=");
map.put(param[0],param[1]);
}
var authStringx = "https://www.dropbox.com/1/oauth/authorize?oauth_token=" + map.get("oauth_token");
Logger.log(authStringx);
var response2 = UrlFetchApp.fetch(authStringx);
Logger.log(response2.getContentText());
var authString2 = 'OAuth oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_token="' + map.get("oauth_token") + '" , oauth_signature="' + encodeURIComponent(ScriptProperties.getProperty("dropboxSecret") + '&' + map.get("oauth_token_secret")) + '", oauth_consumer_key="' + ScriptProperties.getProperty("dropboxKey") + '",oauth_timestamp="'+ timestamp +'", oauth_nonce="' + nonce +'"';
Logger.log(authString2);
var options3 = {
"method" : "POST",
"Authorization" : authString2
}
var response3 = UrlFetchApp.fetch("https://api.dropbox.com/1/oauth/access_token", options3);
Logger.log(response3.getContentText());
}
var getTimestamp = function(){
return (Math.floor((new Date()).getTime() / 1000)).toString()
}
var getNonce = function(timestamp){
return timestamp + Math.floor( Math.random() * 100000000)
}
The code implementation for the map is here. The main problem that I can see is that authorize step does not invoke the Dropbox authorize end point (ie no browser redirection takes place to authorize the application). If I place a breakpoint just after the line Logger.log(authStringx); and manually visit the web page pasting in the contents of authStringx I get the screen to authorize my app. I accept that and get the message that the app is registered in "My Apps". I now let the program continue and I am greeted with the message
Any ideas?
Pram,
I was trying to accomplish the same task and came across your post. I am not a programmer, so I can't figure out the second part either (launching the authorization page fails), but I was able to complete the process in the third step and connect my app successfully.
Instead of:
var authString2 = 'OAuth oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_token="' + map.get("oauth_token") + '" , oauth_signature="' + encodeURIComponent(ScriptProperties.getProperty("dropboxSecret") + '&' + map.get("oauth_token_secret")) + '", oauth_consumer_key="' + ScriptProperties.getProperty("dropboxKey") + '",oauth_timestamp="'+ timestamp +'", oauth_nonce="' + nonce +'"';
Logger.log(authString2);
var options3 = {
"method" : "POST",
"Authorization" : authString2
}
var response3 = UrlFetchApp.fetch("https://api.dropbox.com/1/oauth/access_token", options3);
Logger.log(response3.getContentText());
I used:
var authtokenURL = "https://api.dropbox.com/1/oauth/access_token";
var authString2 = "?oauth_signature_method=PLAINTEXT&oauth_token=" + [MY_OAUTH_REQUEST_TOKEN] + "&oauth_signature=" + encodeURIComponent([MY_DROPBOX_CONSUMER_SECRET] + "&" + [MY_OAUTH_REQUEST_SECRET]) +"&oauth_consumer_key=" + [MY_DROPBOX_CONSUMER_KEY];
Logger.log(authString2);
var response3 = UrlFetchApp.fetch("https://api.dropbox.com/1/oauth/access_token" + authString2);
Logger.log(response3.getContentText());
I then got an email confirmation that I connected a new app to Dropbox, and my app does show up under Settings in my account. Anyway, as I said, I'm no programmer, so sorry for the ugly code. Thanks for supplying your code for me to make it this far. I hope this helps you at least move forward, even if it doesn't solve the underlying problem.
I am able to see this issue as well. There is something special going on here with Dropbox. You should check on their forums or with their API support team. Looks like they are not correctly accepting callback params. Perhaps this is a development mode limitation (vs. production mode). Or perhaps they are stringent about some POST vs GET differences that Google doesn't support.
This code below exhibits the same issue you described where the authorization is never complete.
function dropbox() {
var oAuthCfg = UrlFetchApp.addOAuthService("dropbox");
oAuthCfg.setAccessTokenUrl('https://api.dropbox.com/1/oauth/access_token');
oAuthCfg.setRequestTokenUrl('https://api.dropbox.com/1/oauth/request_token');
oAuthCfg.setAuthorizationUrl('https://api.dropbox.com/1/oauth/authorize');
oAuthCfg.setConsumerKey('DROPBOX_KEY');
oAuthCfg.setConsumerSecret('DROPBOX_SECRET');
var options = {oAuthServiceName:'dropbox',oAuthUseToken:'always'}
var url = 'https://api.dropbox.com/1/account/info';
var response = UrlFetchApp.fetch(url, options).getContentText();
Logger.log(response);
}
However, the same code works without issue with the Twitter OAuth 1 API. The code below should dump out JSON from your stream (once you substitute the tokens from your setup in http://dev.twitter.com
function twitter(){
var oAuthCfg = UrlFetchApp.addOAuthService('twitter');
oAuthCfg.setAccessTokenUrl('http://api.twitter.com/oauth/access_token');
oAuthCfg.setRequestTokenUrl('http://api.twitter.com/oauth/request_token');
oAuthCfg.setAuthorizationUrl('http://api.twitter.com/oauth/authorize');
oAuthCfg.setConsumerKey('TWITTER_KEY');
oAuthCfg.setConsumerSecret('TWITTER_SECRET');
var options = {oAuthServiceName:'twitter',oAuthUseToken:'always'}
var url = "http://api.twitter.com/1/statuses/user_timeline.json";
var response = UrlFetchApp.fetch(url, options).getContentText();
Logger.log(response);
}
If you are able to narrow this down to a Google issue log a bug here on the Issue Tracker.