Skip to content

Commit 77cece9

Browse files
committed
fix(google-drive): expose the page token so pagination is reachable
list, search, list_comments, list_permissions and list_revisions each declared a hidden pageToken and forwarded it to Google, but the block had no subBlock of that name and never has — so every list was capped at one page and the nextPageToken output had nowhere to go. Adds a per-operation Page Token field mirroring the block's existing per-operation pageSize fields, collapses them onto the canonical pageToken in the params mapper, and flips the tool param to user-only so it is documented and settable.
1 parent 3604c23 commit 77cece9

9 files changed

Lines changed: 122 additions & 6 deletions

File tree

apps/docs/content/docs/en/integrations/google_drive.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ List files and folders in Google Drive with complete metadata
4646
| `folderId` | string | No | The ID of the folder to list files from \(internal use\) |
4747
| `query` | string | No | Search term to filter files by name \(e.g. "budget" finds files with "budget" in the name\). Do NOT use Google Drive query syntax here - just provide a plain search term. |
4848
| `pageSize` | number | No | The maximum number of files to return \(default: 100\) |
49+
| `pageToken` | string | No | The page token to use for pagination |
4950

5051
#### Output
5152

@@ -484,6 +485,7 @@ Search for files in Google Drive using advanced query syntax (e.g., fullText con
484485
| --------- | ---- | -------- | ----------- |
485486
| `query` | string | Yes | Google Drive query string using advanced search syntax \(e.g., "fullText contains 'budget'", "mimeType = 'application/pdf'", "modifiedTime > '2024-01-01'"\) |
486487
| `pageSize` | number | No | Maximum number of files to return \(default: 100\) |
488+
| `pageToken` | string | No | Token for fetching the next page of results |
487489

488490
#### Output
489491

@@ -671,6 +673,7 @@ List all permissions (who has access) for a file in Google Drive
671673
| Parameter | Type | Required | Description |
672674
| --------- | ---- | -------- | ----------- |
673675
| `fileId` | string | Yes | The ID of the file to list permissions for |
676+
| `pageToken` | string | No | The page token to use for pagination |
674677

675678
#### Output
676679

@@ -720,6 +723,7 @@ List the revision history of a file in Google Drive
720723
| --------- | ---- | -------- | ----------- |
721724
| `fileId` | string | Yes | The ID of the file to list revisions for |
722725
| `pageSize` | number | No | Maximum number of revisions to return \(1-1000, default 200\) |
726+
| `pageToken` | string | No | The page token to use for pagination |
723727

724728
#### Output
725729

@@ -779,6 +783,7 @@ List comments on a file in Google Drive
779783
| `includeDeleted` | boolean | No | Whether to include deleted comments \(their content is stripped\) |
780784
| `pageSize` | number | No | Maximum number of comments to return \(1-100, default 20\) |
781785
| `startModifiedTime` | string | No | Only return comments modified after this RFC 3339 timestamp |
786+
| `pageToken` | string | No | The page token to use for pagination |
782787

783788
#### Output
784789

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* @vitest-environment node
3+
*/
4+
import { describe, expect, it, vi } from 'vitest'
5+
6+
vi.mock('@/triggers', () => ({
7+
getTrigger: () => ({ subBlocks: [] }),
8+
}))
9+
10+
import { GoogleDriveBlock } from '@/blocks/blocks/google_drive'
11+
import { listTool } from '@/tools/google_drive/list'
12+
import { listCommentsTool } from '@/tools/google_drive/list_comments'
13+
import { listPermissionsTool } from '@/tools/google_drive/list_permissions'
14+
import { listRevisionsTool } from '@/tools/google_drive/list_revisions'
15+
import { searchTool } from '@/tools/google_drive/search'
16+
17+
const paginationCases = [
18+
{ operation: 'list', subBlockId: 'pageToken', tool: listTool },
19+
{ operation: 'search', subBlockId: 'searchPageToken', tool: searchTool },
20+
{ operation: 'list_permissions', subBlockId: 'permissionsPageToken', tool: listPermissionsTool },
21+
{ operation: 'list_revisions', subBlockId: 'revisionsPageToken', tool: listRevisionsTool },
22+
{ operation: 'list_comments', subBlockId: 'commentsPageToken', tool: listCommentsTool },
23+
] as const
24+
25+
describe('GoogleDriveBlock pagination', () => {
26+
const buildParams = GoogleDriveBlock.tools.config.params!
27+
28+
describe.each(paginationCases)('$operation', ({ operation, subBlockId, tool }) => {
29+
it('exposes a page token field scoped to the operation', () => {
30+
expect(GoogleDriveBlock.subBlocks.find(({ id }) => id === subBlockId)).toMatchObject({
31+
type: 'short-input',
32+
mode: 'advanced',
33+
condition: { field: 'operation', value: operation },
34+
})
35+
})
36+
37+
it('forwards the page token to the tool', () => {
38+
expect(
39+
buildParams({ operation, [subBlockId]: 'token-abc' }, undefined as never)
40+
).toMatchObject({ pageToken: 'token-abc' })
41+
})
42+
43+
it('declares pageToken as a user-settable tool param', () => {
44+
expect(tool.params.pageToken?.visibility).toBe('user-only')
45+
})
46+
})
47+
48+
it('does not leak a page token into operations that do not paginate', () => {
49+
expect(
50+
buildParams({ operation: 'get_file', pageToken: 'token-abc' }, undefined as never).pageToken
51+
).toBeUndefined()
52+
})
53+
54+
it('declares pageToken as a block input', () => {
55+
expect(GoogleDriveBlock.inputs.pageToken).toBeDefined()
56+
})
57+
})

apps/sim/blocks/blocks/google_drive.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,14 @@ Return ONLY the query string - no explanations, no quotes around the whole thing
463463
placeholder: 'Number of results (default: 100, max: 100)',
464464
condition: { field: 'operation', value: 'list' },
465465
},
466+
{
467+
id: 'pageToken',
468+
title: 'Page Token',
469+
type: 'short-input',
470+
placeholder: 'Token from a previous nextPageToken',
471+
mode: 'advanced',
472+
condition: { field: 'operation', value: 'list' },
473+
},
466474
// Download File Fields - File Selector (basic mode)
467475
{
468476
id: 'downloadFileSelector',
@@ -905,6 +913,14 @@ Return ONLY the message text - no subject line, no greetings/signatures, no extr
905913
condition: { field: 'operation', value: 'list_permissions' },
906914
required: true,
907915
},
916+
{
917+
id: 'permissionsPageToken',
918+
title: 'Page Token',
919+
type: 'short-input',
920+
placeholder: 'Token from a previous nextPageToken',
921+
mode: 'advanced',
922+
condition: { field: 'operation', value: 'list_permissions' },
923+
},
908924
// Get File Content Fields
909925
{
910926
id: 'getContentFileSelector',
@@ -1073,6 +1089,14 @@ Return ONLY the query string - no explanations, no quotes around the whole thing
10731089
mode: 'advanced',
10741090
condition: { field: 'operation', value: 'search' },
10751091
},
1092+
{
1093+
id: 'searchPageToken',
1094+
title: 'Page Token',
1095+
type: 'short-input',
1096+
placeholder: 'Token from a previous nextPageToken',
1097+
mode: 'advanced',
1098+
condition: { field: 'operation', value: 'search' },
1099+
},
10761100
// Untrash File Fields
10771101
{
10781102
id: 'untrashFileSelector',
@@ -1191,6 +1215,14 @@ Return ONLY the query string - no explanations, no quotes around the whole thing
11911215
mode: 'advanced',
11921216
condition: { field: 'operation', value: 'list_revisions' },
11931217
},
1218+
{
1219+
id: 'revisionsPageToken',
1220+
title: 'Page Token',
1221+
type: 'short-input',
1222+
placeholder: 'Token from a previous nextPageToken',
1223+
mode: 'advanced',
1224+
condition: { field: 'operation', value: 'list_revisions' },
1225+
},
11941226
{
11951227
id: 'getRevisionFileSelector',
11961228
title: 'Select File',
@@ -1255,6 +1287,14 @@ Return ONLY the query string - no explanations, no quotes around the whole thing
12551287
mode: 'advanced',
12561288
condition: { field: 'operation', value: 'list_comments' },
12571289
},
1290+
{
1291+
id: 'commentsPageToken',
1292+
title: 'Page Token',
1293+
type: 'short-input',
1294+
placeholder: 'Token from a previous nextPageToken',
1295+
mode: 'advanced',
1296+
condition: { field: 'operation', value: 'list_comments' },
1297+
},
12581298
{
12591299
id: 'includeDeleted',
12601300
title: 'Include Deleted Comments',
@@ -1473,6 +1513,11 @@ Return ONLY the comment text - no explanations, no quotes, no extra formatting.`
14731513
searchPageSize,
14741514
revisionsPageSize,
14751515
commentsPageSize,
1516+
pageToken,
1517+
searchPageToken,
1518+
permissionsPageToken,
1519+
revisionsPageToken,
1520+
commentsPageToken,
14761521
getContentExportMimeType,
14771522
exportMimeType,
14781523
...rest
@@ -1586,6 +1631,13 @@ Return ONLY the comment text - no explanations, no quotes, no extra formatting.`
15861631
else if (params.operation === 'list_revisions') effectivePageSize = revisionsPageSize
15871632
else if (params.operation === 'list_comments') effectivePageSize = commentsPageSize
15881633

1634+
let effectivePageToken: string | undefined = pageToken
1635+
if (params.operation === 'search') effectivePageToken = searchPageToken
1636+
else if (params.operation === 'list_permissions') effectivePageToken = permissionsPageToken
1637+
else if (params.operation === 'list_revisions') effectivePageToken = revisionsPageToken
1638+
else if (params.operation === 'list_comments') effectivePageToken = commentsPageToken
1639+
else if (params.operation !== 'list') effectivePageToken = undefined
1640+
15891641
const effectiveQuery = params.operation === 'search' ? searchQuery : query
15901642
const effectiveMimeType =
15911643
params.operation === 'get_content'
@@ -1603,6 +1655,7 @@ Return ONLY the comment text - no explanations, no quotes, no extra formatting.`
16031655
pageSize: effectivePageSize
16041656
? Number.parseInt(effectivePageSize as string, 10)
16051657
: undefined,
1658+
pageToken: effectivePageToken?.trim() || undefined,
16061659
query: effectiveQuery,
16071660
mimeType: effectiveMimeType === 'auto' ? undefined : effectiveMimeType,
16081661
type: shareType, // Map shareType to type for share tool
@@ -1660,6 +1713,7 @@ Return ONLY the comment text - no explanations, no quotes, no extra formatting.`
16601713
// List operation inputs
16611714
query: { type: 'string', description: 'Search query' },
16621715
pageSize: { type: 'number', description: 'Results per page' },
1716+
pageToken: { type: 'string', description: 'Pagination token from a previous nextPageToken' },
16631717
// Copy operation inputs
16641718
newName: { type: 'string', description: 'New name for copied file' },
16651719
// Update operation inputs

apps/sim/tools/generated/tool-metadata.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

apps/sim/tools/google_drive/list.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const listTool: ToolConfig<GoogleDriveToolParams, GoogleDriveListResponse
4848
pageToken: {
4949
type: 'string',
5050
required: false,
51-
visibility: 'hidden',
51+
visibility: 'user-only',
5252
description: 'The page token to use for pagination',
5353
},
5454
},

