Microsoft 365 OneDrive for Business: ファイル / フォルダコピー

Microsoft 365 OneDrive for Business: ファイル / フォルダコピー

Microsoft 365 OneDrive for Business: Copy File / Folder

この工程は、OneDrive 上のファイル / フォルダを複製し、指定フォルダに新規保存します。

Auto Step icon
Basic Configs
工程名
メモ
Configs for this Auto Step
conf_OAuth2
C1: OAuth2 設定 *
conf_sourceUrl
C2: コピー元ファイル / フォルダの URL *
conf_destUrl
C3: 保存先フォルダの URL (空白の場合、元ファイル / フォルダと同じ場所にコピーされます)
conf_newName
C4: 新しいファイル / フォルダの名前 *#{EL}
conf_dataForUrl
C5: 新しいファイル / フォルダの URL を保存するデータ項目

Notes

  • Microsoft 365 の OneDrive for Business で使用できる自動工程です
    • 個人用の OneDrive では使用できません
  • ファイルやフォルダの URL は、OneDrive でファイルやフォルダの詳細ウィンドウ(右上のiのアイコン)から「その他の詳細」へ進み、「パス」の隣のアイコンから取得します(上部メニューの「共有」や「リンクのコピー」から取得した URL も使用できます)
    ファイル、フォルダURLの取得方法

Capture

See also

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

// OAuth2 config sample at [OAuth 2.0 Setting]
// - Authorization Endpoint URL: https://login.microsoftonline.com/common/oauth2/v2.0/authorize
// - Token Endpoint URL: https://login.microsoftonline.com/common/oauth2/v2.0/token
// - Scope: https://graph.microsoft.com/Files.ReadWrite.All offline_access
// - Consumer Key: (Get by Microsoft Azure Active Directory)
// - Consumer Secret: (Get by Microsoft Azure Active Directory)

// グローバル変数
const GRAPH_URI = "https://graph.microsoft.com/v1.0/";

function main() {
    //// == Config Retrieving / 工程コンフィグの参照 ==
    const oauth2 = configs.getObject("conf_OAuth2");
    const sourceUrl = retrieveSourceUrl();
    const destUrl = retrieveDestUrl();
    const newName = retrieveNewName();
    const saveUrlDataDef = configs.getObject("conf_dataForUrl");

    //// == Calculating / 演算 ==
    // getting itemInfo for Requesting Copy and Updating Data
    const sourceInfo = getItemInfoByUrl(sourceUrl, oauth2);
    const destInfo = getItemInfoByUrl(destUrl, oauth2);
    // sending Copy Request
    const location = sendCopyRequest(sourceInfo, destInfo, newName, oauth2);
    const driveId = destInfo.driveId ?? sourceInfo.driveId;

    // コピー状況を確認し、未完了なら proceed() に進む
    if (checkStatusAndSaveUrl(location, driveId, oauth2, saveUrlDataDef) === false) {
        // location と driveId を一時データとして保存
        const tempData = {location, driveId};
        engine.saveTemporaryData(JSON.stringify(tempData));
        return false;
    }
}

function proceed() {
    //// == Config Retrieving / 工程コンフィグの参照 ==
    const oauth2 = configs.getObject("conf_OAuth2");
    const saveUrlDataDef = configs.getObject("conf_dataForUrl");

    //// == Restoring Temporary Data / 一時データの読み出し ==
    const tempDataStr = engine.restoreTemporaryData();
    if (tempDataStr === null) {
        throw 'temporary data has not been saved';
    }
    const { location, driveId } = JSON.parse(tempDataStr);

    if (checkStatusAndSaveUrl(location, driveId, oauth2, saveUrlDataDef) === false) {
        return false;
    }
}

/**
  * config からコピー元アイテムの URL を読み出す
  * 空の場合はエラー
  * @return {String} sourceUrl
  */
function retrieveSourceUrl() {
    const sourceUrlDef = configs.getObject("conf_sourceUrl");
    let sourceUrl = configs.get("conf_sourceUrl");
    if (sourceUrlDef !== null) {
        sourceUrl = engine.findData(sourceUrlDef);
    }
    if (sourceUrl === "" || sourceUrl === null) {
        throw `Source file / folder URL is empty.`;
    }
    return sourceUrl;
}

/**
  * config からコピー先フォルダの URL を読み出す
  * @return {String} destUrl
  */
function retrieveDestUrl() {
    const destUrlDef = configs.getObject("conf_destUrl");
    let destUrl = configs.get("conf_destUrl");
    if (destUrlDef !== null) {
        destUrl = engine.findData(destUrlDef);
    }
    return destUrl;
}

