Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/sim/app/api/tools/dropbox/upload/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
const dropboxApiArg = {
path: finalPath,
mode: validatedData.mode || 'add',
autorename: validatedData.autorename ?? true,
autorename: validatedData.autorename ?? false,
mute: validatedData.mute ?? false,
}

Expand Down
102 changes: 100 additions & 2 deletions apps/sim/blocks/blocks/dropbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ export const DropboxBlock: BlockConfig<DropboxResponse> = {
{ label: 'Move File/Folder', id: 'dropbox_move' },
{ label: 'Get Metadata', id: 'dropbox_get_metadata' },
{ label: 'Create Shared Link', id: 'dropbox_create_shared_link' },
{ label: 'List Shared Links', id: 'dropbox_list_shared_links' },
{ label: 'Search Files', id: 'dropbox_search' },
{ label: 'List Revisions', id: 'dropbox_list_revisions' },
{ label: 'Restore File', id: 'dropbox_restore' },
],
value: () => 'dropbox_upload',
},
Expand Down Expand Up @@ -299,6 +302,71 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: '100',
condition: { field: 'operation', value: 'dropbox_search' },
},
// List shared links operation inputs
{
id: 'path',
title: 'Path',
type: 'short-input',
placeholder: '/ (all links) or /folder',
condition: { field: 'operation', value: 'dropbox_list_shared_links' },
},
{
id: 'directOnly',
title: 'Direct Links Only',
type: 'switch',
condition: { field: 'operation', value: 'dropbox_list_shared_links' },
mode: 'advanced',
},
Comment thread
waleedlatif1 marked this conversation as resolved.
{
id: 'cursor',
title: 'Cursor',
type: 'short-input',
placeholder: 'Cursor from a previous call, to fetch the next page',
condition: { field: 'operation', value: 'dropbox_list_shared_links' },
mode: 'advanced',
},
// List revisions operation inputs
{
id: 'path',
title: 'File Path',
type: 'short-input',
placeholder: '/folder/document.pdf',
condition: { field: 'operation', value: 'dropbox_list_revisions' },
required: true,
},
{
id: 'limit',
title: 'Maximum Revisions',
type: 'short-input',
placeholder: '10',
condition: { field: 'operation', value: 'dropbox_list_revisions' },
mode: 'advanced',
},
{
id: 'beforeRev',
title: 'Before Revision',
type: 'short-input',
placeholder: 'Revision from a previous call, to fetch the next page',
condition: { field: 'operation', value: 'dropbox_list_revisions' },
mode: 'advanced',
},
// Restore operation inputs
{
id: 'path',
title: 'File Path',
type: 'short-input',
placeholder: '/folder/document.pdf',
condition: { field: 'operation', value: 'dropbox_restore' },
required: true,
},
{
id: 'rev',
title: 'Revision',
type: 'short-input',
placeholder: 'a1c10ce0dd78',
condition: { field: 'operation', value: 'dropbox_restore' },
required: true,
},
],
tools: {
access: [
Expand All @@ -311,7 +379,10 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
'dropbox_move',
'dropbox_get_metadata',
'dropbox_create_shared_link',
'dropbox_list_shared_links',
'dropbox_search',
'dropbox_list_revisions',
'dropbox_restore',
],
config: {
tool: (params) => {
Expand All @@ -334,8 +405,14 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
return 'dropbox_get_metadata'
case 'dropbox_create_shared_link':
return 'dropbox_create_shared_link'
case 'dropbox_list_shared_links':
return 'dropbox_list_shared_links'
case 'dropbox_search':
return 'dropbox_search'
case 'dropbox_list_revisions':
return 'dropbox_list_revisions'
case 'dropbox_restore':
return 'dropbox_restore'
default:
return 'dropbox_upload'
}
Expand Down Expand Up @@ -379,14 +456,24 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
query: { type: 'string', description: 'Search query' },
fileExtensions: { type: 'string', description: 'File extensions filter' },
maxResults: { type: 'number', description: 'Maximum search results' },
// List shared links inputs
directOnly: { type: 'boolean', description: 'Only return direct links, not parent folders' },
cursor: { type: 'string', description: 'Fetch the next page of shared links (pagination)' },
// List revisions input
beforeRev: { type: 'string', description: 'Fetch revisions before this one (pagination)' },
// Restore input
rev: { type: 'string', description: 'Revision identifier to restore' },
},
outputs: {
// Upload/Download outputs
file: { type: 'file', description: 'Downloaded file stored in execution files' },
content: { type: 'string', description: 'File content (base64)' },
temporaryLink: { type: 'string', description: 'Temporary download link' },
// List folder outputs
entries: { type: 'json', description: 'List of files and folders' },
// List folder / List revisions outputs
entries: {
type: 'json',
description: 'List of files and folders (List Folder), or file revisions (List Revisions)',
},
cursor: { type: 'string', description: 'Pagination cursor' },
hasMore: { type: 'boolean', description: 'Whether more results exist' },
// Create folder output
Expand All @@ -399,6 +486,10 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
sharedLink: { type: 'json', description: 'Shared link details' },
// Search outputs
matches: { type: 'json', description: 'Search results' },
// List shared links outputs
links: { type: 'json', description: 'List of shared links (url, name, path_lower, expires)' },
// List revisions output
isDeleted: { type: 'boolean', description: 'Whether the latest revision is deleted or moved' },
},
}

