web-dev-qa-db-fra.com

Comment ajouter / créer / insérer des fichiers dans Google Drive via l'API?

Besoin d'aide concernant l'insertion d'un fichier dans Google Drive via l'API. La documentation de l'API à cet effet n'explique pas clairement comment envoyer le corps réel du fichier via la requête de publication http.

32
Niranja

La documentation sur les opérations d'insertion contient déjà des exemples dans un tas de langages de programmation, voici comment le faire en utilisant le protocole HTTP de l'API Google Drive.

Tout d'abord, POST les nouvelles métadonnées de fichier au point de terminaison Drive. Elles doivent être sous la forme d'un objet JSON de ressource de fichier :

POST /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer <OAuth 2.0 access token here>
...

{
  "title": "file_name.extension",
  "mimeType": "mime/type",
  "description": "Stuff about the file"
}

Le corps de la réponse sera une représentation JSON de la ressource File nouvellement créée. Cela ressemblera à:

{
  "kind": "drive#file",
  "id": string,
  "etag": etag,
  "selfLink": string,
  "title": "file_name",
  "mimeType": "mime/type",
  "description": "Stuff about the file"
  ...
  "downloadUrl": string,
  ...
}

Il s'agit d'une confirmation que l'entrée de fichier a été créée. Vous devez maintenant télécharger le contenu. Pour ce faire, vous devez prendre l'ID du fichier donné par l'attribut JSON id dans la réponse ci-dessus et METTRE le contenu du fichier réel au point de terminaison de téléchargement avec un OAuth 2.0 demande autorisée. Elle devrait ressembler à:

PUT /upload/drive/v2/files/{id}?uploadType=media HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer <OAuth 2.0 access token here>
Content-Type: mime/type

<file content here>

Vous avez terminé :)

Il existe également un moyen de le faire en 1 seule requête POST en utilisant une requête en plusieurs parties où vous publiez les métadonnées du fichier en même temps que le contenu. Voici un exemple:

POST /upload/drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer <OAuth 2.0 access token here>
Content-Type: multipart/form-data; boundary=287032381131322
...

--287032381131322
Content-Type: application/json

{
  "title": "file_name.extension",
  "mimeType": "mime/type",
  "description": "Stuff about the file"
}
--287032381131322
Content-Type: mime/type

<file content here>
--287032381131322--

La réponse contiendra les métadonnées du fichier nouvellement créé. Vous pouvez également utiliser l'en-tête Content-Transfer-Encoding: base64 dans la sous-partie de la demande pour pouvoir transmettre les données du fichier comme Base 64 encodée.

Enfin, il existe également un protocole de téléchargement pouvant être repris qui est pratique pour télécharger des fichiers volumineux, offrir une fonction de pause/reprise et/ou télécharger des fichiers avec une connexion Internet instable.

PS: la plupart de cela est maintenant décrit dans documentation de téléchargement de fichiers de Drive .

65
Nicolas Garnier

