2026-07-28 (C) Questetra, Inc. (MIT License) 3 2 This item searches for a drive item (such as a file or a folder) with a specific name directly under the specified folder on OneDrive. The search result status is one of the following: FOUND_FILE / FOUND_FOLDER / FOUND_OTHER / NOT_FOUND この工程は、OneDrive の指定フォルダ直下に特定の名前の項目(ファイルやフォルダ)があるかどうか調べます。検索結果のステータスは、FOUND_FILE / FOUND_FOLDER / FOUND_OTHER / NOT_FOUND のいずれかです。 https://support.questetra.com/en/bpmn-icons/service-task-onedrive-file-search/ https://support.questetra.com/ja/bpmn-icons/service-task-onedrive-file-search/ iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADXUlEQVRYR8WXW0hUURSG/33GbC5e 8pJJF6nM6YKUmsFAIAZSONOM4FtqL/mQVg9GhXR5iCIiEAqF9KEMsvKpi06OZoRPGaRmVoSGU4om aqaMzeXYOLPjTJ7R41w8k8bZLwNn1r/Wt9dee+29CSQeRHR8vVEpd7vzGTAHKKXpADYDiJnTTwEY IIR0u+FuYxnmCYx6uxjfSwKotE2JbuoqB0EJALkYpwBYUNQwRHbDZtKNBtMEBVBqG0ooSAUAlcjA i81sBPSs3ZRXE0gfEECuM94mlJb+Y2CBjBJSzTbpT/jz5RdAoTU+BGjBSgSf90EeOUz6wsU+fQBW cuaLg/nLhABgbs2rV3bmQm8EtHRhTXgBPNUOV/8yCk4st42BbBu/O7wAitzGmyAoE+tlWXYUtxzN htOcj78AeqNS4aI/Q9jneH5Ng0x1DCLkMlhZFz59m0ZZ9UfPr4jBOmQkjmtWHgC5rqGIUFIXTHih QI3UzVHoH7HhsCYROzZF+JgPjNqxq/iViPgAJfQo25T3wAOg1BnvUkqP+VNGKsLQXpmF5PXCXmR1 zKJvyAqL3Yn4qHCoN0ZCHs6gvm0YxRXdS0IQQmrtTfpiD4BC2/gOANfffUbjVQ1yMtYKvnNZGJlg kZESDeVqGSy2WbzoHPdkpdtswcnKniUBAHQ7TIYMHmBywcEiEPfey0FSgsL7zWJzosc8jazdcQI7 l5tiwvIbUaowTE47UfXMjMqnX4OBTDlMhlgegC62TNmgwp0z6UhLjsaqMMbzN5f25o4x5O5bhwhF WNBZ2mdcyDn3Gu/NloB2DpOBBAToqs7GzqRIr/j7BIu+4V9I2xqN2KhwMSlGbcsgTlV9EAXgswSW Bp135pQCrV3jOJSZICowb2RjXWjtHEfh9U5/OsES+BThj8daqOQyb+q/DFuRkbImJADOmKuNg+Xt ePOZm6NgzBehv21YfzETek0iGIZgxun2OMjeEx8yACfIv/wWLR1jAq1gGwZqROePqLE/NRZjUzOo ezmE++V7ER8tbv35aFzm0o63+YALGlEorfhS0XZsSVSKysTgmANX6nr92QpbMWch7WHEncFSH8dc FiS9kPALJemVjIeQ9FL6PzIR8rWch5D0YcJDSPo0E3QQqR6nolreMoz+ACVfiTBvFfnjAAAAAElF TkSuQmCC { const oauth2 = httpClient.createAuthSettingOAuth2( 'OneDrive', 'https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize', 'https://login.microsoftonline.com/organizations/oauth2/v2.0/token', 'https://graph.microsoft.com/Files.ReadWrite.All offline_access', 'client_id', 'client_secret', 'access_token' ); configs.putObject('conf_OAuth2', oauth2); configs.put('conf_Name', name); // 検索対象の親フォルダの URL を保存する文字型データ項目(単数行)を準備 const parentFolderUrlDef = engine.createDataDefinition('親フォルダの URL', 1, 'q_parent_folder_url', 'STRING_TEXTFIELD'); engine.setData(parentFolderUrlDef, parentFolderUrl); configs.putObject('conf_ParentFolderUrl', parentFolderUrlDef); // 検索結果のステータスを保存する文字型データ項目(単数行)を準備 const statusDef = engine.createDataDefinition('ステータス', 2, 'q_status', 'STRING_TEXTFIELD'); engine.setData(statusDef, '事前文字列'); configs.putObject('conf_Status', statusDef); // 見つかった項目の URL を保存する文字型データ項目(単数行)を準備 const foundUrlDef = engine.createDataDefinition('見つかった項目の URL', 3, 'q_found_url', 'STRING_TEXTFIELD'); engine.setData(foundUrlDef, '事前文字列'); configs.putObject('conf_FoundUrl', foundUrlDef); return { statusDef, foundUrlDef }; }; /** * 異常系のテスト * @param errorMsg */ const assertError = (errorMsg) => { let failed = false; try { main(); } catch (e) { failed = true; expect(e.message).toEqual(errorMsg); } if (!failed) { fail('No error was thrown.'); } }; /** * 親フォルダのメタデータを取得する GET リクエストのテスト * @param {Object} request * @param request.url * @param request.method * @param sharingUrl */ const assertGetRequest = ({ url, method }, sharingUrl) => { expect(url).toEqual(`${GRAPH_URI}shares/${encodeSharingUrl(sharingUrl)}/driveItem`); expect(method).toEqual('GET'); }; /** * 子アイテムを検索する GET リクエストのテスト * @param {Object} request * @param request.url * @param request.method * @param request.headers * @param expectedUrl */ const assertSearchRequest = ({ url, method, headers }, expectedUrl) => { expect(url).toEqual(expectedUrl); expect(method).toEqual('GET'); expect(headers.get('Prefer')).toEqual('Include-Feature=AddToOneDrive'); }; /** * Name to search for が空でエラーになる場合 */ test('Name to search for is blank', () => { prepareConfigs('https://test-my.sharepoint.com/personal/aaa/Documents/parent1', ''); assertError('Name to search for is blank.'); }); /** * C4, C5 のいずれも設定されておらずエラーになる場合 */ test('Neither of the data items to save the result is set', () => { prepareConfigs('https://test-my.sharepoint.com/personal/aaa/Documents/parent2', 'test2'); configs.put('conf_Status', ''); configs.put('conf_FoundUrl', ''); assertError('Neither of the data items to save the result is set.'); }); /** * 親フォルダのメタデータ取得リクエストが失敗する場合 */ test('GET Failed - retrieving parent folder metadata', () => { prepareConfigs('https://test-my.sharepoint.com/personal/aaa/Documents/parent3', 'test3'); httpClient.setRequestHandler((request) => { assertGetRequest(request, 'https://test-my.sharepoint.com/personal/aaa/Documents/parent3'); return httpClient.createHttpResponse(400, 'application/json', '{}'); }); assertError('Failed to get drive item. status: 400'); }); /** * 親フォルダの URL に指定した項目がフォルダでない場合 */ test('Parent Folder URL does not point to a folder', () => { prepareConfigs('https://test-my.sharepoint.com/personal/aaa/Documents/notAFolder', 'test4'); httpClient.setRequestHandler((request) => { assertGetRequest(request, 'https://test-my.sharepoint.com/personal/aaa/Documents/notAFolder'); const responseObj = { 'id': 'Id001', 'file': {}, 'parentReference': { 'driveId': 'Drive001' } }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); assertError('The drive item specified by Parent Folder URL is not a folder.'); }); /** * 子アイテム検索リクエストが失敗する場合 - 親フォルダ URL をデータ項目で指定 */ test('GET Failed - searching child items', () => { prepareConfigs('https://test-my.sharepoint.com/personal/aaa/Documents/parent5', 'test5'); let reqCount = 0; httpClient.setRequestHandler((request) => { if (reqCount++ === 0) { assertGetRequest(request, 'https://test-my.sharepoint.com/personal/aaa/Documents/parent5'); const responseObj = { 'id': 'Id002', 'folder': {}, 'parentReference': { 'driveId': 'Drive002' } }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); } assertSearchRequest(request, `${GRAPH_URI}drives/Drive002/items/Id002/children?%24select=name%2Cfile%2Cfolder%2CwebUrl`); return httpClient.createHttpResponse(400, 'application/json', '{}'); }); assertError('Failed to search. status: 400'); }); /** * ファイルが見つかる場合 - 親フォルダ URL を固定値で指定 */ test('Success - Found File - Specify Parent Folder URL with a fixed value', () => { const { statusDef, foundUrlDef } = prepareConfigs(null, 'file1.txt'); configs.put('conf_ParentFolderUrl', 'https://test-my.sharepoint.com/personal/aaa/Documents/parent6'); let reqCount = 0; httpClient.setRequestHandler((request) => { if (reqCount++ === 0) { assertGetRequest(request, 'https://test-my.sharepoint.com/personal/aaa/Documents/parent6'); const responseObj = { 'id': 'Id003', 'folder': {}, 'parentReference': { 'driveId': 'Drive003' } }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); } assertSearchRequest(request, `${GRAPH_URI}drives/Drive003/items/Id003/children?%24select=name%2Cfile%2Cfolder%2CwebUrl`); const responseObj = { 'value': [ { 'name': 'other.txt', 'file': {}, 'webUrl': 'https://example.com/other.txt' }, { 'name': 'file1.txt', 'file': {}, 'webUrl': 'https://example.com/file1.txt' } ] }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); main(); expect(engine.findData(statusDef)).toEqual('FOUND_FILE'); expect(engine.findData(foundUrlDef)).toEqual('https://example.com/file1.txt'); }); /** * フォルダが見つかる場合 - 親フォルダ URL 未指定(ルートフォルダ直下を検索) */ test('Success - Found Folder - Parent Folder URL is blank (search under root)', () => { const { statusDef, foundUrlDef } = prepareConfigs('', 'folder1'); httpClient.setRequestHandler((request) => { assertSearchRequest(request, `${GRAPH_URI}me/drive/items/root/children?%24select=name%2Cfile%2Cfolder%2CwebUrl`); const responseObj = { 'value': [ { 'name': 'folder1', 'folder': {}, 'webUrl': 'https://example.com/folder1' } ] }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); main(); expect(engine.findData(statusDef)).toEqual('FOUND_FOLDER'); expect(engine.findData(foundUrlDef)).toEqual('https://example.com/folder1'); }); /** * ファイルでもフォルダでもない項目が見つかる場合(FOUND_OTHER) */ test('Success - Found Other', () => { const { statusDef, foundUrlDef } = prepareConfigs('', 'notebook1'); httpClient.setRequestHandler((request) => { assertSearchRequest(request, `${GRAPH_URI}me/drive/items/root/children?%24select=name%2Cfile%2Cfolder%2CwebUrl`); const responseObj = { 'value': [ { 'name': 'notebook1', 'package': { 'type': 'oneNote' }, 'webUrl': 'https://example.com/notebook1' } ] }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); main(); expect(engine.findData(statusDef)).toEqual('FOUND_OTHER'); expect(engine.findData(foundUrlDef)).toEqual('https://example.com/notebook1'); }); /** * 見つかった項目に webUrl が無い場合、見つかった項目の URL は null になる */ test('Success - Found Folder but webUrl is missing', () => { const { statusDef, foundUrlDef } = prepareConfigs('', 'folder2'); httpClient.setRequestHandler((request) => { assertSearchRequest(request, `${GRAPH_URI}me/drive/items/root/children?%24select=name%2Cfile%2Cfolder%2CwebUrl`); const responseObj = { 'value': [ { 'name': 'folder2', 'folder': {} } ] }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); main(); expect(engine.findData(statusDef)).toEqual('FOUND_FOLDER'); expect(engine.findData(foundUrlDef)).toEqual(null); }); /** * 検索対象の名前が最終ページまで見つからない場合(NOT_FOUND) */ test('Success - Not Found', () => { const { statusDef, foundUrlDef } = prepareConfigs('', 'notExist'); httpClient.setRequestHandler((request) => { assertSearchRequest(request, `${GRAPH_URI}me/drive/items/root/children?%24select=name%2Cfile%2Cfolder%2CwebUrl`); const responseObj = { 'value': [ { 'name': 'other1', 'file': {} } ] }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); main(); expect(engine.findData(statusDef)).toEqual('NOT_FOUND'); expect(engine.findData(foundUrlDef)).toEqual(null); }); /** * ページングを行い、2 回目のリクエストで見つかる場合 * 2 回目以降のリクエストでは $select クエリが付与されないことも確認する */ test('Success - Found on the 2nd page', () => { const { statusDef, foundUrlDef } = prepareConfigs('', 'target'); const nextLink = `${GRAPH_URI}me/drive/items/root/children?%24skiptoken=abc123`; let reqCount = 0; httpClient.setRequestHandler((request) => { if (reqCount++ === 0) { assertSearchRequest(request, `${GRAPH_URI}me/drive/items/root/children?%24select=name%2Cfile%2Cfolder%2CwebUrl`); const responseObj = { 'value': [ { 'name': 'other2', 'file': {} } ], '@odata.nextLink': nextLink }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); } assertSearchRequest(request, nextLink); const responseObj = { 'value': [ { 'name': 'target', 'folder': {}, 'webUrl': 'https://example.com/target' } ] }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); main(); expect(reqCount).toEqual(2); expect(engine.findData(statusDef)).toEqual('FOUND_FOLDER'); expect(engine.findData(foundUrlDef)).toEqual('https://example.com/target'); }); /** * リクエスト数の上限を超えてしまう場合 */ test('Too many drive items are in the specified folder', () => { prepareConfigs('', 'neverFound'); let reqCount = 0; httpClient.setRequestHandler(() => { const responseObj = { 'value': [ { 'name': `other${reqCount}`, 'file': {} } ], '@odata.nextLink': `${GRAPH_URI}me/drive/items/root/children?%24skiptoken=page${reqCount}` }; reqCount++; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); assertError('Too many drive items are in the specified folder. The search could not be completed.'); }); /** * C4(ステータス)のみが設定されている場合、C5(URL)は保存されない */ test('Success - Only conf_Status data item is set', () => { const { statusDef, foundUrlDef } = prepareConfigs('', 'file2.txt'); configs.put('conf_FoundUrl', ''); httpClient.setRequestHandler((request) => { assertSearchRequest(request, `${GRAPH_URI}me/drive/items/root/children?%24select=name%2Cfile%2Cfolder%2CwebUrl`); const responseObj = { 'value': [ { 'name': 'file2.txt', 'file': {}, 'webUrl': 'https://example.com/file2.txt' } ] }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); main(); expect(engine.findData(statusDef)).toEqual('FOUND_FILE'); expect(engine.findData(foundUrlDef)).toEqual('事前文字列'); }); /** * C5(URL)のみが設定されている場合、C4(ステータス)は保存されない */ test('Success - Only conf_FoundUrl data item is set', () => { const { statusDef, foundUrlDef } = prepareConfigs('', 'file3.txt'); configs.put('conf_Status', ''); httpClient.setRequestHandler((request) => { assertSearchRequest(request, `${GRAPH_URI}me/drive/items/root/children?%24select=name%2Cfile%2Cfolder%2CwebUrl`); const responseObj = { 'value': [ { 'name': 'file3.txt', 'file': {}, 'webUrl': 'https://example.com/file3.txt' } ] }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); main(); expect(engine.findData(statusDef)).toEqual('事前文字列'); expect(engine.findData(foundUrlDef)).toEqual('https://example.com/file3.txt'); }); /** * 検索する名前と実際の項目名で大文字・小文字が異なっていても見つかる場合 */ test('Success - Found File - Case-insensitive match', () => { const { statusDef, foundUrlDef } = prepareConfigs('', 'FILE4.TXT'); httpClient.setRequestHandler((request) => { assertSearchRequest(request, `${GRAPH_URI}me/drive/items/root/children?%24select=name%2Cfile%2Cfolder%2CwebUrl`); const responseObj = { 'value': [ { 'name': 'file4.txt', 'file': {}, 'webUrl': 'https://example.com/file4.txt' } ] }; return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(responseObj)); }); main(); expect(engine.findData(statusDef)).toEqual('FOUND_FILE'); expect(engine.findData(foundUrlDef)).toEqual('https://example.com/file4.txt'); }); ]]>