Expand Down Expand Up @@ -501,5 +592,12 @@ export const DropboxBlockMeta = {
content:
'# Share Dropbox Link\n\nGenerate a shareable link for an existing Dropbox item with the right access controls.\n\n## Steps\n1. Confirm the exact path of the file or folder. Use Get Metadata to verify it exists.\n2. Call Create Shared Link with the path and the requested visibility — public for anyone, team-only for internal sharing, or password-protected with a supplied password.\n3. Set an expiration date if the link should not be permanent.\n\n## Output\nReturn the shared link URL, its visibility setting, and the expiration date if one was applied.',
},
{
name: 'recover-dropbox-file-version',
description:
'Recover an earlier version of a Dropbox file after an unwanted overwrite or edit.',
content:
'# Recover Dropbox File Version\n\nRoll a file back to an earlier saved revision.\n\n## Steps\n1. Call List Revisions on the file path to see prior versions, each with a revision identifier and modification time.\n2. Identify the revision to recover based on its timestamp or size.\n3. Call Restore File with the file path and the chosen revision identifier. This saves that revision as the new current version — it does not delete history.\n\n## Output\nReturn the restored file metadata, including its path and the revision that was restored.',
},
],
} as const satisfies BlockMeta
10 changes: 5 additions & 5 deletions apps/sim/tools/dropbox/copy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ export const dropboxCopyTool: ToolConfig<DropboxCopyParams, DropboxCopyResponse>
}
},
body: (params) => ({
from_path: params.fromPath,
to_path: params.toPath,
from_path: params.fromPath.trim(),
to_path: params.toPath.trim(),
autorename: params.autorename ?? false,
}),
},
Expand Down Expand Up @@ -77,10 +77,10 @@ export const dropboxCopyTool: ToolConfig<DropboxCopyParams, DropboxCopyResponse>
description: 'Metadata of the copied item',
properties: {
'.tag': { type: 'string', description: 'Type: file or folder' },
id: { type: 'string', description: 'Unique identifier' },
id: { type: 'string', description: 'Unique identifier', optional: true },
name: { type: 'string', description: 'Name of the copied item' },
path_display: { type: 'string', description: 'Display path' },
size: { type: 'number', description: 'Size in bytes (files only)' },
path_display: { type: 'string', description: 'Display path', optional: true },
size: { type: 'number', description: 'Size in bytes (files only)', optional: true },
},
},
},
Expand Down
6 changes: 3 additions & 3 deletions apps/sim/tools/dropbox/create_folder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const dropboxCreateFolderTool: ToolConfig<
}
},
body: (params) => ({
path: params.path,
path: params.path.trim(),
autorename: params.autorename ?? false,
}),
},
Expand Down Expand Up @@ -74,8 +74,8 @@ export const dropboxCreateFolderTool: ToolConfig<
properties: {
id: { type: 'string', description: 'Unique identifier for the folder' },
name: { type: 'string', description: 'Name of the folder' },
path_display: { type: 'string', description: 'Display path of the folder' },
path_lower: { type: 'string', description: 'Lowercase path of the folder' },
path_display: { type: 'string', description: 'Display path of the folder', optional: true },
path_lower: { type: 'string', description: 'Lowercase path of the folder', optional: true },
},
},
},
Expand Down
26 changes: 21 additions & 5 deletions apps/sim/tools/dropbox/create_shared_link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const dropboxCreateSharedLinkTool: ToolConfig<
},
body: (params) => {
const body: Record<string, any> = {
path: params.path,
path: params.path.trim(),
}

const settings: Record<string, any> = {}
Expand Down Expand Up @@ -88,12 +88,24 @@ export const dropboxCreateSharedLinkTool: ToolConfig<
const data = await response.json()

if (!response.ok) {
// Check if a shared link already exists
// A link may already exist for this path - Dropbox includes its metadata in the error
// when the requested settings match the existing link, so surface it as a success.
// Per Stone's JSON rules, a union member whose payload is a struct (SharedLinkMetadata)
// flattens that struct's fields alongside ".tag" - there is no nested "metadata" key.
const existingLink = data.error?.shared_link_already_exists
if (existingLink) {
return {
success: true,
output: {
sharedLink: existingLink,
},
}
}
Comment thread
waleedlatif1 marked this conversation as resolved.
if (data.error_summary?.includes('shared_link_already_exists')) {
return {
success: false,
error:
'A shared link already exists for this path. Use list_shared_links to get the existing link.',
'A shared link already exists for this path with different settings. Use Dropbox List Shared Links to retrieve it.',
output: {},
}
}
Expand All @@ -119,8 +131,12 @@ export const dropboxCreateSharedLinkTool: ToolConfig<
properties: {
url: { type: 'string', description: 'The shared link URL' },
name: { type: 'string', description: 'Name of the shared item' },
path_lower: { type: 'string', description: 'Lowercase path of the shared item' },
expires: { type: 'string', description: 'Expiration date if set' },
path_lower: {
type: 'string',
description: 'Lowercase path of the shared item',
optional: true,
},
expires: { type: 'string', description: 'Expiration date if set', optional: true },
link_permissions: {
type: 'object',
description: 'Permissions for the shared link',
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/tools/dropbox/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const dropboxDeleteTool: ToolConfig<DropboxDeleteParams, DropboxDeleteRes
}
},
body: (params) => ({
path: params.path,
path: params.path.trim(),
}),
},

Expand Down Expand Up @@ -65,7 +65,7 @@ export const dropboxDeleteTool: ToolConfig<DropboxDeleteParams, DropboxDeleteRes
properties: {
'.tag': { type: 'string', description: 'Type: file, folder, or deleted' },
name: { type: 'string', description: 'Name of the deleted item' },
path_display: { type: 'string', description: 'Display path' },
path_display: { type: 'string', description: 'Display path', optional: true },
},
},
deleted: {
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/tools/dropbox/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const dropboxDownloadTool: ToolConfig<DropboxDownloadParams, DropboxDownl
return {
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/octet-stream',
'Dropbox-API-Arg': httpHeaderSafeJson({ path: params.path }),
'Dropbox-API-Arg': httpHeaderSafeJson({ path: params.path.trim() }),
}
},
},
Expand Down Expand Up @@ -64,7 +64,7 @@ export const dropboxDownloadTool: ToolConfig<DropboxDownloadParams, DropboxDownl
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ path: params.path }),
body: JSON.stringify({ path: params.path.trim() }),
})
if (linkResponse.ok) {
const linkData = await linkResponse.json()
Expand Down
30 changes: 21 additions & 9 deletions apps/sim/tools/dropbox/get_metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const dropboxGetMetadataTool: ToolConfig<
}
},
body: (params) => ({
path: params.path,
path: params.path.trim(),
include_media_info: params.includeMediaInfo ?? false,
include_deleted: params.includeDeleted ?? false,
}),
Expand Down Expand Up @@ -80,15 +80,27 @@ export const dropboxGetMetadataTool: ToolConfig<
description: 'Metadata for the file or folder',
properties: {
'.tag': { type: 'string', description: 'Type: file, folder, or deleted' },
id: { type: 'string', description: 'Unique identifier' },
id: { type: 'string', description: 'Unique identifier', optional: true },
name: { type: 'string', description: 'Name of the item' },
path_display: { type: 'string', description: 'Display path' },
path_lower: { type: 'string', description: 'Lowercase path' },
size: { type: 'number', description: 'Size in bytes (files only)' },
client_modified: { type: 'string', description: 'Client modification time' },
server_modified: { type: 'string', description: 'Server modification time' },
rev: { type: 'string', description: 'Revision identifier' },
content_hash: { type: 'string', description: 'Content hash' },
path_display: { type: 'string', description: 'Display path', optional: true },
path_lower: { type: 'string', description: 'Lowercase path', optional: true },
size: { type: 'number', description: 'Size in bytes (files only)', optional: true },
client_modified: {
type: 'string',
description: 'Client modification time (files only)',
optional: true,
},
server_modified: {
type: 'string',
description: 'Server modification time (files only)',
optional: true,
},
rev: { type: 'string', description: 'Revision identifier (files only)', optional: true },
content_hash: {
type: 'string',
description: 'Content hash (files only)',
optional: true,
},
},
},
},
Expand Down
6 changes: 6 additions & 0 deletions apps/sim/tools/dropbox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { dropboxDeleteTool } from '@/tools/dropbox/delete'
import { dropboxDownloadTool } from '@/tools/dropbox/download'
import { dropboxGetMetadataTool } from '@/tools/dropbox/get_metadata'
import { dropboxListFolderTool } from '@/tools/dropbox/list_folder'
import { dropboxListRevisionsTool } from '@/tools/dropbox/list_revisions'
import { dropboxListSharedLinksTool } from '@/tools/dropbox/list_shared_links'
import { dropboxMoveTool } from '@/tools/dropbox/move'
import { dropboxRestoreTool } from '@/tools/dropbox/restore'
import { dropboxSearchTool } from '@/tools/dropbox/search'
import { dropboxUploadTool } from '@/tools/dropbox/upload'

