视觉画布设计
canvas-design
基于设计原则创作静态视觉作品,用于海报与品牌图形。
sharepoint【文档与办公】Build integrations with SharePoint Online for document management, site automation, and intranet development. Use when someone asks to "integrate with SharePoint", "upload files to SharePoint", "manage SharePoint lists", "create SharePoint site", "automate SharePoint", "search SharePoint documents", "SharePoint API", or "SharePoint permissions". Cove…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
This skill helps AI agents integrate with SharePoint Online for document management, list operations, site automation, and custom development. It covers Microsoft Graph API for sites/lists/files, SharePoint REST API for advanced operations, search, permissions management, and SharePoint Framework (SPFx) for custom web parts.
import { ClientSecretCredential } from '@azure/identity';
import { Client } from '@microsoft/microsoft-graph-client';
import { TokenCredentialAuthenticationProvider } from '@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials';
// Permissions: Sites.ReadWrite.All, Files.ReadWrite.All, Lists.ReadWrite.All
const credential = new ClientSecretCredential(
process.env.AZURE_TENANT_ID, process.env.AZURE_CLIENT_ID, process.env.AZURE_CLIENT_SECRET
);
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
scopes: ['https://graph.microsoft.com/.default'],
});
const graphClient = Client.initWithMiddleware({ authProvider });
// Get site by URL
const site = await graphClient.api('/sites/contoso.sharepoint.com:/sites/engineering').get();
// Get document libraries (drives)
const drives = await graphClient.api(`/sites/${site.id}/drives`).get();
const driveId = drives.value[0].id;
// List folder contents
const items = await graphClient.api(`/drives/${driveId}/root/children`)
.select('id,name,size,lastModifiedDateTime,webUrl').get();
// Create folder
await graphClient.api(`/drives/${driveId}/root/children`).post({
name: 'New Project', folder: {}, '@microsoft.graph.conflictBehavior': 'rename',
});
// Upload small file (< 4MB)
await graphClient.api(`/drives/${driveId}/root:/Reports/monthly-report.pdf:/content`).putStream(fileContent);
// Upload large file (> 4MB) — resumable upload session
const session = await graphClient
.api(`/drives/${driveId}/root:/LargeFiles/dataset.csv:/createUploadSession`)
.post({ item: { '@microsoft.graph.conflictBehavior': 'replace', name: 'dataset.csv' } });
// Upload in 10MB chunks with Content-Range headers to session.uploadUrl
// Download, copy, move, delete
await graphClient.api(`/drives/${driveId}/items/${itemId}/content`).getStream();
await graphClient.api(`/drives/${driveId}/items/${itemId}/copy`).post({ parentReference: { driveId, path: '/root:/Archive' }, name: 'backup.pdf' });
await graphClient.api(`/drives/${driveId}/items/${itemId}`).patch({ parentReference: { id: targetFolderId } });
await graphClient.api(`/drives/${driveId}/items/${itemId}`).delete();
// Create sharing link
await graphClient.api(`/drives/${driveId}/items/${itemId}/createLink`).post({
type: 'view', scope: 'organization',
});
// Create a list
await graphClient.api(`/sites/${siteId}/lists`).post({
displayName: 'Project Tracker',
columns: [
{ name: 'ProjectName', text: {} },
{ name: 'Status', choice: { choices: ['Not Started', 'In Progress', 'Complete'] } },
{ name: 'DueDate', dateTime: {} },
{ name: 'Budget', currency: {} },
],
list: { template: 'genericList' },
});
// Get items with filter
const items = await graphClient.api(`/sites/${siteId}/lists/${listId}/items`)
.expand('fields($select=ProjectName,Status,DueDate)')
.filter("fields/Status eq 'In Progress'")
.orderby('fields/DueDate').get();
// Create / Update / Delete items
await graphClient.api(`/sites/${siteId}/lists/${listId}/items`).post({
fields: { ProjectName: 'Website Redesign', Status: 'In Progress', DueDate: '2026-04-01', Budget: 25000 },
});
await graphClient.api(`/sites/${siteId}/lists/${listId}/items/${itemId}/fields`).patch({ Status: 'Complete' });
await graphClient.api(`/sites/${siteId}/lists/${listId}/items/${itemId}`).delete();
// Bulk create (batch request)
const batchBody = {
requests: items.map((item, i) => ({
id: `${i}`, method: 'POST', url: `/sites/${siteId}/lists/${listId}/items`,
body: { fields: item }, headers: { 'Content-Type': 'application/json' },
})),
};
await graphClient.api('/$batch').post(batchBody);
// Search across all SharePoint content
const results = await graphClient.api('/search/query').post({
requests: [{
entityTypes: ['driveItem', 'listItem', 'site'],
query: { queryString: 'quarterly report 2026' },
from: 0, size: 25,
}],
});
// Search with filters (file type, author, site)
await graphClient.api('/search/query').post({
requests: [{ entityTypes: ['driveItem'], query: { queryString: 'filetype:pdf AND author:"John Smith"' } }],
});
// Subscribe to document library changes
const subscription = await graphClient.api('/subscriptions').post({
changeType: 'created,updated,deleted',
notificationUrl: 'https://your-app.com/api/sharepoint-webhook',
resource: `/drives/${driveId}/root`,
expirationDateTime: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000).toISOString(),
clientState: 'your-secret-token',
});
// Renew before expiry (max 3 days for SharePoint)
await graphClient.api(`/subscriptions/${subscription.id}`).patch({
expirationDateTime: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000).toISOString(),
});
User prompt: "Write a script that uploads a generated PDF report to our SharePoint Engineering site's Reports folder each month, creating the folder if it doesn't exist."
The agent will:
/sites/contoso.sharepoint.com:/sites/engineering/sites/{siteId}/drivesPOST /drives/{driveId}/root/childrenPUT /drives/{driveId}/root:/Reports/2026-02/monthly-report.pdf:/content) or a resumable upload session if the file exceeds 4MBUser prompt: "Create a SharePoint list called 'Project Tracker' with columns for project name, status, due date, and budget. Then add three sample projects and filter for in-progress items."
The agent will:
POST /sites/{siteId}/lists with text, choice, dateTime, and currency columnsPOST /sites/{siteId}/lists/{listId}/items with realistic data (e.g., "Website Redesign" at $25,000 In Progress).filter("fields/Status eq 'In Progress'") and .orderby('fields/DueDate')/$batch) — max 20 requests per batch$select and $expand to reduce payload size — don't fetch everything/drives/{id}/root/delta) for syncing — tracks changes since last checkfields object for values