Google Drive APIJavascriptを介してURLからGoogleドライブに画像をアップロードします

Aug 18 2020

私はJavascriptを初めて使用しますが、私の質問があなたに足りないと思われる場合は申し訳ありません。ウェブサイトからGoogleドライブに画像をアップロードしたい。認証とフォルダの作成部分を正常に実装しましたが、アップロードプロセスについて混乱しています。
これがGoogleドライブ内にフォルダを作成するための私のコードだとしましょう:

function createFolder(folderName) {
  var parentId = 'xxxxxxx';//some parentId of a folder under which to create the new folder
  var fileMetadata = {
    'name' : folderName,
    'mimeType' : 'application/vnd.google-apps.folder',
    'parents': [parentId]
  };
  gapi.client.drive.files.create({
    resource: fileMetadata,
  }).then(function(response) {
    switch(response.status){
      case 200:
      var file = response.result;
      console.log('Created Folder Id: ', file.id);
      uploadImage(file.id);
      break;
      default:
      console.log('Error creating the folder, '+response);
      break;
    }
  });
}

ここで、このURLから画像をアップロードしたいと思いhttps://xxxxxx.comます:上部の応答から新しく作成されたフォルダーに(file.id

これはGoogleAPIドキュメントで取得したものですが、URLをどこに配置/添付する必要がありますか?

function uploadImage(folderId) {
  var fileMetadata = {
    'name': 'photo.jpg',
    parents: [folderId]
  };
  var media = {
    mimeType: 'image/jpeg',
    body: fs.createReadStream('files/photo.jpg')
  };
  drive.files.create({
    resource: fileMetadata,
    media: media,
    fields: 'id'
  }, function (err, file) {
    if (err) {
      // Handle error
      console.error(err);
    } else {
      console.log('File Id: ', file.id);
    }
  });
}   

よろしくお願いします。

回答

1 Tanaike Aug 19 2020 at 08:26

私はあなたの目標を次のように信じています。

  • URLからファイルをダウンロードし、ダウンロードしたファイルをJavascriptを使用してGoogleドライブにアップロードします。
  • あなたの場合、あなたgapi.clientはファイルをGoogleドライブにアップロードするために使用することができます。

変更点:

  • 残念ながら現段階でgapi.client.drive.files.createは、内容も含めてリクエストを送信できないようです。Refしたがって、この場合、fetch回避策として使用することを提案したいと思います。ときにfetch使用され、ファイルの内容とメタデータがで要求することができますmultipart/form-data
  • この回避策では、アクセストークンはから使用されgapi.clientます。したがって、このスクリプトはgapi.client、ファイルのアップロードにを使用できることを前提としています。これに注意してください。

変更されたスクリプト:

const url = "###";  // Please set the URL.
const fileName = "sample filename";
const folderId = "###";  // Please set the folder ID.

fetch(url).then(res => res.blob()).then(blob => {
  const form = new FormData();
  form.append('metadata', new Blob([JSON.stringify({name: fileName, parents: [folderId]})], {type: 'application/json'}));
  form.append('file', blob);
  fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
    method: 'POST',
    headers: new Headers({'Authorization': 'Bearer ' + gapi.auth.getToken().access_token}),
    body: form
  }).then(res => res.json()).then(val => console.log(val));
});
  • このスクリプトを実行すると、コンソールに次の結果が表示されます。(URLがJpeg画像ファイルの直接リンクの場合。)

      {
        "kind": "drive#file",
        "id": "###",
        "name": "sample filename",
        "mimeType": "image/jpeg"
      }
    

注意:

  • この場合、uploadType=multipartが使用されます。したがって、最大ファイルサイズは5MBです。これに注意してください。5 MBを超える容量を使用する場合は、再開可能なアップロードを確認してください。参照

参照:

  • フェッチの使用
  • ファイルデータをアップロードする

追加:

CORSに関連するエラーを回避するために、別の方法として、Webアプリをラッパーとして使用することを提案したいと思います。この場合、クライアント側はJavascriptです。このJavascriptはGoogleの外部で使用できます。

使用法:

次のフローを実行してください。

1. Google AppsScriptの新しいプロジェクトを作成します。

WebAppsのサンプルスクリプトはGoogleAppsScriptです。そこで、Google AppsScriptのプロジェクトを作成してください。

