使用 Pywin32 获取 Outlook 组日历 (win32com.client)

Get Outlook Group Calendars using Pywin32 (win32com.client)

我想知道如何访问我所属的不同 Outlook 组的日历。我正在使用 win32com 和 Python 3.9 来完成这项任务,并且宁愿避免使用 RESTful/auth 令牌路由,因为对于应该是一个简单的脚本插入一个几个日历约会。

我可以使用以下代码获得自己的约会:

import win32com.client

application = win32com.client.Dispatch('Outlook.Application')
namespace = application.GetNamespace('MAPI')

cal = namespace.GetDefaultFolder(9)
    
for item in cal.Items:
    print(item.Subject)

返回我个人日历中每个约会的主题行。

我也可以使用 GetSharedDefaultFolder 获得相同的信息:

application = win32com.client.Dispatch('Outlook.Application')
namespace = application.GetNamespace('MAPI')

recipient = namespace.createRecipient("{my_email}")
resolved = recipient.Resolve()

sharedCalendar = namespace.GetSharedDefaultFolder(recipient, 9)

for item in sharedCalendar.Items:
    print(item.Subject)

我了解到您想将创建所需日历的人的 email/user 作为收件人,但我没有成功。

在尝试使用创建者的电子邮件时,出现以下错误:

pywintypes.com_error: (-2147352567, 'Exception occurred.', (4096, 'Microsoft Outlook', 'The operation failed because of a registry or installation problem. Restart Outlook and try again. If the problem persists, reinstall.', None, 0, -2147221219), None)

如果我尝试使用他们的 (lastName, firstName),我会得到以下信息:

pywintypes.com_error: (-2009857777, 'OLE error 0x8834010f', None, None)

请注意,我指的是 GROUP 日历,而不是共享日历。我不确定这两者之间是否真的有区别,但对我来说它们在 Outlook 中显示为不同的部分。

我一直在参考的一些参考资料(对于找到此页面并遇到此问题的其他人):
Read Outlook Events via Python
https://docs.microsoft.com/en-us/office/vba/api/outlook.namespace.getdefaultfolder(及相关页面)
Problem with read Outlook shared calendar via python
https://docs.microsoft.com/en-us/answers/questions/607061/how-to-create-new-events-share-calendar-with-pytho.html

NameSpace.GetSharedDefaultFolder 方法用于委托方案,其中一个用户已将访问权限委托给另一个用户一个或多个默认文件夹(例如,他们的共享日历文件夹)。因此,您需要确保用户被授权访问您。

如果日历在 Outlook 的导航窗格中可见,您可以使用 NavigationGroups 对象访问它。您可以使用 NavigationGroupsNavigationFolders 集合遍历导航窗格中模块的组和文件夹层次结构。 NavigationModule 对象的 NavigationGroups 集合包含导航模块中显示的每个导航组,而 NavigationGroup 对象的 NavigationFolders 集合包含导航组中显示的每个导航文件夹.通过结合使用这些集合,您可以为导航窗格中显示的导航模块枚举每个导航文件夹。这是示例 VBA 代码,您可以在其中了解获取所需日历所需的 OOM 属性方法:

Dim WithEvents objPane As NavigationPane 
 
Private Sub EnumerateActiveCalendarFolders() 
 Dim objModule As CalendarModule 
 Dim objGroup As NavigationGroup 
 Dim objFolder As NavigationFolder 
 Dim intCounter As Integer 
 
 On Error GoTo ErrRoutine 
 
 ' Get the NavigationPane object for the 
 ' currently displayed Explorer object. 
 Set objPane = Application.ActiveExplorer.NavigationPane 
 
 ' Get the CalendarModule object, if one exists, 
 ' for the current Navigation Pane. 
 Set objModule = objPane.Modules.GetNavigationModule(olModuleCalendar) 
 
 ' Iterate through each NavigationGroup contained 
 ' by the CalendarModule. 
 For Each objGroup In objModule.NavigationGroups 
 ' Iterate through each NavigationFolder contained 
 ' by the NavigationGroup. 
 For Each objFolder In objGroup.NavigationFolders 
 ' Check if the folder is selected. 
 If objFolder.IsSelected Then 
 intCounter = intCounter + 1 
 End If 
 Next 
 Next 
 
 ' Display the results. 
 MsgBox "There are " & intCounter & " selected calendars in the Calendar module." 
 
EndRoutine: 
 On Error GoTo 0 
 Set objFolder = Nothing 
 Set objGroup = Nothing 
 Set objModule = Nothing 
 Set objPane = Nothing 
 intCounter = 0 
 Exit Sub 
 
ErrRoutine: 
 MsgBox Err.Number & " - " & Err.Description, _ 
 vbOKOnly Or vbCritical, _ 
 "EnumerateActiveCalendarFolders" 
End Sub

Outlook 对象模型对于所有类型的编程语言都是通用的,因此识别完成工作所需的属性和方法的顺序并不需要太多努力。