Skip to content
Bitzsoft.Integrationsbitzsoft.integrations

Concept

Calendar 日历

日历统一抽象域完整手册——ICalendarService 7 方法、日历事件 CRUD/列表/接受与拒绝邀请、Google Bearer/API Key 与 Microsoft 365 Azure AD Bearer 两种鉴权模型。

Last updated

Calendar 域统一了日历服务的日程管理能力。Google Calendar 和 Microsoft 365(Outlook)两家供应商共享同一个 ICalendarService 接口,覆盖事件的创建、查询、更新、删除、列表,以及会议邀请的接受与拒绝。

域结构

Bitzsoft.Integrations.Calendar ← 抽象层
├── Bitzsoft.Integrations.Calendar.Google ← Google Calendar(Bearer/API Key)
├── Bitzsoft.Integrations.Calendar.Microsoft365 ← Microsoft 365(Azure AD Bearer → Graph)
└── Bitzsoft.Integrations.Calendar.All ← 聚合包

标准三层包模式。

统一接口(7 方法)

ICalendarService 围绕”日历事件(Event)“这一核心概念组织,共 7 个方法:

public interface ICalendarService
{
string ProviderName { get; }
// 事件 CRUD(4)
Task<CalendarEvent> CreateEventAsync(CreateEventRequest request, CancellationToken cancellationToken = default);
Task<CalendarEvent> GetEventAsync(string eventId, CancellationToken cancellationToken = default);
Task<CalendarEvent> UpdateEventAsync(string eventId, UpdateEventRequest request, CancellationToken cancellationToken = default);
Task DeleteEventAsync(string eventId, CancellationToken cancellationToken = default);
// 列表与邀请响应(3)
Task<List<CalendarEvent>> ListEventsAsync(ListEventsRequest request, CancellationToken cancellationToken = default);
Task AcceptInvitationAsync(string eventId, CancellationToken cancellationToken = default);
Task RejectInvitationAsync(string eventId, string? reason = null, CancellationToken cancellationToken = default);
}

查询类方法(Create / Get / Update / List)返回 CalendarEvent,操作类方法(Delete / Accept / Reject)为无返回 Task,失败抛 CalendarExceptionCalendarEvent 含开始/结束时间、时区、参会人、 organizer 等字段。

鉴权模型

两家供应商都走 OAuth2 体系,但凭证来源与 API 端点不同:

供应商鉴权机制Token 注入API 端点
GoogleOAuth2 Access Token 或 API KeyBearer 头或 ?key= query 参数Google Calendar API v3(www.googleapis.com/calendar/v3
Microsoft 365Azure AD Client CredentialsAuthorization: Bearer {token}Microsoft Graph /eventsgraph.microsoft.com/v1.0

供应商清单

供应商Provider IDAPI 基地址StabilityDI 方法
Googlegooglewww.googleapis.com/calendar/v3PreviewAddGoogleCalendar()
Microsoft 365microsoft-365graph.microsoft.com/v1.0PreviewAddMicrosoft365Calendar()

两家是国际主流的日历与协作平台。

注册

单厂商

// ① Google Calendar(OAuth2 Bearer 或 API Key)
builder.Services.AddGoogleCalendar(builder.Configuration.GetSection("Calendar:Google"));
// ② Microsoft 365(Azure AD Bearer → Graph /events)
builder.Services.AddMicrosoft365Calendar(builder.Configuration.GetSection("Calendar:Microsoft365"));

全量聚合

builder.Services.AddBitzsoftCalendarAll(builder.Configuration, "Calendar");

按配置节存在性自动注册,appsettings.json 只需写出启用的供应商:

{
"Calendar": {
"Google": {
"ClientId": "...",
"ClientSecret": "...",
"ApiKey": "..."
},
"Microsoft365": {
"TenantId": "...",
"ClientId": "...",
"ClientSecret": "...",
"DefaultUserPrincipalName": "scheduler@contoso.com"
}
}
}

消费

创建日程事件

public class ScheduleService(IIntegrationProviderResolver<ICalendarService> providers)
{
public async Task<CalendarEvent> BookAsync(string vendor, string subject, DateTimeOffset start, DateTimeOffset end, List<string> attendees)
{
var calendar = providers.GetRequired(vendor); // "google" / "microsoft-365"
return await calendar.CreateEventAsync(new CreateEventRequest
{
Subject = subject,
StartTime = start,
EndTime = end,
Attendees = attendees,
IsOnlineMeeting = true,
});
}
}

更新与删除

// 改时间
await calendar.UpdateEventAsync(eventId, new UpdateEventRequest
{
StartTime = newStart,
EndTime = newEnd,
});
// 取消事件
await calendar.DeleteEventAsync(eventId);

列表与邀请响应

// 查询某时间窗口内的事件
var events = await calendar.ListEventsAsync(new ListEventsRequest
{
TimeMin = DateTimeOffset.UtcNow,
TimeMax = DateTimeOffset.UtcNow.AddDays(7),
CalendarId = "primary",
});
// 接受/拒绝收到的会议邀请
await calendar.AcceptInvitationAsync(eventId);
await calendar.RejectInvitationAsync(eventId, reason: "时间冲突");

多厂商路由

public class CalendarRouter(IIntegrationProviderResolver<ICalendarService> providers)
{
public async Task<CalendarEvent> GetAsync(string source, string eventId)
{
var calendar = providers.GetRequired(source); // "google" / "microsoft-365"
return await calendar.GetEventAsync(eventId);
}
}

相关

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%