0

I know how to create a share link in google drive for each image manually and then use it in an img src element for display but I want to know if there is a way to automate this with laravel.

I've been reading that one approach seems to be to download the image from drive and convert it into base64, send it to the frontend and display it but I want to know if there is a more convenient way. Can the google api for example create a display link on its own, which would negate the need of converting the image to base64?

I'm using masbug/flysystem-google-drive-ext adapter for Laravel 9. My GoogleDriveServiceProvider.php looks like this:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Storage;
use Google\Client;
use Google\Service\Drive;
use Masbug\Flysystem\GoogleDriveAdapter;
use League\Flysystem\Filesystem;
use Illuminate\Filesystem\FilesystemAdapter;


class GoogleDriveServiceProvider extends ServiceProvider
{

    public function register()
    {
        //
    }

    public function boot()
    {
        try {
            Storage::extend('google', function($app, $config) {
                $options = [];

                if (!empty($config['teamDriveId'] ?? null)) {
                    $options['teamDriveId'] = $config['teamDriveId'];
                }

                $client = new Client();
                $client->setClientId($config['clientId']);
                $client->setClientSecret($config['clientSecret']);
                $client->refreshToken($config['refreshToken']);

                $service = new Drive($client);
                $adapter = new GoogleDriveAdapter($service, $config['folder'] ?? '/', $options);
                $driver = new Filesystem($adapter);

                return new FilesystemAdapter($driver, $adapter);
            });
        } catch(\Exception $e) {
            return $e->getMessage();
        }
    }
}

which gives me the ability to use google drive with the Storage facade like so:

$imageId = Storage::disk('google')->put('', $request->image);

With a local filesystem I would do:

$url = Storage::url($imageId);

but it only concats the imageId from google drive with a /storage string:

/storage/bmca03toolPziaMxlGNZluP2Svgg0Jvwd7hJAycA.png

which can't be used in an img src element. Is there a way to generate the url from the google drive api?

Artur Müller Romanov
  • 4,417
  • 10
  • 73
  • 132
  • I think it is same as https://stackoverflow.com/questions/67813895/retrieving-a-raw-file-url-from-the-google-drive-api. It says its not possible. – Manibha Jain Aug 05 '22 at 06:52
  • Try with this [answer](https://stackoverflow.com/a/52067077/3584881) maybe helpful. – Bhaumik Pandhi Aug 05 '22 at 06:53
  • You can certainly obtain the raw bytes using the Drive API as explained in this documentation article https://developers.google.com/drive/api/v3/reference/files/get, you will only need to set the **alt** parameter to *"media"* as mentioned in the documentation. But converting and uploading/downloading the base64 image is not efficient. – Juan Serrano Aug 05 '22 at 07:10

2 Answers2

0

I think I had the same question quite some time ago and my approach was to use a different link with the file ID concatenated at the end, like so:

https://drive.google.com/uc?id=DRIVE_FILE_ID

You won't need to download anything because you could programmatically create the img elements and add the Drive fileID in the URL. It looks like the only thing you are required to do is have the file publicly accessible.

I obtained that link format from this page https://www.labnol.org/google-drive-image-hosting-220515 in the "Alternate Approach" section, where they explain a way to obtain an embed link to add as src for HTML.

Juan Serrano
  • 359
  • 3
  • 9
  • It works if I grab the link in drive manually. Any idea how to extract it from the drive api? – Artur Müller Romanov Aug 05 '22 at 07:16
  • You can list all the files in Google Drive using the _Files.list_ method (https://developers.google.com/drive/api/v3/reference/files/list) there is a parameter for you to filter files, you could specify to list only files inside one folder or search based name. Searching files are explained here: https://developers.google.com/drive/api/guides/search-files. It returns a list of objects with every file, including the file ID. – Juan Serrano Aug 05 '22 at 15:46
0

I found out how it's done:

$url = Storage::disk('google')->url($imageId);

will produce an url that you can directly insert into an img src element:

https://drive.google.com/uc?id=1MsU3OBHDykSNKpX_veHvIHptnM3yEECz&export=media
Artur Müller Romanov
  • 4,417
  • 10
  • 73
  • 132