Expand All @@ -17,7 +20,10 @@ export {
dropboxDownloadTool,
dropboxGetMetadataTool,
dropboxListFolderTool,
dropboxListRevisionsTool,
dropboxListSharedLinksTool,
dropboxMoveTool,
dropboxRestoreTool,
dropboxSearchTool,
dropboxUploadTool,
}
8 changes: 4 additions & 4 deletions apps/sim/tools/dropbox/list_folder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const dropboxListFolderTool: ToolConfig<DropboxListFolderParams, DropboxL
}
},
body: (params) => ({
path: params.path === '/' ? '' : params.path,
path: params.path.trim() === '/' ? '' : params.path.trim(),
recursive: params.recursive ?? false,
include_deleted: params.includeDeleted ?? false,
include_media_info: params.includeMediaInfo ?? false,
Expand Down Expand Up @@ -96,10 +96,10 @@ export const dropboxListFolderTool: ToolConfig<DropboxListFolderParams, DropboxL
type: 'object',
properties: {
'.tag': { type: 'string', description: 'Type: file, folder, or deleted' },
id: { type: 'string', description: 'Unique identifier' },
id: { type: 'string', description: 'Unique identifier', optional: true },
name: { type: 'string', description: 'Name of the file/folder' },
path_display: { type: 'string', description: 'Display path' },
size: { type: 'number', description: 'Size in bytes (files only)' },
path_display: { type: 'string', description: 'Display path', optional: true },
size: { type: 'number', description: 'Size in bytes (files only)', optional: true },
},
},
},
Expand Down
Loading
Loading