apps/sim/tools/google_drive/list_comments.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export const listCommentsTool: ToolConfig<
6565
pageToken: {
6666
type: 'string',
6767
required: false,
68-
visibility: 'hidden',
68+
visibility: 'user-only',
6969
description: 'The page token to use for pagination',
7070
},
7171
},

apps/sim/tools/google_drive/list_permissions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export const listPermissionsTool: ToolConfig<
4343
pageToken: {
4444
type: 'string',
4545
required: false,
46-
visibility: 'hidden',
46+
visibility: 'user-only',
4747
description: 'The page token to use for pagination',
4848
},
4949
},

apps/sim/tools/google_drive/list_revisions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export const listRevisionsTool: ToolConfig<
5151
pageToken: {
5252
type: 'string',
5353
required: false,
54-
visibility: 'hidden',
54+
visibility: 'user-only',
5555
description: 'The page token to use for pagination',
5656
},
5757
},

apps/sim/tools/google_drive/search.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export const searchTool: ToolConfig<GoogleDriveSearchParams, GoogleDriveSearchRe
5050
pageToken: {
5151
type: 'string',
5252
required: false,
53-
visibility: 'hidden',
53+
visibility: 'user-only',
5454
description: 'Token for fetching the next page of results',
5555
},
5656
},

0 commit comments

Comments
 (0)