CODE-C# 程式讀取 Exchange 共用行事曆
5 |
工作遇到新需求:辦公室自動化服務希望讀取使用者行事曆,整合顯示於個人資訊頁。
EWS Managed API 封裝了複雜又囉嗦的 Exchange Web Service SOAP 細節,改以 .NET 程式庫形式提供電子郵件、連絡人、行事曆、公用資料夾的存取管道,是 C# 開發 Exchange 相關程式的首選。(意外發現 EWS Managed API 從 2014 起轉為 Github 開源專案,有原始碼在手,搞不懂走不通都有救,用起來格外讓人放心,微軟真的愈來愈開放)
官方文件有篇詳細介紹文,示範如何使用 EWS Mananged API 查詢行事曆取得個人約會資訊。基本原理是利用 CalendarFolder.Bind() 連上個人行事曆,接著建立一個 CalendarView 指定查詢期間、取回筆數,CalendarView.PropertySet 則傳入要讀取的欄位(主旨、開始/結束時間… 等),接著呼叫 CalendarFolder.FindAppointments() 就取得 Appointment 的集合,很簡單,這部分可直接參考官方範例。好消息是 EWS Managed API 用 NuGet 就可以下載:
不過我的需求多了一些變化,系統會使用統一中間程式查詢不同使用者的行事曆,而我們不可能為此要使用者交出 AD 帳號密碼。因此,透過行事曆共用是較可行做法。
行事曆共用可使用 Outlook 操作, 找到自己的行事曆(一般會有兩份,要選名稱有個人郵件地址位於 Exchange Server 的那一份),右鍵選單開啟內容:
程式使用 EWS Managed API 會以特定 AD 帳號執行(測試時可用開發者自己的帳號,正式營運則會申請專用帳號),要開放行事曆供程式存取,使用者必須授與該帳號讀取權限,授權完成可使用 Outlook 檢查是否看到測試對象的約會做為驗證。但有一點要留意,除了授權讀取空閒/忙碌時間、主旨、地點外,其他區域有個「可看到資料夾」一定要勾選。未勾選時 Oulook 可查看共享行事曆,但 EWS Managed API 不行,我花了不少時間才發現這個眉角。
若要求省事,也可請共用行事曆的使用者直接選取「權限等級:檢閱者」;若使用者很介意約會細節外流,只想透露主旨、地點,甚至只打算開放/空閒忙碌資訊,只勾選自己想開放範圍也成,但記得一定要勾選「可看到資料夾」,不然程式沒戲唱:
程式範例如下。查詢他人行事曆時,有個關鍵是使用 new FolderId(WellKnownFloderName.Calendar, "對方的Email") 取得資料夾代號,若對方未授與「可看到資料夾」權限,程式會在 FindAppointments 時噴出找不到資料夾的錯誤。
private static void QuerySharedCalender()
{
var ewsUrl = "https://the-exchange-server/ews/Exchange.asmx";
ExchangeService ews = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
ews.Credentials = new WebCredentials(userId, pwd, domainName);
ews.Url = new Uri(ewsUrl);
FolderId folderToAccess =
new FolderId(WellKnownFolderName.Calendar, "someone@company.com");
//指定日期區間與資料筆數
var view = new CalendarView(
new DateTime(2017, 12, 10),
new DateTime(2017, 12, 17),
1024);
view.PropertySet = new PropertySet(
AppointmentSchema.Subject,
AppointmentSchema.Start,
AppointmentSchema.End);
FindItemsResults<Appointment> apps = ews.FindAppointments(folderToAccess, view);
foreach (var app in apps)
{
Console.WriteLine(
$"{app.Start:MM-dd HH:mm} - {app.End:MM-dd HH:mm} {app.Subject}");
}
}
假設行事曆如下:
測試成功!
Comments
# by Hikaru Chiu
感謝黑暗大大。 請問目前仍然是使用EWS嗎? 假如我只是一般在hotmail免費信箱,也可以讀取得到行事曆嗎?
# by Jeffrey
to Hikaru Chiu, Hotmail 併入 Outlook.com 了 ( https://zh.wikipedia.org/wiki/Outlook.com ),程式存取的官方建議是用 Outlook REST API https://docs.microsoft.com/en-us/outlook/rest/get-started
# by Hikaru Chiu
好的,謝謝黑暗大大,我會去研究看看
# by Miles
請問大大。這個 API 可以寫入資料嘛?
# by Jeffrey
to Miles, EWS 支援寫入資料,但現今的主流會建議用 Microsoft Graph (REST API) https://docs.microsoft.com/en-us/graph/outlook-create-event-in-shared-delegated-calendar?tabs=http