Unable to serve download links in google apps script - google-apps-script

UPDATE: I have found a solution. This doesn't necessarily address every case, so I will leave the question open for a short time in case someone can enlighten me more. I solved it by changing the format of the url: Google Drive allows this format for downloading files:
https://docs.google.com/uc?export=download&id=FILE_ID
So I don't know if this is a problem for other URL's; nor actually exactly why the .getDownloadUrl() doesn't work ... maybe someone can explain. But for now this seems to work in the browsers that I can test ...
I have a simple WebApp script which I run on a Google Site by adding the Apps Script gadget. The gadget runs exactly as the Forms example on:
https://developers.google.com/apps-script/guides/html/communication#forms
The gadget is designed to do the following: when the page is loaded, a form is returned, and the user must enter a license key to get a link to download a product. My code serves the form OK, and gets the form submit OK; and it then validates the key, and if valid, sends back a link to download. All that works fine; and the problem is that no matter what I try to return for the download link, the caja iframe wrapper is preventing the click on the link from actually downloading the file.
My preferred URL to return is in fact via the Drive API: the download file is on the Google Drive, and I get the download link like so:
DriveApp.getFileById(downloadFileId).getDownloadUrl()
But when the returned link is clicked inside that caja iframe generated for the WebApp gadget, nothing happens. I have tried a few other URL formats pointing to that file on the Drive, but nothing is working for a download.
Is this possible?

.getDownloadUrl() method returns a temporary URL that can be used to download the file. This URL is valid only for a short period of time, after which it expires and does not return the file any more - that is probably why the links in your web app do not work. Can't remember exactly how long the URL is valid for, but I think it could be as short as 5 minutes.
Permanent download URL is stored in another file property: webContentLink. However, this property is not (yet) available through Google Apps Drive Service - you must use Advanced Drive Service to access it. You can enable Drive API under Advanced Google services in your script. After it is enabled, you can use it like so:
var file = Drive.Files.get(FILE_ID_HERE);
var dlUrl = file.webContentLink;
This will return the link just like the one you found and posted in your update. An advantage of using the Drive API to get the link, instead of hard-coding it, is that if Google ever changes the format of that URL, your code using Drive API to get the link will continue to work, while hard-coded links will not.
Full Drive Web API reference (what Advanced Drive Service uses) is at https://developers.google.com/drive/v2/reference/.

Related

How to get a direct link from Google Drive?

I know it is possible to get a link that will initiate a download of a file from Google Drive. But this is not exactly what I am looking for. I want to be able to have the link of a file with its extension.
For example, it is possible to do this with Dropbox. I am able to get a direct link if I change "www.dropbox.com" to "dl.dropboxusercontent.com". So if I have a video file, it will play on the browser's player instead of opening the page to download it.
With Google Drive I don't know how to do this. If I generate a direct link, it will then create a link that automatically starts a download. A direct link for a .txt file will not be rendered on the browser. It will be downloaded instead.
So, it is possible to have a direct link to a file in Google Drive that is not the direct link that starts downloading automatically, but instead with the directory/file.ext?
There are several things you need to understand about how the Google drive api works.
When you do a file.get with the Google Drive api it returns a file resource this is the response for the file itself. The information about it that google is willing to share with us. There are two fields here you may find interesting
The first thing you should know is that a file has one or the other of these links not both. If the file is a binary type for example an image you will be given a webContentLink which can be used to download the file, If its say a google sheet then you will be given a webViewLink which can be used to view the file in Google Drive web application.
Which link you get depends entirely upon the type of file it is. No matter which link you get you will still need to have permission to access this file. So whoever clicks the link must have at the very least read permission to the file.
On the Google drive web application we can create links which can be shared with anyone and allow anyone to "access" there is no way to create these links VIA the api.
What you wish to do is out of scope for the Google drive api, probably due to security reasons. Also the simple fact that google drive api is not a file service api it a file storage system. THere is a difference.

Create shared Google Drive document owned by web service

