Google ドライブ: ファイルダウンロード

Google ドライブ: ファイルダウンロード

Google Drive: Download File

この工程は、Google ドライブ内の指定ファイルをダウンロードします。一度に複数のダウンロードが可能です。複数ダウンロードする場合、データ項目では 1 行につき 1 つずつファイル ID を書くようにしてください。

Basic Configs
工程名
メモ
Auto Step icon
Configs for this Auto Step
conf_Auth
C1: サービスアカウント設定 *
conf_FileIds
C2: ダウンロードするファイルの ID(1 行に 1 つ) *
conf_FileData
C3: ダウンロードファイルを追加保存するデータ項目 *

Notes

  • ダウンロードするファイルは、事前に[C1: サービスアカウント設定]のサービスアカウントと共有しておく必要があります
  • [C1: サービスアカウント設定]を設定するには:
    1. Google Cloud コンソールでサービスアカウントを準備します
    2. Questetra BPM Suite で OAuth2 JWT ベアラーフローの設定を作成し、C1 に設定します
      • スコープ https://www.googleapis.com/auth/drive.readonly が必要です
      • 以降の項目は、下表のとおり設定してください
Questetra BPM Suite の設定項目対応する Google Cloud
サービスアカウントキーの情報
JSON ファイルの項目名設定必須かどうか
クライアント IDOAuth2 クライアント IDclient_id任意
秘密鍵 IDキー IDprivate_key_id必須
秘密鍵秘密鍵private_key必須
カスタム秘密情報 1メールアドレスclient_email必須

Capture

See Also

Script (click to open)
  • 次のスクリプトが記述されている XML ファイルをダウンロードできます
    • google-drive-file-download.xml (C) Questetra, Inc. (MIT License)
    • Professional のワークフロー基盤では、ファイル内容を改変しオリジナルのアドオン自動工程として活用できます


const REQUEST_NUM_PER_FILE = 4; // ファイル 1 つにつき 4 回リクエストを行う

function main() {
    ////// == 工程コンフィグ・ワークフローデータの参照 / Config & Data Retrieving ==
    const auth = configs.getObject('conf_Auth');
    const fileIds = retrieveFileIds();

    const fileDef = configs.getObject('conf_FileData');
    let files = engine.findData( fileDef );
    if (files === null) {
        files = new java.util.ArrayList();
    }

    ////// == 演算 / Calculating ==
    if (fileIds.length * REQUEST_NUM_PER_FILE > httpClient.getRequestingLimit()) {
        throw new Error('Number of File IDs exceeds the limit.');
    }
    fileIds.forEach(fileId => {
        const {name, contentType} = getFileMetadata(auth, fileId);
        const content = getFile(auth, fileId);
        const qfile = new com.questetra.bpms.core.event.scripttask.NewQfile(
            name, contentType, content
        );
        files.add(qfile);
    });

    ////// == ワークフローデータへの代入 / Data Updating ==
    engine.setData(fileDef, files);
}

/**
 * config からファイル ID を読み出す
 * ファイル ID が設定されていない場合はエラー
 * @returns {Array<String>} ファイル ID の配列
 */
const retrieveFileIds = () => {
    let fileIdsStr = configs.get('conf_FileIds');
    const fileIdsDef = configs.getObject('conf_FileIds');
    if (fileIdsDef !== null) {
        fileIdsStr = engine.findData(fileIdsDef);
    }
    if (fileIdsStr === null) {
        throw new Error('No File IDs.');
    }
    const fileIds =  fileIdsStr.split('\n').filter(key => key.length !== 0);
    if (fileIds.length === 0) {
        throw new Error('No File IDs.');
    }
    return fileIds;
};

const URL_TOKEN_REQUEST = 'https://oauth2.googleapis.com/token';
const SCOPE = 'https://www.googleapis.com/auth/drive.readonly';

/**
 * @param auth HTTP 認証設定
 * @returns {any} アクセストークンを含むオブジェクト
 */
const getAccessToken = (auth) => {
    const privateKeyId = auth.getPrivateKeyId();
    const privateKey = auth.getPrivateKey();
    const serviceAccount = auth.getCustomSecret1();
    const scope = auth.getScope();
    if (!scope.split(' ').includes(SCOPE)) {
        throw new Error(`Scope ${SCOPE} must be included in the scope.`);
    }
    if (privateKeyId === '') {
        throw new Error('Private Key ID is required.');
    }
    if (privateKey === '') {
        throw new Error('Private Key is required.');
    }
    if (serviceAccount === '') {
        throw new Error('Service Account must be set to Custom Secret 1.');
    }
    const header = {
        "alg": "RS256",
        "typ": "at+jwt",
        "kid": privateKeyId
    };
    const now = Math.floor(Date.now() / 1000);
    const payload = {
        "iss": serviceAccount,
        "aud": URL_TOKEN_REQUEST,
        "sub": '',
        "iat": now,
        "exp": now + 3600,
        /**
         * https://developers.google.com/identity/protocols/oauth2/service-account#jwt-auth
         * "without OAuth" の話だが、OAuth でも 1 hour になるようだ。
         * 1 hour より長ければエラー。短ければ、1 hour のトークンが返ってくる。
         */
        scope
    };
    const keyB = rsa.readKeyFromPkcs8(privateKey);
    const assertion = jwt.build(header, payload, keyB);

    const response = httpClient.begin()
        .formParam("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")
        .formParam('assertion', assertion)
        .post(URL_TOKEN_REQUEST);
    const responseText = response.getResponseAsString();
    if (response.getStatusCode() !== 200) {
        engine.log(responseText);
        throw new Error(`Failed to get Access token. status: ${response.getStatusCode()}`);
    }
    const result = JSON.parse(response.getResponseAsString());
    if (result.access_token === undefined) {
        engine.log(responseText);
        throw new Error(`Failed to get Access token. access token not found.`);
    }
    return result;
};

/**
 * ファイルメタデータ取得
 * @param auth HTTP 認証設定
 * @param fileId ファイルID
 */
const getFileMetadata = (auth, fileId) => {
    const URL = `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}`;

    const response = httpClient.begin()
        .oauth2JwtBearer(auth, () => getAccessToken(auth))
        .queryParam("supportsAllDrives", "true")
        .get(URL);

    const status = response.getStatusCode();
    const respTxt = response.getResponseAsString();
    if (status !== 200) {
        engine.log(respTxt);
        throw new Error(`Failed to get metadata of file. status: ${status}`);
    }
    const respJson = JSON.parse(respTxt);
    return {
        name: respJson.name,
        contentType: respJson.mimeType
    };
};

/**
 * ファイル取得
 * @param auth HTTP 認証設定
 * @param fileId ファイルID
 */
const getFile = (auth, fileId) => {
    const URL = `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}`;

    const response = httpClient.begin()
        .oauth2JwtBearer(auth, () => getAccessToken(auth))
        .queryParam("supportsAllDrives", "true")
        .queryParam("alt", "media")
        .get(URL);

    const status = response.getStatusCode();
    const respTxt = response.getResponseAsString();
    if (status !== 200) {
        engine.log(respTxt);
        throw new Error(`Failed to download file. status: ${status}`);
    }
    return response.getResponse();
};

Questetra Supportをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む

上部へスクロール