Embed google spreadsheets without publishing - google-apps-script

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

Related

Google Sheet Script to download

excuse my bad English.
I have a main Google Sheet that export that from other sheets to fill the information. This action depends on the number in a cell, then I would download the PDF of the sheet. But the name would automatically be the sheet's name. Is there a script I could use so that the name of the pdf file would be one of the data on a specific cell?
I would gladly appreciate the help. This is so I could get this done more quickly since there are so many people.
I tried to follow some code from another thread: [https://stackoverflow.com/questions/56215898/how-to-download-single-sheet-as-pdf-not-export-to-google-drive]
And ended up with something like this:
function onOpen() {
var submenu = [{name:"Save PDF", functionName:"generatePdf"}];
SpreadsheetApp.getActiveSpreadsheet().addMenu('Export', submenu);
}
function generatePdf() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetId = ss.getActiveSheet().getSheetId();
var valor = SpreadsheetApp.getActiveSheet().getRange('G2').getValue();
var filename = valor;
// Creat PDF file as a temporary file and create URL for downloading.
var url = "https://docs.google.com/a/mydomain.org/spreadsheets/d/" + ss.getId() + "/export?exportFormat=pdf&gid=" + sheetId + "&access_token=" + ScriptApp.getOAuthToken();
var blob = UrlFetchApp.fetch(url).getBlob().setName(filename);
var file = DriveApp.createFile(blob);
var dlUrl = "https://drive.google.com/uc?export=download&id=" + file.getId();
// Open a dialog and run Javascript for downloading the file.
var str = '<script>window.location.href="' + dlUrl + '"</script>';
var html = HtmlService.createHtmlOutput(str);
SpreadsheetApp.getUi().showModalDialog(html, "sample");
file.setTrashed(true);
// This is used for closing the dialog.
Utilities.sleep(3000);
var closeHtml = HtmlService.createHtmlOutput("<script>google.script.host.close()</script>");
SpreadsheetApp.getUi().showModalDialog(closeHtml, "sample");
}
Didn't work, just maybe one time after so many tries.
Then I tried this: https://gist.github.com/primaryobjects/6370689c6f5fd3799ea53f89551eced7
But the PDF that exports have the cell's lines in the background... So, it doesn't look good.
Is there a way for the export to use the pdf download method, so it looks clean, but automatically put the name of the pdf from a cell value?

How to get video duration of google drive file via API?

On my website, I am hosting a few videos via Google Drive. On my sidebar, there is a thumbnail of the videos and I'd like to show the duration of the video in the corner. I have looked at two similar questions (here and here) to solve this problem. This is what I produced from looking at these two problems:
function sample1() {
console.log("running script");
var fileId = "theFileID"; // Please set the file ID of the video file.
var fields = "mimeType,name,videoMediaMetadata"; // duration is included in "videoMediaMetadata"
var url = "https://www.googleapis.com/drive/v3/files/" + fileId + "?fields=" + encodeURIComponent(fields) + "&access_token=" + ScriptApp.getOAuthToken();
var res = UrlFetchApp.fetch(url, {headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}});
var obj = JSON.parse(res);
console.log("filename: %s, duration: %s seconds", obj.name, obj.videoMediaMetadata.durationMillis / 1000);
}
sample1();
However, when I check the console after running this script, nothing is printed after "running script". Is there a different approach I should be taking in my program when attempting to solve this problem via Google APIs?
Using the Drive API method Files: get with Apps Script I have been able to get the durationMillis from the video.
You have to add the Drive API Advanced Services on the Apps Script project:
function getVideoLength() {
var fileId = "FILE ID";
var returnedFile = Drive.Files.get(fileId);
Logger.log(returnedFile.videoMediaMetadata.durationMillis)
}

Add a button to automatically download a google sheet to excel from a google application script

I have an application made on google than handdle different sheets on a google workbook. I need to add a button to allow users download some of these sheets but in an excel format if is possible. I took one code from StackOv and try to modify it, as i donĀ“t want it name the file and save it in drive, i only need it download as same that when from excel it is download in Book1 ("libro1") without saving anywhere. THK!
var ss = SpreadsheetApp.openById("fffffffffffffffffffffffffffff...myID");
var sheetId = ss.ss.getSheetByName('nameSheetNeedToDownload');
var url = "https://docs.google.com/spreadsheets/d/" + sheetId + "/export?format=xlsx&access_token=" + ScriptApp.getOAuthToken();
var blob = UrlFetchApp.fetch(url).getBlob().setName(name + ".xlsx");
createFile(blob); // here need to create but without saving
THK you Tanaike!...Yes here i copy the code i have
function downloadAsXlsx() {
var bogus = DriveApp.getRootFolder();
var spreadSheet = SpreadsheetApp.openById('WorkbookID');
var ssID = spreadSheet.getSheetByName('SheetName');
Logger.log(ssID);
var url = "https://docs.google.com/spreadsheets/d/"+ssID+"/export?format=xlsx";
var params = {method:"GET", headers:{"authorization":"Bearer "+
ScriptApp.getOAuthToken()}};
var response = UrlFetchApp.fetch(url, params);
// save to drive
DriveApp.createFile(response);
}

