add-office365
Adds Office 365 Outlook by delegating to `/add-data-source` with `api-id=shared_office365` and action mode. Use when integrating Outlook mail/calendar.
- License 许可
- MIT
- 最近更新
- 2026-11-06
- Stars
- ★ 36
- Forks
- 11
01 前言 Front Matter
- name
- add-office365
- description
- Adds Office 365 Outlook by delegating to `/add-data-source` with `api-id=shared_office365` and action mode. Use when integrating Outlook mail/calendar.
- allowed-tools
- Read AskUserQuestion Skill
03 SKILL.md 正文
? Shared Instructions: shared-instructions.md — Cross-cutting concerns.
Add Office 365 Outlook (Wrapper)
This skill is a thin wrapper. Use /add-data-source as the single implementation path.
Delegation contract
Invoke /add-data-source with:
api-id:shared_office365mode:action
Office 365 Connector: Method Selection Guide
After the connector is added, you'll have access to Office365OutlookService with 20+ methods. Use this guide to select the right method for your use case.
Calendar Operations
For Fetching Events in a Date Range: GetEventsCalendarViewV2
Best for: Meeting lists, calendar views, event queries between two dates (e.g., "past 7 days", "next 30 days").
Key Parameters:
calendarId(string) — Always discover usingCalendarGetTables()firststartDateTimeOffset(ISO 8601 string) — Use.toISOString()endDateTimeOffset(ISO 8601 string) — Use.toISOString()top,skip(optional) — For pagination (200-1000 range typical)
Pattern:
import { Office365OutlookService } from '../../generated/services/Office365OutlookService'
// Step 1: Discover calendar ID (validate and prefer primary calendar)
const calendarsResult = await Office365OutlookService.CalendarGetTables()
if (!calendarsResult.success) {
throw new Error(calendarsResult.error?.message ?? 'Failed to list calendars')
}
const calendars = calendarsResult.data?.value ?? []
if (calendars.length === 0) {
throw new Error('No calendars found in Office 365 connection')
}
// Prefer primary 'calendar' (by DisplayName), fall back to first
const defaultCalendar =
calendars.find((c: any) => (c.DisplayName ?? '').toLowerCase() === 'calendar')
?? calendars[0]
const calendarId = defaultCalendar?.Name ?? calendars[0]?.Name
if (!calendarId) {
throw new Error('Could not determine calendar ID from response')
}
// Step 2: Query events with pagination
const eventsResult = await Office365OutlookService.GetEventsCalendarViewV2(
calendarId,
startDate.toISOString(),
endDate.toISOString(),
undefined, // filter (optional)
undefined, // select (optional)
200, // top - results per page
0 // skip - pagination offset
)
if (!eventsResult.success) {
throw new Error(eventsResult.error?.message ?? 'Failed to fetch events')
}
const meetings = eventsResult.data?.value ?? []
Response Structure:
- Array of
CalendarEventClientReceiveStringEnums(access via.data.value) - Contains:
Subject,Start,End,Id,Organizer,RequiredAttendees,OptionalAttendees
For Immediate Upcoming Events: OnUpcomingEventsV3
Best for: "Show me my next meeting" queries using a minutes-based time window.
Key Parameters:
table(string) — Calendar IDminutesWindow(number) — Time window in minutes (e.g., 60 for next hour, 1440 for next 24 hours)
For Creating Events: V3CalendarPostItem
Parameters:
table— Calendar IDitem—CalendarEventHtmlClientobject withSubject,Start,End(required)
For Updating Events: CalendarPatchItem
Parameters:
table— Calendar IDid— Event IDitem— Updated event properties
For Deleting Events: CalendarDeleteItem
Parameters:
table— Calendar IDid— Event ID
Discovery: CalendarGetTables
Purpose: List available calendars to discover correct calendar IDs (required before using other calendar methods)
Email Operations
For Sending Emails: SendEmailV2
Best for: Sending notifications, alerts, summaries.
Pattern:
const result = await Office365OutlookService.SendEmailV2({
To: 'recipient@example.com',
Subject: 'Meeting Summary',
Body: '<p>Here is your meeting summary...</p>',
Importance: 'Normal'
})
For Fetching Inbox: GetEmails
Parameters:
folderPath(string) — E.g., "Inbox", "Drafts"fetchOnlyUnread(boolean) — Filter for unread emailstop(number) — Limit
For Reading Single Email: GetEmail
Parameters:
messageId(string) — Email ID
For Marking as Read: MarkAsRead
Parameters:
messageId(string) — Email ID
For Replying to Email: ReplyToV3
Parameters:
messageId(string) — Email ID to reply tobody(string) — Reply text
Key Patterns
? Generic connector response handling: shared-instructions.md — Error handling, array access (.data.value), empty results, and response structure patterns apply to all connectors, including Office 365.
1. Always discover calendar ID first using CalendarGetTables()
This ensures you have the correct calendar ID for the user (don't hardcode "Calendar").
2. Use ISO date strings for date parameters
Use .toISOString() when passing dates to Office 365 methods.
3. Calendar ID Discovery - CRITICAL
⚠️ NEVER use hardcoded 'Calendar' as calendar ID. Always discover from the user's actual calendars.
// ❌ BROKEN - Will fail for users whose primary calendar isn't named 'Calendar'
const calendarId = 'Calendar'
// ✅ CORRECT - Discover actual calendar IDs
const calendarsResult = await Office365OutlookService.CalendarGetTables()
const calendars = calendarsResult.data?.value ?? []
// Validate calendars exist
if (calendars.length === 0) {
throw new Error('No calendars found')
}
// Prefer primary calendar by DisplayName, otherwise use first
const primaryCalendar =
calendars.find((c: any) => (c.DisplayName ?? '').toLowerCase() === 'calendar')
?? calendars[0]
// Extract the actual calendar ID from response
const calendarId = primaryCalendar?.Name
if (!calendarId) {
throw new Error('Could not extract calendar ID from Office 365 response')
}
Why this matters:
- Users may have multiple calendars (shared calendars, project calendars, etc.)
- The primary calendar's internal ID is not always the string
"Calendar" - Hardcoding causes failures for any user without a calendar literally named
"Calendar" - Must validate response contains valid data before proceeding
04 同仓库更多 Skills
state
Store and query a Microsoft Managed App's built-in state and file attachments with `ms project state` CLI schema commands and generated TypeScript clients. First, with the user signed in to the CLI, run `ms feature status --name state --json`; if `feature.enabled` is not `true`, recommend an alternative connector or data source.
share
Shares (or unshares) a Microsoft App with users via `ms app share` / `ms app unshare`. Use when updating app access control.
share-link
Manages tenant-wide share links for a Microsoft App via `ms app share link create`, `ms app share link list`, and `ms app share link revoke`. Use when you want to distribute app access via a URL instead of named principals.
play
Opens a Microsoft App in the browser via `ms app play`. Use when opening the live deployed version or a cloud-hosted preview (main branch or specific commit SHA) without starting a local dev server.
list-connectors
Lists connectors available in the active environment — including whether each is allowed or blocked by your organization's policy — plus the connection-bound data sources already wired into a Microsoft App. Use when discovering connectors and their operations before adding data sources.
list-apps
Discovers managed apps in the active environment via `ms app list --json` and optional `ms app show --json`. Use when listing or locating apps.