Merci pour l'explication! Cela m'a pris des heures à tourner en rond avec la documentation merde du SDK Google (désolé d'avoir dû sortir mon diatribe).

Voici une fonction que j'ai créée qui mettra à jour un fichier texte (comme vous pouvez le voir, je mets à jour le HTML):

  function Gd_updateFile(fileId, folderId, text, callback) {

    const boundary = '-------314159265358979323846';
    const delimiter = "\r\n--" + boundary + "\r\n";
    const close_delim = "\r\n--" + boundary + "--";

    var contentType = "text/html";
    var metadata = {'mimeType': contentType,};

    var multipartRequestBody =
        delimiter +  'Content-Type: application/json\r\n\r\n' +
        JSON.stringify(metadata) +
        delimiter + 'Content-Type: ' + contentType + '\r\n' + '\r\n' +
        text +
        close_delim;

    if (!callback) { callback = function(file) { console.log("Update Complete ",file) }; }

    gapi.client.request({
        'path': '/upload/drive/v2/files/'+folderId+"?fileId="+fileId+"&uploadType=multipart",
        'method': 'PUT',
        'params': {'fileId': fileId, 'uploadType': 'multipart'},
        'headers': {'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'},
        'body': multipartRequestBody,
        callback:callback,
    });
  }

C'est un mashup de l'exemple de google (qui utilise un fichier binaire de téléchargement) et de l'explication de Nice de @Nivco ci-dessus.

17
user1158023

4 ans plus tard, c'est encore difficile à comprendre. J'ai pris la réponse de @ user1158023 pour prendre en charge le téléchargement d'images. J'utilise l'API v3 et superagent.js pour m'aider (puisque gapi.client.request envoie la demande à content.googleapis.com !?). J'espère que quelqu'un pourra trouver cela utile.

function Gd_uploadFile(name, contentType, data, callback) {
    const boundary = '-------314159265358979323846';
    const delimiter = "\r\n--" + boundary + "\r\n";
    const close_delim = "\r\n--" + boundary + "--";

    contentType = contentType || "text/html";
    var metadata = {
        name: name,
        'mimeType': contentType
    };

    var multipartRequestBody =
        delimiter +  'Content-Type: application/json\r\n\r\n' +
        JSON.stringify(metadata) +
        delimiter +
        'Content-Type: ' + contentType + '\r\n';

    //Transfer images as base64 string.
    if (contentType.indexOf('image/') === 0) {
        var pos = data.indexOf('base64,');
        multipartRequestBody += 'Content-Transfer-Encoding: base64\r\n' + '\r\n' +
            data.slice(pos < 0 ? 0 : (pos + 'base64,'.length));
    } else {
        multipartRequestBody +=  + '\r\n' + data;
    }
    multipartRequestBody += close_delim;

    if (!callback) { callback = function(file) { console.log("Update Complete ", file) }; }

    superagent.post('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart').
        set('Content-Type', 'multipart/form-data;  boundary="' + boundary + '"').
        set('Authorization', 'Bearer ' + gapi.auth.getToken().access_token).
        send(multipartRequestBody).
        end(function () {
            console.log(arguments);
        });
}

//On upload
$('#file')[0].onchange = function () {
    var file = $('#file')[0].files[0];
    if (file && file.type === 'image/jpeg') {
        var reader = new FileReader();
        reader.onloadend = function () {
            var data = reader.result;
            Gd_uploadFile('img.jpg', 'image/jpeg', data, function () {
                console.log(arguments);
            });
        }
        reader.readAsDataURL(file);
    }
};

index.html

...
<form>
    <span>Upload: </span><input id="file" type="file" name="myFile">
</form>
...
7
Munawwar

Je souhaite qu'il y ait de meilleurs exemples pour Drive Gapis v3 ... Il m'a fallu un certain temps pour comprendre comment télécharger du nouveau contenu dans un fichier existant créé avec

gapi.client.drive.files.create({ "name" : "savefile.txt" }).execute(function(file) { console.log("Created file " + file.name + " id: " + file.id); });

mais finalement j'ai essayé la combinaison "chanceuse" d'ajouter le fileId au chemin et de changer la méthode en PATCH

function uploadFile(id, text)                                                                                                                                                          
{
  var auth_token = gapi.auth.getToken().access_token;

  const boundary = '-------314159265358979323846';
  const delimiter = "\r\n--" + boundary + "\r\n";
  const close_delim = "\r\n--" + boundary + "--";

  var metadata = { 
      description : 'savefile for my game',
      'mimeType': 'application/json'
  };  

  var multipartRequestBody =
    delimiter +  'Content-Type: application/json\r\n\r\n' +
    JSON.stringify(metadata) +
    delimiter + 'Content-Type: application/json\r\n\r\n' +
    text +
    close_delim;

  gapi.client.request
    ( { 
     'path': '/upload/drive/v3/files/'+id,
     'method': 'PATCH',
     'params': {'fileId': id, 'uploadType': 'multipart'},
     'headers': { 'Content-Type': 'multipart/form-data; boundary="' + boundary + '"', 'Authorization': 'Bearer ' + auth_token, },
     'body': multipartRequestBody 
     }).execute(function(file) { console.log("Wrote to file " + file.name + " id: " + file.id); }); 
}

Mais je suppose que maintenant toute la documentation sur https://developers.google.com/drive/v3/reference/files/update commence à avoir un sens pour moi :-)

3
renato

L'équipe API Google Drivesortie v fin 2015, et dans cette version, insert() a changé de nom en create() donc afin de mieux refléter le fonctionnement du fichier. La documentation a également été améliorée: il y a maintenant un guide spécial consacré aux téléchargements (simple, en plusieurs parties et pouvant être repris) qui est fourni avec un exemple de code en Java, Python, PHP, C # /. NET, Ruby, JavaScript /Node.js et iOS/Obj-C pour télécharger un fichier normal et un autre pour importer un fichier CSV en tant que feuille Google.

Pour le montrer simplement, voici un alternatif Python (à l'exemple dans les documents) pour fichiers courts ("téléchargement simple") où vous n'avez pas besoin du apiclient.http.MediaFileUpload classe. Cet extrait suppose que votre code d'authentification fonctionne là où votre point de terminaison de service est DRIVE avec une portée d'authentification minimale de https://www.googleapis.com/auth/drive.file.

# filenames & MIMEtypes
DST_FILENAME = 'inventory'
SRC_FILENAME = DST_FILENAME + '.csv'
SHT_MIMETYPE = 'application/vnd.google-apps.spreadsheet'
CSV_MIMETYPE = 'text/csv'

# Import CSV file to Google Drive as a Google Sheets file
METADATA = {'name': DST_FILENAME, 'mimeType': SHT_MIMETYPE}
rsp = DRIVE.files().create(body=METADATA, media_body=SRC_FILENAME).execute()
if rsp:
    print('Imported %r to %r (as %s)' % (SRC_FILENAME, DST_FILENAME, rsp['mimeType']))

Notez que si vous écrivez une application Android Android, il y a une API Google Drive pour Android avec son propre ensemble de documents. Enfin, si vous utilisez JavaScript sur Google Apps Script, les objet natif Drive Service et Drive Advanced Service utilisent toujours la version 2 de l'API.

2
wescpy