Authorization for Contacts API across domain access using Google Apps Script

I am working in a Google Apps Script web app using Contacts API v3, to access all user's contacts within the domain.
I have no problems so far with Contacts API requests, but I have no idea yet on how to get authorization across the domain to access any user's contacts (other than me).
I have tried OAuth domain key from cpanel - advanced tools, with no results so far. I got "Request failed for returned code 403 (Forbidden)" when trying with other users within the domain
Thanks in advance, Fausto
EDIT-1 (Mar.05) I'm closer now, but need a bit of help
I have combined 2LO (2-legged OAuth) with oauth_signature and signing request, but still getting Error 401 (Client Error)!!1. This is the sample code I am working with now.
function test_xOAuth() {
// OAUTH_CONSUMER_SECRET from GApps: control panel > advanced tools > Manage OAuth domain key
var domain = Session.getEffectiveUser().getEmail().split("#")[1];
var xuser = 'fausto#thexs.ca';
var method = "GET";
var baseUrl = "https://www.google.com/m8/feeds/groups/default/full";
var timestamp = getTimestamp();
var paramsJson = {
oauth_consumer_key : domain,
oauth_nonce : getNonce(timestamp),
oauth_signature_method : "HMAC-SHA1",
oauth_timestamp : timestamp,
oauth_version : "1.0"
};
var paramsStringArray = [];
for (var k in paramsJson) paramsStringArray.push(k + '="' + paramsJson[k] + '"');
var paramsString = paramsStringArray.join("&") + '&xoauth_requestor_id=' + xuser;
var signatureBaseString = method +"&"+ encodeURIComponent(baseUrl) +"&"+ encodeURIComponent(paramsString);
var signatureBytes = Utilities.computeHmacSha256Signature(signatureBaseString, OAUTH_CONSUMER_SECRET);
var signature = Utilities.base64Encode(signatureBytes);
var xoauthString = 'OAuth ' + paramsStringArray.join(",") + ',oauth_signature="' + signature + '"';
var options = {
method : method,
headers : {"Authorization" : xoauthString}
}
var url = baseUrl + '?xoauth_requestor_id=' + 'fausto#thexs.ca';
var response = UrlFetchApp.fetch(url, options);
var responseHeader = response.getHeaders();
var responseText = response.getContentText();
return HtmlService.createHtmlOutput(responseText);
}
var getTimestamp = function(){
return (Math.floor((new Date()).getTime() / 1000)).toString()
}
var getNonce = function(timestamp){
return timestamp + Math.floor( Math.random() * 100000000)
}
Thanks in advance for any help !! Fausto
First, you should properly URL-encode all parameters before you calculate signature.
Second, strip the quotes, you don't really need them, especially in the base string.
Third, you should use signature method you're specifying i.e. HMAC-SHA1. And last but not least, despite you're not using OAuth token you still need to include '&' in the encryption key.
Here's the code that works properly:
var OAUTH_CONSUMER_SECRET = 'you secret goes here';
var domain = 'domain.tld';
var username = 'test.user';
var xuser = encodeURIComponent(username+'#'+domain);
var method = "GET";
var baseUrl = "https://www.google.com/m8/feeds/groups/default/full";
var timestamp = Math.round(new Date().getTime() / 1000);
var paramsJson = {
oauth_consumer_key : domain,
oauth_nonce : timestamp,
oauth_signature_method : "HMAC-SHA1",
oauth_timestamp : timestamp,
oauth_version : "1.0"
};
var paramsStringArray = [];
for (var k in paramsJson) paramsStringArray.push(k + '=' + encodeURIComponent(paramsJson[k]));
var paramsString = paramsStringArray.join("&") + "&xoauth_requestor_id="+xuser;
var signatureBaseString = method +"&"+ encodeURIComponent(baseUrl) +"&"+ encodeURIComponent(paramsString);
var signatureBytes = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_1, signatureBaseString, OAUTH_CONSUMER_SECRET+'&');
var signature = encodeURIComponent(Utilities.base64Encode(signatureBytes));
var xoauthString = 'OAuth ' + paramsStringArray.join(", ") + ', oauth_signature="' + signature + '"';
var options = {
method : method,
headers : {authorization: xoauthString}
}
var url = baseUrl + '?xoauth_requestor_id=' + xuser;
var response = UrlFetchApp.fetch(url, options);
I have not performed the access to contacts like you mention here but I have manage to perform a similar action to act as a domain user and access the users Google drive, The one limiting factor to this was that to be able to do what you are trying to do is that you have to be a super administrator for you Google domain and the access level i had to use was trough URL Requests and REST API, You might also what to have a look at Google Domain Shared Contacts API to be able to manage your shared contacts in a Google domain and leave everyone's personal contacts to be managed by them self

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.