I'm new to the Google APIs, and would like to write a small service class for my web application that:
creates blank Google document without user assistance
assigns a generated title
returns a URL that can be provided to multiple people to edit this document
This document mst be editable via a sharing link. Ideally it is owned/managed as part of the web service's Drive storage.
Code is welcome if it's easier than explaining, but I'm really asking for help understanding Google's service offering.
Can I fully authenticate using only credentials specific to my app? (e.g. call the Drive API without prompting an interloper/observer/user to
authenticate.)
Once authenticated, can I create documents local to my
API?
Whose quota are the created documents consuming, the person that created the API key?
Can I share
these created documents with others?
Will I be able to manage a list of
these created file URLs from a standard Google web UI?
Just to clarify what it is that you are asking. You want to be able to embed a google doc on your website A couple things that can happen here.
First, you will need to create a google doc, lets say a spreadsheet. Within that spreadsheet you will:
click File > Publish to the Web.
From here a new window will be brought up. Click Embed and Published content and settings and click the publish button. Ensure the Automatically republish when changes are made checkbox. (this will allow for your website to be automatically updated anytime that doc is changed.
Take the embedded link that is generated and plop it in your webpage and it will be live.
Now you can share the page via Google Docs and anyone that has that link can make changes to that spreadsheet. As soon as a change is made, it will update on your website with the next refresh.
Hope this is all clear, let me know if there is anything unclear.
Cheers

Drive JS API Realtime sample example is not behaving as expected

Well i have just tried the sample example of real time js Google drive api. As they said in their tutorial,the application's text areas will be synced even if they are opened in different browser windows. But here the application is not doing that. It only reflects changes to the text areas of same browser window.
Here is the link: Google Drive Realtime JS API
Is there anything that i miss? I am running my application in Koding.com's vm.
Starting the quickstart app with the base url will cause it to create a new document.
To view the same document twice, you can copy-paste the full url after its loaded, which should include a document id, or open an existing document from drive with your app.

ChromeOS App: Simple example app which opens/saves to Google Drive as well as Download and External Drive

I've succeeded in using the filesystem API in a Chrome App on my Chromebook. But none of the examples I've found allow you to open files from Google Drive. Any number of apps on the Chromebook (supplied or added) open the exact same dialog but with Google Drive showing on the left along with Download and External Drive.
Is there a simple example App which shows how this is done?
Or am I simply missing some concept which will make even the Diff or TextEdit examples work this way if done (like pushing the App to the store, perhaps -- right now I'm just loading and packing my own off local storage)?
From reading your comment it seems that you will want to use google drive sdk in order to integrate the 'open file' dialog into your web app.
and even more to the point - the file 'picker' - In order to integrate the file picker you will need to use google JS client lib. Then you will be able to open the file dialog with a code like this:
// Use the Google Loader script to load the google.picker script.
google.setOnLoadCallback(createPicker);
google.load('picker', '1');
// Create and render a Picker object for searching images.
function createPicker() {
var picker = new google.picker.PickerBuilder().
addView(google.picker.ViewId.IMAGE_SEARCH).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
Good luck.
The answer to this is to use the <input type="file" name="somename" size="chars"> code in the browser. That is what is producing this. It creates a standard way to read in the file from disk or Google drive. It's what I've seen in multiple apps. All the API stuff is a red herring, if what one wants is to get access to this simple dialog.
However, it doesn't allow me to WRITE, just to read, since one would expect it to be returning only the content of the file, not a file handle of any sort, or even the full name. I'll play with it and figure out whether there's any hook I can find to tell me to write it to Google drive (using the links Ido provided above). If anyone has suggestions on where to snag the full path (or an interesting Google Drive path) somewhere using this, I'll love to hear them.

Is is possible to get a permanent URL to a file uploaded to Google drive?

I can't find the answer to this in the API docs or elsewhere. I see in the docs says you can get a downloadURL of a file, but it refers to it as a 'short lived URL'. What does that mean?
I need to upload images and get a permanent URL of that image that is the direct URL than can be embedded into emails or web docs etc. Is that possible?
Thanks
Yes, you can get a permalink to any file hosted on Google Drive in a public folder. Just note the folderID:
and paste it to the following URL:
http://googledrive.com/host/<folderID>/<filename>
or you can create a short custom alias using G Drives: http://gdriv.es/<alias>/<filename>
https://developers.google.com/drive/v2/reference/files#webContentLink
downloadUrl is short lived, but webContentLink is a permanent link. It's odd that one is a URL and the other is a "link", but I guess it probably has to do with the additional query params in the strong. Maybe that makes it not just a URL? :)
That property is only available for files that are publically readable, so you may have to use the SDK/API to set the permissions first.
In case someone encounter the same problem and don't want to do with deprecated Google Drive solution above and requires frequently changed files with exact same url, you can use Dropbox. Steps:
Download the program and share a folder (tutorial)
Copy a file into that folder; wait for sync with Dropbox
Go to your dropbox.com account
Share your file by button, get something like:
https://www.dropbox.com/s/d28d8scvr3rfy48/foo.exe?dl=0
Rename it to:
https://dl.dropboxusercontent.com/s/d28d8scvr3rfy48/foo.exe?dl=0
Now you have a public, unchanged url for all your foo.exe changes.
Enjoy, don't waste time with sites offering you file hosting and they change the URL for same files.
If you share a file publicly in GDrive, you can use the following link to make the file download directly:
https://drive.google.com/uc?export=download&id=FILEID
The problem happens when you want to change the file (for version controlled download, in instance) and keep the same downloading link.
You can use a URL Shortener like bitly.com and use a Branded Bitlink to change the destination URL keeping the input URL.
I hope it works, good luck!
It seems if you have file ID you can access it with such url:
https://drive.google.com/open?id=file-id-here
If file is public, you'll see it immediately but if not, you're be asked to login
I don't know how often this changes but I was looking for a dynamic solution where I wouldn't need to manually upload to another site and the provided solutions weren't working.
Here's the url that worked for me:
https://lh3.google.com/u/0/d/<file_id>
Where file_id is the getId() using the google apps script drive API. Secondly the file must be shared publicly like posted previously
Secondly I imagine the lh3 are different cdn's though I cannot confirm since lh1/2 don't work and everything higher than 3 redirects to lh3
I don't know if such API for google drive exists, but I think you should also have a look at dropbox,
which will meet all the demands that you mention in your question.
Also there are some very cool applications developed just for dropbox, like pancake.io which lets you share links of text, html files, in an html page format.
that + permanent link is always there.
You can use gdriveurl.com, it got updated and now allows users to log in with their google drive account and share the list of files instantly, getting for each file "View" & "Download" short permalink.
There's also the old solution (login to Google Drive, set everything to "Public on web", copy share link, convert it into the gdriveurl.com textarea in the homepage), but it's just a waste of time, you should try "MyDrive" api.
Not sure if the link generated here is guaranteed to be permanent, but Google Drive Direct Link Generator does the job of generating a direct download link.
Just make sure your file's sharing setting is set to Anyone with the link