
Microsoft 365 OneDrive for Business: ファイル / フォルダコピー (Microsoft 365 OneDrive for Business: Copy File / Folder)
この工程は、OneDrive 上のファイル / フォルダを複製し、指定フォルダに新規保存します。
Configs:共通設定
- 工程名
- メモ
Configs
- C1: OAuth2 設定 *
- C2: コピー元ファイル / フォルダの URL *
- C3: 保存先フォルダの URL (空白の場合、元ファイル / フォルダと同じ場所にコピーされます)
- C4: 新しいファイル / フォルダの名前 *#{EL}
- C5: 新しいファイル / フォルダの URL を保存するデータ項目
Notes
- Microsoft 365 の OneDrive for Business で使用できる自動工程です。個人用の OneDrive では使用できません。
- ファイルやフォルダの URL は、OneDrive でファイルやフォルダの詳細ウィンドウ(右上のiのアイコン)から「その他の詳細」へ進み、「パス」の隣のアイコンから取得します。(上部メニューの「共有」や「リンクのコピー」から取得した URL も使用できます)
- OneDrive 側でのコピー処理の進捗状況によっては、「新しいファイル/フォルダのURL を保存するデータ項目」が空となる場合があります
- 「新しいファイル/フォルダの URL を保存するデータ項目」が空の場合であっても、一定時間経過後には OneDrive 側でコピー処理が完了している見込みです
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/";
main();
function main(){
//// == Config Retrieving / 工程コンフィグの参照 ==
const oauth2 = configs.get( "conf_OAuth2" );
const sourceUrl = retrieveSourceUrl();
const destUrl = retrieveDestUrl();
const newName = retrieveNewName();
const saveUrlDataDef = configs.getObject( "conf_dataForUrl" );
//// == Calculating / 演算 ==
// checking the HTTP requesting limit
checkHttpRequestingLimit( destUrl );
// getting itemInfo for Requesting Copy and Updating Data
const sourceInfo = getItemInfoByUrl( sourceUrl, oauth2 );
const destInfo = getItemInfoByUrl( destUrl, oauth2 );
// sending Copy Request
const copyResponse = sendCopyRequest( sourceInfo, destInfo, newName, oauth2 );
// コピー状況を確認し、ドライブアイテム ID を取得
const newItemId = getNewItemId( copyResponse );
// ワークフローデータへの代入データの作成
const newItemUrl = getNewItemUrl( sourceInfo.driveId, destInfo.driveId, newItemId, oauth2 );
//// == Data Updating / ワークフローデータへの代入 ==
if ( saveUrlDataDef !== null ){
engine.setData( saveUrlDataDef, newItemUrl );
}
}
/**
* configから値を読み出し、必要に応じて値チェックを行った後、値を返す
* @return {String} configの値
*/
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;
}
function retrieveDestUrl() {
const destUrlDef = configs.getObject( "conf_destUrl" );
let destUrl = configs.get( "conf_destUrl" );
if ( destUrlDef !== null ) {
destUrl = engine.findData( destUrlDef );
}
return destUrl;
}
function retrieveNewName() {
const newName = configs.get( "conf_newName" );
if ( newName === "" || newName === null ) {
throw `New file / folder name is empty.`;
}
return newName;
}
/**
* HTTPリクエストの上限を超えないか確認する
* @param {String} destUrl コピー先フォルダのURL
*/
function checkHttpRequestingLimit( destUrl ) {
const reqLimit = httpClient.getRequestingLimit();
if ( destUrl !== "" && destUrl !== null ) {
if ( reqLimit < 5 ) {
throw `HTTP requesting limit is fewer than necessary requests.`;
}
} else if ( reqLimit < 4 ) {
throw `HTTP requesting limit is fewer than neceessary requests.`;
}
}
/**
* ドライブアイテムのURLからアイテム情報(ドライブIDとアイテムID)を取得し、
* オブジェクトで返す(URLが空の場合はドライブIDもアイテムIDも空文字列)
* @param {String} driveItemUrl ドライブアイテム(ファイル、フォルダ)のURL
* @param {String} oauth2 OAuth2 認証設定
* @return {Object} itemInfo ドライブアイテム情報 {driveId, id}
*/
function getItemInfoByUrl( driveItemUrl, oauth2 ) {
let itemInfo = {driveId: "", id: ""};
if ( driveItemUrl !== "" && driveItemUrl !== null ) {
// 分割代入
const {
id: id,
parentReference: {
driveId: driveId
}
} = getObjBySharingUrl( driveItemUrl, oauth2 );
itemInfo = {driveId: driveId, id: 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 {String} 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し、レスポンスを返す
* @param {String} sourceInfo コピー元アイテム情報 {driveId, id}
* @param {String} destInfo コピー先フォルダ情報 {driveId, id}
* @param {String} newName 新しいファイル / フォルダの名前
* @param {String} oauth2 OAuth2 認証設定
* @return {HttpResponseWrapper} response レスポンス
*/
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;
}
/**
* copyリクエストのBODYを生成し、JSON文字列で返す
* @param {Object} destInfo コピー先フォルダ情報 {driveId, id}
* @param {String} newName 新しいファイル / フォルダの名前
* @return {JSON String} requestBody リクエストBODY
*/
function generateCopyRequestBody( destInfo, newName ) {
let requestBodyObj = {};
if ( destInfo.driveId !== "" ) {
requestBodyObj.parentReference = {
driveId: destInfo.driveId,
id: destInfo.id
};
}
if ( newName !== "" && newName !== null ) {
requestBodyObj.name = newName;
}
return JSON.stringify( requestBodyObj );
}
/**
* コピーAPIのレスポンスからコピーの完了状態を確認し、新しいドライブアイテムのIDを返す
* @param {HttpResponseWrapper} copyResponse コピーAPIのレスポンス
* @return {String} newItemId 新しいドライブアイテムのID
*/
function getNewItemId( copyResponse ) {
const location = copyResponse.getHeaderValues("Location").get(0);
const monitorResponseObj = getMonitorResponseObj( location );
const copyStatus = monitorResponseObj.status;
let newItemId = "";
if ( copyStatus === "notStarted" || copyStatus === "inProgress" ) {
// 未開始または進行中の場合、newItemId は空文字列のまま
engine.log(`Copy status: ${copyStatus}\nTo retrieve copy status, GET ${location}\n`);
} else if ( copyStatus === "completed" ) {
// 完了の場合、ドライブアイテムIDを取得
engine.log(`Copy status: ${copyStatus}\n`);
newItemId = monitorResponseObj.resourceId;
} else {
// 不明なステータスの場合はエラー
engine.log(`error: ${JSON.stringify( monitorResponseObj.error )}\n`);
throw `Copy is not in progress nor completed. status: ${copyStatus}`;
}
return newItemId;
}
/**
* copyの完了状態レポートを取得し、JSONオブジェクトを返す
* @param {String} location copy応答のLocationヘッダの値(コピー操作の現在の状況を返すサービスの URL)
* @return {Object} responseObj copy完了状態レポートのJSONオブジェクト
*/
function getMonitorResponseObj( location ) {
// API Request
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 );
}
/**
* 新しいファイル / フォルダのURLを返す
* @param {String} driveIdOfSource コピー元アイテムのドライブのID(フォルダのドライブIDが空文字列の場合に使用)
* @param {String} driveIdOfDest コピー先フォルダのドライブID
* @param {String} newItemId 新しいファイル/ フォルダのID
* @param {String} oauth2 OAuth2 認証設定
* @return {String} newItemUrl 新しいファイル / フォルダのURL
*/
function getNewItemUrl( driveIdOfSource, driveIdOfDest, newItemId, oauth2 ) {
let newItemUrl = "";
// ドライブIDを決める(コピー先フォルダのドライブIDが空文字列でなければフォルダのドライブID)
let driveId = driveIdOfSource;
if ( driveIdOfDest !== "" ) {
driveId = driveIdOfDest;
}
if ( newItemId !== "" ) {
newItemUrl = getItemUrlById( driveId, newItemId, oauth2 );
}
return newItemUrl;
}
/**
* OneDriveのドライブアイテムのメタデータを取得し、URLを返す
* @param {String} driveId ドライブID
* @param {String} itemId アイテムID
* @param {String} oauth2 OAuth2 認証設定
* @return {String} webUrl ドライブアイテムのURL
*/
function getItemUrlById( driveId, itemId, oauth2 ) {
if (itemId === "" || itemId === null) {
throw `DriveItem ID is empty.`;
}
if (driveId === "" || driveId === null) {
throw `Drive ID is empty.`;
}
// API Request
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;
}
ピンバック: ワークフローから OneDrive を活用する – Questetra Support