スポンサーリンク

Googleフォームから送信された画像をDropboxにアップするためのコード

スポンサーリンク

DropboxでAPP_KEYやAPP_SECRET_KEY、リフレッシュトークンの取得して、
プロパティに設定する感じでやってます

以下のコードをAIに読ませて、希望の動作を要望したり、あるいはトークンとかの取得方法について聞くのがいいと思います

// Google Apps Scriptファイル: Code.gs

// スクリプトプロパティから設定を取得する関数
function getConfig() {
  const scriptProperties = PropertiesService.getScriptProperties();
  return {
    DROPBOX_APP_KEY: scriptProperties.getProperty('DROPBOX_APP_KEY'),
    DROPBOX_APP_SECRET: scriptProperties.getProperty('DROPBOX_APP_SECRET'),
    DROPBOX_REFRESH_TOKEN: scriptProperties.getProperty('DROPBOX_REFRESH_TOKEN'),
    MAX_RETRIES: parseInt(scriptProperties.getProperty('MAX_RETRIES') || '3'),
    INITIAL_RETRY_DELAY: parseInt(scriptProperties.getProperty('INITIAL_RETRY_DELAY') || '1000')
  };
}

// スクリプトプロパティにアクセストークンを保存
function getAccessToken() {
  const scriptProperties = PropertiesService.getScriptProperties();
  let accessToken = scriptProperties.getProperty('DROPBOX_ACCESS_TOKEN');
  
  if (!accessToken) {
    accessToken = refreshAccessToken();
  }
  
  return accessToken;
}

// アクセストークンを更新
function refreshAccessToken() {
  const config = getConfig();
  const url = 'https://api.dropboxapi.com/oauth2/token';
  const payload = {
    grant_type: 'refresh_token',
    refresh_token: config.DROPBOX_REFRESH_TOKEN,
    client_id: config.DROPBOX_APP_KEY,
    client_secret: config.DROPBOX_APP_SECRET
  };
  
  const options = {
    method: 'POST',
    payload: payload
  };
  
  const response = UrlFetchApp.fetch(url, options);
  const result = JSON.parse(response.getContentText());
  
  const scriptProperties = PropertiesService.getScriptProperties();
  scriptProperties.setProperty('DROPBOX_ACCESS_TOKEN', result.access_token);
  
  return result.access_token;
}

// フォーム送信時に実行される関数
function onFormSubmit(e) {
  const form = FormApp.getActiveForm();
  const formResponses = form.getResponses();
  const latestResponse = formResponses[formResponses.length - 1];
  const itemResponses = latestResponse.getItemResponses();
  
  // 画像ファイルを取得
  const fileItem = itemResponses.find(response => response.getItem().getType() === FormApp.ItemType.FILE_UPLOAD);
  if (!fileItem) {
    console.error('画像ファイルが見つかりません。');
    return;
  }
  
  const fileId = fileItem.getResponse()[0];
  const file = DriveApp.getFileById(fileId);
  const fileName = file.getName();
  
  // 画像に新しい名前を付ける(例: タイムスタンプを追加)
  const newFileName = `${new Date().getTime()}_${fileName}`;
  
  // Dropboxにフォルダを作成し、画像をアップロード
  const folderName = 'GoogleFormUploads';
  createDropboxFolderAndUploadFile(folderName, newFileName, file.getBlob());
}

// Dropboxにフォルダを作成し、ファイルをアップロードする関数
function createDropboxFolderAndUploadFile(folderName, fileName, fileBlob) {
  let accessToken = getAccessToken();
  
  // フォルダ作成
  const createFolderUrl = 'https://api.dropboxapi.com/2/files/create_folder_v2';
  const createFolderPayload = {
    path: '/' + folderName,
    autorename: false
  };
  
  try {
    callDropboxApi(createFolderUrl, 'POST', accessToken, createFolderPayload);
  } catch (e) {
    // フォルダが既に存在する場合はエラーを無視
    if (e.message.indexOf('path/conflict/folder') === -1) {
      console.error('フォルダ作成エラー:', e.message);
      return;
    }
  }
  
  // ファイルアップロード
  const uploadUrl = 'https://content.dropboxapi.com/2/files/upload';
  const uploadPayload = {
    path: '/' + folderName + '/' + fileName,
    mode: 'add',
    autorename: true,
    mute: false
  };
  
  try {
    const response = callDropboxApi(uploadUrl, 'POST', accessToken, uploadPayload, fileBlob.getBytes());
    console.log('ファイルがアップロードされました: ' + response);
  } catch (e) {
    console.error('ファイルアップロードエラー:', e.message);
  }
}

