23

I'm using Google Drive API (PHP) to upload some photos to my Drive. When a file is uploaded, a Google_DriveFile object is returned in the response to confirm the successful transfer. It includes a field called thumbnailLink, accessible through the getThumbnailLink getter. Its content may look like this:

https://lh4.googleusercontent.com/dqVdU195R4_0ZtWxsJlhW1Fr2K30xa2hH3V1KV4UrTBl9QkhOSR0ZqN9HoB-TjEQv8SIJw=s220

Until today, I was sure that the link doesn't change by itself over time. However, when I tried to display a thumbnail of a photo I have on my Drive, using a cached address I keep in my local database, I got a 403 error - you can see it under the mentioned link. I asked the API for the current link to the thumbnail and it's now completely different.

It happened to me only once but for multiple files, i.e. all the files I had on my Drive suddenly got new thumbnail links.

Is there a way to quickly retrieve a thumbnail of a document (preferably, a photo) by some constant value or to be sure that it won't change? The perfect solution would be to access the thumbnail under a link that includes the document's id instead of some hash that may change.

PiotrK
  • 1,502
  • 1
  • 15
  • 33
  • 1
    Thumbnails are invalidated each time the content of the file changes. You are going to have to grab the new one from time to time even if you send your own thumbnail Drive will over ride it with its own thumbnail if it can create one. https://developers.google.com/drive/web/file – Linda Lawton - DaImTo Sep 12 '14 at 06:44
  • Thanks for the feedback. Well, that's really weird. It makes caching the links to the thumbnails pointless. So every time I want to display the thumbnail, I have to get its 'fresh' address? For a lot of files to display at once, it may take a lot of time. Is there a way to at least do it somehow in a batch, i.e. get thumbnails for all files in a given folder? – PiotrK Sep 12 '14 at 13:54
  • The web client surely can get a bunch of thumbnails at once, but I don't want to reverse-engineer it yet. Maybe is there a documented function for this? – PiotrK Sep 12 '14 at 14:10

3 Answers3

73

Try this:

https://drive.google.com/thumbnail?authuser=0&sz=w320&id=[fileid]

Where:

  • sz is a size, where you may use as w (width), as h (height)
  • fileid is a file id. You may find it in "share" menu by right click in Google Drive UI.
Kos
  • 4,890
  • 9
  • 38
  • 42
user5132772
  • 731
  • 5
  • 2
  • Thanks a lot. I've the problem that every thumbnail link is null. I don't know why. But your solution works fine also in my case. – realtebo Jan 25 '16 at 13:00
  • 1
    @realtebo Did you understand why every thumbnail link is null? I am having the same problem. – emem Mar 14 '16 at 09:17
  • 2
    @realtebo I just figured out what was my problem - the authentication scope was not updated with the correct permission to get the thumbnail. You cannot use only permissions for file metadata if you wish to get the thumbnail. – emem Mar 14 '16 at 13:20
  • @EranMarom: usefull comment, thanks. What is the right permission to add? – realtebo Mar 14 '16 at 14:09
  • @realtebo I think "drive" (full permissions) and "drive.readonly". See: https://developers.google.com/drive/v3/web/about-auth#OAuth2Authorizing) – emem Mar 14 '16 at 14:41
  • 1
    If you are logged in with multiple users, the authuser=<> seems to be an index into which user – user1170883 May 07 '18 at 22:56
  • This only works with auth user in cookies I think. I get a 404 without that – Denny Weinberg Apr 26 '19 at 19:51
  • This Solution is from 2015 but Still working in 2020. Thank you, brother. After 5 hard working days on getting thumbnails from google drive URL, I found this and it worked – Ramesh Nov 17 '20 at 21:03
  • someeone know ifthere is some param to change aspect ratio? thanks – Alberto Acuña Dec 02 '22 at 17:06
4

I have gone through the API Documentation as they have provided:

Important: Thumbnails are invalidated each time the content of the file changes. When supplying thumbnails, it is important to upload new thumbnails each time the content is modified.

According to the information it means that a new Thumbnail is only generated only when the contents of the file are modifided. But in your case it is really weired thing and the contents are not changed but the thumbnail are Changed. As from documentation there is no batch process thing avaiable but another way around is available i.e. Web Hook

According to the Documentation there is web hook available i.e. Files:Watch process through which one can track the changes are made to file. Thus, it means every time contents are changed then hook would run and you can change the cache of the image thumbnail.

HTTP request can be sent to request the watching the files changing

POST https://www.googleapis.com/drive/v2/files/fileId/watch

Here fileID means the ID provided after loading the file.

In the request body, supply data with the following structure:

id     ==>  string  (A UUID or similar unique string that identifies 
            this channel.)

token# ==>  string  (An arbitrary string delivered to the target address with 
                    each notification delivered over this channel).

expiration# => long (Date and time of notification channel expiration, 
                     expressed as a Unix timestamp, in milliseconds.)

 type  ==> string  (The type of delivery mechanism used for this channel. 
                   The only option is web_hook.)

 address => string  (The address where notifications are delivered 
                     for this channel.)

 # Optional.

If the contents get changed then new Thumbnail is generated and hook will notify you address and through your address you can fetch new information.

Vineet1982
  • 7,730
  • 4
  • 32
  • 67
  • thanks for the idea. I'll try to implement it tomorrow and we'll see if it reports any changes also in this weird case. – PiotrK Sep 15 '14 at 20:32
  • I did my best to configure the watching properly, but I'm not getting any notifications. I do get responses from the API, immediately after setting up the watch, confirming that my request is OK. The webhook address also seems to be fine - I'm using a Firefox plugin called Poster to send 'artificial' calls and my site catches them and logs them without problems. Do you have any idea what mistake I'm making? – PiotrK Sep 16 '14 at 20:00
  • After applying webhook try to change the contents see the hook works or not as in documentation clearly mentioned only in case of change of content – Vineet1982 Sep 17 '14 at 04:22
  • Unfortunately, still no notification. I tested it on a TXT file and made sure I edited the actual file, not created a copy of it. – PiotrK Sep 17 '14 at 15:56
  • 1
    I think I'll just implement thumbnails myself. It won't be as flexible as Google's, but better have something than nothing. Thanks for your help. – PiotrK Sep 17 '14 at 17:39
  • According to the documentation, this won't work because the thumbnail is short-lived. "A short-lived link to the file's thumbnail, if available. Typically lasts on the order of hours. Only populated when the requesting app can access the file's content.". The thumbnail is only supposed to last a few hours, so a permanent reference to this file won't work and you won't get a webhook when it changes. – N_A Apr 29 '17 at 03:45
1

Here is another solution. Let's say we store only GDrive ID of the images or PDFs (google generate thumbs for many file types).

we can send request to gDrive to get valid thumbnail since looks like thumbs will expire even if there is no changes to the file.

In this case each thumbnail inside Angular component. If you use something else you can create array of links and iterate through it to create proper thumb links.

Here is the code:

const thumb = () => {
            if (this.item.DriveId) {
            this.getThumb(this.item.DriveId, this.authToken)
                .then(response => {
                    console.log(`response from service ${response}`);
                    // Set thumbnail width size to 300px or any other width if needed
                    this.item.externalThumbnailId = response.slice(0, -3) + 300;
                })
                //here we can handle cases when API limit exceeded 10 req in a sec
                .catch(e => {
                    if(e.data.error.message == 'User Rate Limit Exceeded'){
                        console.log('Failed to load thumb. trying one more time');
                        setTimeout(thumb, 1000);
                    } else {
                        console.log(e);                        
                    }                       
                });
            }
            };

//call this function on component load. 
thumb();

Another solution will be to write some backend script that updates thumbs in DB records.