Skip to main content
Glama

mcp-google-sheets

copy-item.ts4.42 kB
import { microsoftSharePointAuth } from '../../'; import { createAction, Property } from '@activepieces/pieces-framework'; import { microsoftSharePointCommon } from '../common'; import { Client, ResponseType } from '@microsoft/microsoft-graph-client'; const polling_delay_ms = 2000; const polling_timeout_secs = 120; async function delay(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); } export const copyItemAction = createAction({ auth: microsoftSharePointAuth, name: 'microsoft_sharepoint_copy_item', displayName: 'Copy File or Folder (Across Sites)', description: 'Copy a file or folder from one site to another within the same tenant, with overwrite option.', props: { siteId: microsoftSharePointCommon.siteId, driveId: microsoftSharePointCommon.driveId, itemId: microsoftSharePointCommon.itemId, destination_site_id: microsoftSharePointCommon.siteId, destination_drive_id: microsoftSharePointCommon.createDriveDropdown({ displayName: 'Destination Drive', refreshers: ['destination_site_id'], }), destination_folder_id: microsoftSharePointCommon.destinationFolderId, new_name: Property.ShortText({ displayName: 'New Name (Optional)', description: 'A new name for the copied item. If not provided, the original name is used.', required: false, }), conflict_behavior: Property.StaticDropdown({ displayName: 'Conflict Behavior', description: 'Action to take if a file with the same name already exists.', required: true, options: { options: [ { label: 'Fail on conflict', value: 'fail' }, { label: 'Overwrite existing file', value: 'replace' }, { label: 'Rename with a number', value: 'rename' }, ], }, defaultValue: 'fail', }), }, async run(context) { const { siteId, driveId, itemId, destination_drive_id, destination_folder_id, new_name, conflict_behavior, } = context.propsValue; const client = Client.initWithMiddleware({ authProvider: { getAccessToken: () => Promise.resolve(context.auth.access_token), }, }); const body: { parentReference: { driveId: string; id?: string }; name?: string } = { parentReference: { driveId: destination_drive_id, }, }; if (destination_folder_id) { body.parentReference.id = destination_folder_id; } if (new_name) { body.name = new_name; } let initialResponse; try { initialResponse = await client .api(`/drives/${driveId}/items/${itemId}/copy`) .responseType(ResponseType.RAW) .query({ '@microsoft.graph.conflictBehavior': conflict_behavior }) .post(body); } catch (error: any) { if (error.statusCode === 400) { throw new Error(`Invalid request: ${error.message || 'Check your input parameters'}`); } if (error.statusCode === 403) { throw new Error('Insufficient permissions to copy this item. Requires Files.ReadWrite or higher.'); } if (error.statusCode === 404) { throw new Error('Source item not found. Please verify the site, drive, and item IDs.'); } throw new Error(`Failed to initiate copy operation: ${error.message || 'Unknown error'}`); } const monitorUrl = initialResponse.headers.get('Location'); if (!monitorUrl) { throw new Error('Could not get monitor URL from copy operation response.'); } let attempts = polling_timeout_secs * 1000 / polling_delay_ms; while (attempts > 0) { const monitorResponse = await client.api(monitorUrl).get(); if (monitorResponse.status === 'completed') { return { success: true, status: 'completed', resourceId: monitorResponse.resourceId, resourceLocation: monitorResponse.resourceLocation, }; } if (monitorResponse.status === 'failed') { const errorDetails = monitorResponse.error?.details ? monitorResponse.error.details.map((d: any) => d.message || d.code).join(', ') : monitorResponse.error?.message || 'Unknown error'; throw new Error(`Copy operation failed: ${errorDetails}`); } await delay(polling_delay_ms); attempts--; } throw new Error('Copy operation timed out after 120 seconds.'); }, });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server