/**
  * config から新しいファイル / フォルダの名前を読み出す
  * @return {String} newName
  */
function retrieveNewName() {
    const newName = configs.get("conf_newName");
    if (newName === "" || newName === null) {
        throw `New file / folder name is empty.`;
    }
    return newName;
}

/**
  * ドライブアイテムのURLからアイテム情報(ドライブIDとアイテムID)を取得し、
  * オブジェクトで返す(URLが空の場合はドライブIDもアイテムIDも空文字列)
  * @param {String} driveItemUrl  ドライブアイテム(ファイル、フォルダ)のURL
  * @param {AuthSettingWrapper} oauth2  OAuth2 認証設定
  * @return {Object} itemInfo  ドライブアイテム情報 {driveId, id}
  */
function getItemInfoByUrl(driveItemUrl, oauth2) {
    let itemInfo = {};
    if (driveItemUrl !== "" && driveItemUrl !== null) {
        // 分割代入
        const {
            id,
            parentReference: {
                driveId
            }
        } = getObjBySharingUrl(driveItemUrl, oauth2);
        itemInfo = {driveId, id};
    }
    return itemInfo;
}

/**
  * OneDriveのドライブアイテム(ファイル、フォルダ)のメタデータを取得し、JSONオブジェクトを返す
  * APIの仕様: https://docs.microsoft.com/ja-jp/onedrive/developer/rest-api/api/shares_get?view=odsp-graph-online
  * @param {String} sharingUrl  ドライブアイテムの共有URL
  * @param {AuthSettingWrapper} oauth2  OAuth2 認証設定
  * @return {Object} responseObj  ドライブアイテムのメタデータのJSONオブジェクト
  */
function getObjBySharingUrl(sharingUrl, oauth2) {
    if (sharingUrl === "" || sharingUrl === null) {
        throw `Sharing URL is empty.`;
    }

    // encoding sharing URL
    const encodedSharingUrl = encodeSharingUrl(sharingUrl);

    // API Request
    const response = httpClient.begin() // HttpRequestWrapper
        .authSetting(oauth2) // Request HEADER (OAuth2 Token)
        .get(`${GRAPH_URI}shares/${encodedSharingUrl}/driveItem`); // HttpResponseWrapper
    const httpStatus = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (httpStatus >= 300) {
        const accessLog = `---GET request--- ${httpStatus}\n${responseStr}\n`;
        engine.log(accessLog);
        throw `Failed to get drive item. status: ${httpStatus}`;
    }
    return JSON.parse(response.getResponseAsString());
}

/**
  * 共有URLをunpadded base64url 形式にエンコードする
  * @param {String} sharingUrl  共有URL
  * @return {String} encodedSharingUrl  エンコードされた共有URL
  */
function encodeSharingUrl(sharingUrl) {
    let encodedSharingUrl = base64.encodeToUrlSafeString(sharingUrl);
    while (encodedSharingUrl.slice(-1) === '=') {
        encodedSharingUrl = encodedSharingUrl.slice(0, -1);
    }
    return `u!${encodedSharingUrl}`;
}

/**
  * copy リクエストを POST し、コピーステータス確認先 URL を返す
  * @param {Object} sourceInfo  コピー元アイテム情報 {driveId, id}
  * @param {Object} destInfo  コピー先フォルダ情報 {driveId, id}
  * @param {String} newName  新しいファイル / フォルダの名前
  * @param {AuthSettingWrapper} oauth2  OAuth2 認証設定
  * @return {String} location  コピーステータス確認先 URL
  */
function sendCopyRequest(sourceInfo, destInfo, newName, oauth2) {
    // Request PATH
    const apiUri = `${GRAPH_URI}drives/${sourceInfo.driveId}/items/${sourceInfo.id}/copy`;
    // Request BODY (JSON, Form Parameters, etc)
    const requestBody = generateCopyRequestBody(destInfo, newName);
    // API Request
    const response = httpClient.begin() // HttpRequestWrapper
        .authSetting(oauth2) // Request HEADER (OAuth2 Token)
        .body(requestBody, "application/json")
        .post(apiUri); // HttpResponseWrapper
    const httpStatus = response.getStatusCode();
    if (httpStatus >= 300) {
        const accessLog = `---POST request--- ${httpStatus}\n${response.getResponseAsString()}\n`;
        engine.log(accessLog);
        throw `Failed to copy. status: ${httpStatus}`;
    }
    return response.getHeaderValues("Location").get(0);
}

