Skip to content

Commit d0b6945

Browse files
aadamgoughAdam Gough
andauthored
Improvement(sharepoint): added more operations in sharepoint (#1369)
* added list tools * not working yet * improved read and create * added scopes * updated sharepoint tools * added greptile comments --------- Co-authored-by: Adam Gough <[email protected]>
1 parent 6028b1f commit d0b6945

File tree

10 files changed

+909
-10
lines changed

10 files changed

+909
-10
lines changed

apps/docs/content/docs/en/tools/sharepoint.mdx

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Sharepoint
3-
description: Read and create pages
3+
description: Work with pages and lists
44
---
55

66
import { BlockInfoCard } from "@/components/ui/block-info-card"
@@ -61,7 +61,7 @@ In Sim, the SharePoint integration empowers your agents to create and access Sha
6161

6262
## Usage Instructions
6363

64-
Integrate Sharepoint into the workflow. Can read and create pages, and list sites. Requires OAuth.
64+
Integrate SharePoint into the workflow. Read/create pages, list sites, and work with lists (read, create, update items). Requires OAuth.
6565

6666

6767

@@ -124,6 +124,65 @@ List details of all SharePoint sites
124124
| --------- | ---- | ----------- |
125125
| `site` | object | Information about the current SharePoint site |
126126

127+
### `sharepoint_create_list`
128+
129+
Create a new list in a SharePoint site
130+
131+
#### Input
132+
133+
| Parameter | Type | Required | Description |
134+
| --------- | ---- | -------- | ----------- |
135+
| `siteId` | string | No | The ID of the SharePoint site \(internal use\) |
136+
| `siteSelector` | string | No | Select the SharePoint site |
137+
| `listDisplayName` | string | Yes | Display name of the list to create |
138+
| `listDescription` | string | No | Description of the list |
139+
| `listTemplate` | string | No | List template name \(e.g., 'genericList'\) |
140+
| `pageContent` | string | No | Optional JSON of columns. Either a top-level array of column definitions or an object with \{ columns: \[...\] \}. |
141+
142+
#### Output
143+
144+
| Parameter | Type | Description |
145+
| --------- | ---- | ----------- |
146+
| `list` | object | Created SharePoint list information |
147+
148+
### `sharepoint_get_list`
149+
150+
Get metadata (and optionally columns/items) for a SharePoint list
151+
152+
#### Input
153+
154+
| Parameter | Type | Required | Description |
155+
| --------- | ---- | -------- | ----------- |
156+
| `siteSelector` | string | No | Select the SharePoint site |
157+
| `siteId` | string | No | The ID of the SharePoint site \(internal use\) |
158+
| `listId` | string | No | The ID of the list to retrieve |
159+
160+
#### Output
161+
162+
| Parameter | Type | Description |
163+
| --------- | ---- | ----------- |
164+
| `list` | object | Information about the SharePoint list |
165+
166+
### `sharepoint_update_list`
167+
168+
Update the properties (fields) on a SharePoint list item
169+
170+
#### Input
171+
172+
| Parameter | Type | Required | Description |
173+
| --------- | ---- | -------- | ----------- |
174+
| `siteSelector` | string | No | Select the SharePoint site |
175+
| `siteId` | string | No | The ID of the SharePoint site \(internal use\) |
176+
| `listId` | string | No | The ID of the list containing the item |
177+
| `itemId` | string | Yes | The ID of the list item to update |
178+
| `listItemFields` | object | Yes | Field values to update on the list item |
179+
180+
#### Output
181+
182+
| Parameter | Type | Description |
183+
| --------- | ---- | ----------- |
184+
| `item` | object | Updated SharePoint list item |
185+
127186

128187

129188
## Notes

apps/sim/blocks/blocks/sharepoint.ts

Lines changed: 186 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { MicrosoftSharepointIcon } from '@/components/icons'
2+
import { createLogger } from '@/lib/logs/console/logger'
23
import type { BlockConfig } from '@/blocks/types'
34
import type { SharepointResponse } from '@/tools/sharepoint/types'
45

6+
const logger = createLogger('SharepointBlock')
7+
58
export const SharepointBlock: BlockConfig<SharepointResponse> = {
69
type: 'sharepoint',
710
name: 'Sharepoint',
8-
description: 'Read and create pages',
11+
description: 'Work with pages and lists',
912
longDescription:
10-
'Integrate Sharepoint into the workflow. Can read and create pages, and list sites. Requires OAuth.',
13+
'Integrate SharePoint into the workflow. Read/create pages, list sites, and work with lists (read, create, update items). Requires OAuth.',
1114
docsLink: 'https://docs.sim.ai/tools/sharepoint',
1215
category: 'tools',
1316
bgColor: '#E0E0E0',
@@ -23,6 +26,9 @@ export const SharepointBlock: BlockConfig<SharepointResponse> = {
2326
{ label: 'Create Page', id: 'create_page' },
2427
{ label: 'Read Page', id: 'read_page' },
2528
{ label: 'List Sites', id: 'list_sites' },
29+
{ label: 'Create List', id: 'create_list' },
30+
{ label: 'Read List', id: 'read_list' },
31+
{ label: 'Update List', id: 'update_list' },
2632
],
2733
},
2834
// Sharepoint Credentials
@@ -39,6 +45,8 @@ export const SharepointBlock: BlockConfig<SharepointResponse> = {
3945
'email',
4046
'Files.Read',
4147
'Files.ReadWrite',
48+
'Sites.Read.All',
49+
'Sites.ReadWrite.All',
4250
'offline_access',
4351
],
4452
placeholder: 'Select Microsoft account',
@@ -64,7 +72,17 @@ export const SharepointBlock: BlockConfig<SharepointResponse> = {
6472
placeholder: 'Select a site',
6573
dependsOn: ['credential'],
6674
mode: 'basic',
67-
condition: { field: 'operation', value: ['create_page', 'read_page', 'list_sites'] },
75+
condition: {
76+
field: 'operation',
77+
value: [
78+
'create_page',
79+
'read_page',
80+
'list_sites',
81+
'create_list',
82+
'read_list',
83+
'update_list',
84+
],
85+
},
6886
},
6987

7088
{
@@ -86,13 +104,59 @@ export const SharepointBlock: BlockConfig<SharepointResponse> = {
86104
mode: 'advanced',
87105
},
88106

107+
{
108+
id: 'listId',
109+
title: 'List ID',
110+
type: 'short-input',
111+
layout: 'full',
112+
placeholder: 'Enter list ID (GUID). Required for Update; optional for Read.',
113+
canonicalParamId: 'listId',
114+
condition: { field: 'operation', value: ['read_list', 'update_list'] },
115+
},
116+
117+
{
118+
id: 'listItemId',
119+
title: 'Item ID',
120+
type: 'short-input',
121+
layout: 'full',
122+
placeholder: 'Enter item ID',
123+
canonicalParamId: 'itemId',
124+
condition: { field: 'operation', value: ['update_list'] },
125+
},
126+
127+
{
128+
id: 'listDisplayName',
129+
title: 'List Display Name',
130+
type: 'short-input',
131+
layout: 'full',
132+
placeholder: 'Name of the list',
133+
condition: { field: 'operation', value: 'create_list' },
134+
},
135+
136+
{
137+
id: 'listTemplate',
138+
title: 'List Template',
139+
type: 'short-input',
140+
layout: 'full',
141+
placeholder: "Template (e.g., 'genericList')",
142+
condition: { field: 'operation', value: 'create_list' },
143+
},
144+
89145
{
90146
id: 'pageContent',
91147
title: 'Page Content',
92148
type: 'long-input',
93149
layout: 'full',
94-
placeholder: 'Content of the page',
95-
condition: { field: 'operation', value: 'create_page' },
150+
placeholder: 'Provide page content',
151+
condition: { field: 'operation', value: ['create_list'] },
152+
},
153+
{
154+
id: 'listDescription',
155+
title: 'List Description',
156+
type: 'long-input',
157+
layout: 'full',
158+
placeholder: 'Optional description',
159+
condition: { field: 'operation', value: 'create_list' },
96160
},
97161

98162
{
@@ -106,9 +170,26 @@ export const SharepointBlock: BlockConfig<SharepointResponse> = {
106170
mode: 'advanced',
107171
condition: { field: 'operation', value: 'create_page' },
108172
},
173+
174+
{
175+
id: 'listItemFields',
176+
title: 'List Item Fields',
177+
type: 'long-input',
178+
layout: 'full',
179+
placeholder: 'Enter list item fields',
180+
canonicalParamId: 'listItemFields',
181+
condition: { field: 'operation', value: 'update_list' },
182+
},
109183
],
110184
tools: {
111-
access: ['sharepoint_create_page', 'sharepoint_read_page', 'sharepoint_list_sites'],
185+
access: [
186+
'sharepoint_create_page',
187+
'sharepoint_read_page',
188+
'sharepoint_list_sites',
189+
'sharepoint_create_list',
190+
'sharepoint_get_list',
191+
'sharepoint_update_list',
192+
],
112193
config: {
113194
tool: (params) => {
114195
switch (params.operation) {
@@ -118,6 +199,12 @@ export const SharepointBlock: BlockConfig<SharepointResponse> = {
118199
return 'sharepoint_read_page'
119200
case 'list_sites':
120201
return 'sharepoint_list_sites'
202+
case 'create_list':
203+
return 'sharepoint_create_list'
204+
case 'read_list':
205+
return 'sharepoint_get_list'
206+
case 'update_list':
207+
return 'sharepoint_update_list'
121208
default:
122209
throw new Error(`Invalid Sharepoint operation: ${params.operation}`)
123210
}
@@ -128,12 +215,71 @@ export const SharepointBlock: BlockConfig<SharepointResponse> = {
128215
// Use siteSelector if provided, otherwise use manualSiteId
129216
const effectiveSiteId = (siteSelector || manualSiteId || '').trim()
130217

218+
const {
219+
itemId: providedItemId,
220+
listItemId,
221+
listItemFields,
222+
includeColumns,
223+
includeItems,
224+
...others
225+
} = rest as any
226+
227+
let parsedItemFields: any = listItemFields
228+
if (typeof listItemFields === 'string' && listItemFields.trim()) {
229+
try {
230+
parsedItemFields = JSON.parse(listItemFields)
231+
} catch (error) {
232+
logger.error('Failed to parse listItemFields JSON', {
233+
error: error instanceof Error ? error.message : String(error),
234+
})
235+
}
236+
}
237+
// Ensure listItemFields is an object for the tool schema
238+
if (typeof parsedItemFields !== 'object' || parsedItemFields === null) {
239+
parsedItemFields = undefined
240+
}
241+
242+
// Sanitize item ID (required by tool)
243+
const rawItemId = providedItemId ?? listItemId
244+
const sanitizedItemId =
245+
rawItemId === undefined || rawItemId === null
246+
? undefined
247+
: String(rawItemId).trim() || undefined
248+
249+
const coerceBoolean = (value: any) => {
250+
if (typeof value === 'boolean') return value
251+
if (typeof value === 'string') return value.toLowerCase() === 'true'
252+
return undefined
253+
}
254+
255+
// Debug logging for update_list param mapping
256+
if (others.operation === 'update_list') {
257+
try {
258+
logger.info('SharepointBlock update_list param check', {
259+
siteId: effectiveSiteId || undefined,
260+
listId: (others as any)?.listId,
261+
listTitle: (others as any)?.listTitle,
262+
itemId: sanitizedItemId,
263+
hasItemFields: !!parsedItemFields && typeof parsedItemFields === 'object',
264+
itemFieldKeys:
265+
parsedItemFields && typeof parsedItemFields === 'object'
266+
? Object.keys(parsedItemFields)
267+
: [],
268+
})
269+
} catch {}
270+
}
271+
131272
return {
132273
credential,
133274
siteId: effectiveSiteId || undefined,
134-
pageSize: rest.pageSize ? Number.parseInt(rest.pageSize as string, 10) : undefined,
275+
pageSize: others.pageSize ? Number.parseInt(others.pageSize as string, 10) : undefined,
135276
mimeType: mimeType,
136-
...rest,
277+
...others,
278+
// Map to tool param names
279+
itemId: sanitizedItemId,
280+
listItemFields: parsedItemFields,
281+
includeColumns: coerceBoolean(includeColumns),
282+
includeItems: coerceBoolean(includeItems),
137283
}
138284
},
139285
},
@@ -151,12 +297,44 @@ export const SharepointBlock: BlockConfig<SharepointResponse> = {
151297
siteSelector: { type: 'string', description: 'Site selector' },
152298
manualSiteId: { type: 'string', description: 'Manual site ID' },
153299
pageSize: { type: 'number', description: 'Results per page' },
300+
// Create List operation inputs
301+
listDisplayName: { type: 'string', description: 'List display name' },
302+
listDescription: { type: 'string', description: 'List description' },
303+
listTemplate: { type: 'string', description: 'List template' },
304+
// Read List operation inputs
305+
listId: { type: 'string', description: 'List ID' },
306+
listTitle: { type: 'string', description: 'List title' },
307+
includeColumns: { type: 'boolean', description: 'Include columns in response' },
308+
includeItems: { type: 'boolean', description: 'Include items in response' },
309+
// Update List Item operation inputs
310+
listItemId: { type: 'string', description: 'List item ID' },
311+
listItemFields: { type: 'string', description: 'List item fields' },
154312
},
155313
outputs: {
156314
sites: {
157315
type: 'json',
158316
description:
159317
'An array of SharePoint site objects, each containing details such as id, name, and more.',
160318
},
319+
list: {
320+
type: 'json',
321+
description: 'SharePoint list object (id, displayName, name, webUrl, etc.)',
322+
},
323+
item: {
324+
type: 'json',
325+
description: 'SharePoint list item with fields',
326+
},
327+
items: {
328+
type: 'json',
329+
description: 'Array of SharePoint list items with fields',
330+
},
331+
success: {
332+
type: 'boolean',
333+
description: 'Success status',
334+
},
335+
error: {
336+
type: 'string',
337+
description: 'Error message',
338+
},
161339
},
162340
}

apps/sim/lib/auth.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ export const auth = betterAuth({
565565
'email',
566566
'Sites.Read.All',
567567
'Sites.ReadWrite.All',
568+
'Sites.Manage.All',
568569
'offline_access',
569570
],
570571
responseType: 'code',

apps/sim/lib/oauth/oauth.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
260260
'email',
261261
'Sites.Read.All',
262262
'Sites.ReadWrite.All',
263+
'Sites.Manage.All',
263264
'offline_access',
264265
],
265266
},

0 commit comments

Comments
 (0)