// Dropbox APIを呼び出す関数(改善されたエラーハンドリングとリトライロジック付き)
function callDropboxApi(url, method, accessToken, payload, binaryPayload) {
  const config = getConfig();
  let retries = 0;
  let delay = config.INITIAL_RETRY_DELAY;

  while (retries < config.MAX_RETRIES) {
    try {
      const options = {
        method: method,
        headers: {
          'Authorization': 'Bearer ' + accessToken,
          'Content-Type': binaryPayload ? 'application/octet-stream' : 'application/json'
        },
        payload: binaryPayload || JSON.stringify(payload),
        muteHttpExceptions: true
      };

      if (binaryPayload) {
        options.headers['Dropbox-API-Arg'] = JSON.stringify(payload);
      }

      const response = UrlFetchApp.fetch(url, options);
      const responseCode = response.getResponseCode();
      
      if (responseCode === 200) {
        return response.getContentText();
      } else if (responseCode === 401) {
        console.log('アクセストークンが無効です。更新します。');
        accessToken = refreshAccessToken();
        continue; // トークン更新後、即座に再試行
      } else if (responseCode === 429 || (responseCode >= 500 && responseCode < 600)) {
        // レート制限または一時的なサーバーエラーの場合はリトライ
        console.log(`一時的なエラー (${responseCode}). リトライします...`);
      } else {
        throw new Error(`API呼び出しに失敗しました: ${response.getContentText()}`);
      }
    } catch (e) {
      console.error(`エラー発生 (試行 ${retries + 1}/${config.MAX_RETRIES}):`, e.message);
      if (retries === config.MAX_RETRIES - 1) {
        throw e; // 最後の試行で失敗した場合はエラーを投げる
      }
    }

    // 指数バックオフを使用して待機
    Utilities.sleep(delay);
    delay *= 2; // 次の待機時間を2倍に
    retries++;
  }

  throw new Error(`最大リトライ回数 (${config.MAX_RETRIES}) に達しました。`);
}

// 定期的にアクセストークンを更新するトリガーを設定
function setRefreshTokenTrigger() {
  ScriptApp.newTrigger('refreshAccessToken')
    .timeBased()
    .everyHours(1)
    .create();
}

// スクリプトプロパティを設定する関数(初期設定用)
function setScriptProperties() {
  const properties = PropertiesService.getScriptProperties();
  properties.setProperties({
    'DROPBOX_APP_KEY': 'YOUR_DROPBOX_APP_KEY',
    'DROPBOX_APP_SECRET': 'YOUR_DROPBOX_APP_SECRET',
    'DROPBOX_REFRESH_TOKEN': 'YOUR_DROPBOX_REFRESH_TOKEN',
    'MAX_RETRIES': '3',
    'INITIAL_RETRY_DELAY': '1000'
  });
  console.log('スクリプトプロパティが設定されました。');
}

Powershellで実行したら、リフレッシュトークンを取得できる
詳細は

Dropbox APIトークンを取得する

を参考


$Body = @{
    code = '{アクセスコード}'
    grant_type = 'authorization_code'
    client_id = '{App_key}'
    client_secret = '{Secret_key}'
}

$Response = Invoke-RestMethod -Uri 'https://api.dropboxapi.com/oauth2/token' -Method Post -Body $Body

$Response | ConvertTo-Json

コメント

タイトルとURLをコピーしました