直接作成したい場合は、にアクセスしてください。 https://script.new/。この場合、Googleにログインしていないと、ログイン画面が開きます。だからGoogleにログインしてください。これにより、Google AppsScriptのスクリプトエディタが開きます。

2.スクリプトを準備します。

次のスクリプト(Google Apps Script)をコピーしてスクリプトエディタに貼り付けてください。このスクリプトはWebアプリ用です。

サーバー側:Google Apps Script

このスクリプトはWebアプリに使用されます。この場合、Webアプリがラッパーとして使用されます。

function doGet(e) {
  const imageUrl = e.parameter.imageUrl;
  const res = UrlFetchApp.fetch(imageUrl);
  if (res.getResponseCode() != 200) throw new Error("Image couldn't be retrieved.");
  const blob = res.getBlob();
  const file = DriveApp.getFolderById(e.parameter.folderId).createFile(blob.setName(e.parameter.filename));
  const obj = {id: file.getId(), name: file.getName(), mimeType: file.getMimeType()};
  return ContentService.createTextOutput(JSON.stringify(obj)).setMimeType(ContentService.MimeType.JSON);
}

3.Webアプリをデプロイします。

  1. スクリプトエディタで、[公開]-> [ウェブアプリとしてデプロイ]でダイアログボックスを開きます。
  2. アプリを次のように実行する「私」を選択します。
    • これにより、スクリプトが所有者として実行されます。
  3. 選択し、「誰でも、でも、匿名の」ため「誰アプリへのアクセス権を持っています:」
  4. 新しい「プロジェクトバージョン」として「デプロイ」ボタンをクリックします。
  5. 「認証が必要」のダイアログボックスを自動的に開きます。
    1. [権限の確認]をクリックします。
    2. 自分のアカウントを選択してください。
    3. 「このアプリは確認されていません」で「詳細」をクリックします。
    4. 「###プロジェクト名###(安全でない)に移動」をクリックします
    5. 「許可」ボタンをクリックします。
  6. 「OK」をクリックします。
  7. WebアプリのURLをコピーします。のようなものhttps://script.google.com/macros/s/###/execです。
    • Google Apps Scriptを変更した場合は、新しいバージョンとして再デプロイしてください。これにより、変更されたスクリプトがWebアプリに反映されます。これに注意してください。

4.クライアント側からサーバー側にファイルをアップロードします。

クライアント側:HTMLとJavascript

WebアプリのURLを次のスクリプトに設定してください。また、ファイル名とフォルダIDを設定してください。

const imageUrl = "###"; // Please set the URL of image.

const url = "https://script.google.com/macros/s/###/exec"; // Please set the URL of Web Apps.
const qs = new URLSearchParams({
  imageUrl: imageUrl,
  filename: "sample filename",
  folderId: "###", // Please set folder ID.
});
fetch(`${url}?${qs}`).then((res) => res.json()).then(console.log).catch(console.log);
結果:

上記のスクリプトを実行すると、次の値が返されます。戻り値はコンソールで確認できます。

{
  "id": "###",
  "name": "###",
  "mimeType": "###"
}

注意:

  • Web Appsのスクリプトを変更した場合は、WebAppsを新しいバージョンとして再デプロイしてください。これにより、最新のスクリプトがWebアプリに反映されます。これに注意してください。

参照:

  • Webアプリ
  • Google AppsScriptでWebアプリを活用する
1 JeffRush Aug 18 2020 at 21:23

このスニペットを使用して写真ファイルをアップロードしてみてください。

// download file from website 
const http  = require('https')
const fs    = require('fs')

let file    = fs.createWriteStream('Photo001.jpg')
let request = http.get(
    'https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_2x.png', 
    (response) => {
        response.pipe(file)
    })

// upload file to Google Drive
let fileMetadata = {
  'name'    : 'Photo001',
  'mimeType': 'image/jpeg'
}

let media = {
  mimeType  : 'image/jpeg',
  body      : fs.createReadStream('Photo001.jpeg')
}

function uploadFile(auth){

  const drive = google.drive({version: 'v3', auth})

  drive.files.create({
    resource: fileMetadata,
    media   : media,
    fields  : 'id'
  }, (err, res) => {
    if (err) return console.log('The API returned an error: ' + err)
  })

}

ドキュメンテーション

  • ファイル:作成