/**
  * copyリクエストのBODYを生成し、JSON文字列で返す
  * @param {Object} destInfo  コピー先フォルダ情報 {driveId, id}
  * @param {String} newName  新しいファイル / フォルダの名前
  * @return {JSON String} requestBody  リクエストBODY
  */
function generateCopyRequestBody(destInfo, newName) {
    const requestBodyObj = {};
    if (destInfo.driveId !== undefined) {
        requestBodyObj.parentReference = destInfo;
    }
    if (newName !== "" && newName !== null) {
        requestBodyObj.name = newName;
    }
    return JSON.stringify(requestBodyObj);
}

/**
  * コピーの完了状態を確認し、完了していれば新しいアイテムの URL を保存する
  * コピー未完了の場合は false を返す
  * @param {String} location  コピーステータス確認用 URL
  * @param {String} driveId  新しいアイテムのドライブ ID
  * @param {AuthSettingWrapper} oauth2  OAuth2 認証設定
  * @param {DataDefinitionView} saveUrlDataDef  URL を保存するデータ項目
  * @return {boolean}
  */
function checkStatusAndSaveUrl(location, driveId, oauth2, saveUrlDataDef) {
    const newItemId = checkStatusAndGetNewItemId(location);
    if (newItemId === null) {
        return false;
    }
    const newItemUrl = getItemUrlById(driveId, newItemId, oauth2);

    if (saveUrlDataDef !== null) {
        engine.setData(saveUrlDataDef, newItemUrl);
    }
}

/**
  * コピーの完了状態を確認し、新しいドライブアイテムのIDを返す
  * コピー未完了の場合は null を返す
  * @param {String} location  コピーステータス確認用 URL
  * @return {String} newItemId  新しいドライブアイテムのID
  */
function checkStatusAndGetNewItemId(location) {
    const monitorResponseObj = getMonitorResponseObj(location);
    const copyStatus = monitorResponseObj.status;
    if (copyStatus === "notStarted" || copyStatus === "inProgress") {
        // 未開始または進行中の場合、null を返す
        engine.log(`Copy status: ${copyStatus}`);
        return null;
    }
    if (copyStatus === "completed") {
        // 完了の場合、ドライブアイテム ID を返す
        engine.log(`Copy status: ${copyStatus}`);
        return monitorResponseObj.resourceId;
    }
    // 不明なステータスの場合はエラー
    engine.log(`error: ${JSON.stringify(monitorResponseObj.error)}`);
    throw `Copy is not in progress nor completed. status: ${copyStatus}`;
}

/**
  * copyの完了状態レポートを取得し、JSONオブジェクトを返す
  * @param {String} location  copy応答のLocationヘッダの値(コピー操作の現在の状況を返すサービスの URL)
  * @return {Object} responseObj  copy完了状態レポートのJSONオブジェクト
  */
function getMonitorResponseObj(location) {
    const response = httpClient.begin() // HttpRequestWrapper
        .get(location); // HttpResponseWrapper
    const httpStatus = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (httpStatus >= 300) {
        const accessLog = `---GET request--- ${httpStatus}\n${responseStr}\n`;
        engine.log(accessLog);
        throw `Failed to get monitor. status: ${httpStatus}`;
    }
    return JSON.parse(responseStr);
}

/**
  * OneDriveのドライブアイテムのメタデータを取得し、URLを返す
  * @param {String} driveId  ドライブID
  * @param {String} itemId  アイテムID
  * @param {AuthSettingWrapper} oauth2  OAuth2 認証設定
  * @return {String} webUrl  ドライブアイテムのURL
  */
function getItemUrlById(driveId, itemId, oauth2) {
    const response = httpClient.begin() // HttpRequestWrapper
        .authSetting(oauth2) // Request HEADER (OAuth2 Token)
        .get(`${GRAPH_URI}drives/${driveId}/items/${itemId}`); // HttpResponseWrapper
    const httpStatus = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (httpStatus >= 300) {
        const accessLog = `---GET request--- ${httpStatus}\n${responseStr}\n`;
        engine.log(accessLog);
        throw `Failed to get file. status: ${httpStatus}`;
    }
    const responseObj = JSON.parse(responseStr);
    return responseObj.webUrl;
}

    

「Microsoft 365 OneDrive for Business: ファイル / フォルダコピー」への1件のフィードバック

  1. ピンバック: ワークフローから OneDrive を活用する – Questetra Support

コメントは受け付けていません。

Questetra Supportをもっと見る

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

続きを読む

上部へスクロール