使用 EWS 托管 API 在一次调用中获取未读电子邮件并将其标记为已读

问题描述 投票:0回答:2

我有一个标准例程,从邮件服务器获取未读电子邮件,将其标记为已读,然后对其进行处理。它看起来类似于这个:

var view = new ItemView(1);
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
var findResults = ExchangeService.FindItems(WellKnownFolderName.Inbox, sf, view);

if (findResults.Items.Any())
{
    EmailMessage emailMsg = findResults.Items.First() as EmailMessage;
    emailMsg.IsRead = true;
    emailMsg.Update(ConflictResolutionMode.AutoResolve);

    ProcessMail(emailMsg);
}

这可以从各种进程调用,所以我需要确保“查找未读/标记为已读”操作的原子性。换句话说,在

Service.FindItems()
mail.Update()
之间,同一封电子邮件可能会被不同的进程读取两次,并导致重复处理。

现在,我不想参与有关存储已处理电子邮件 ID 或是否应该使用多个进程访问同一电子邮件服务器的讨论。

我想知道是否有一种 EWS API 方法可以在一次调用中执行这两个操作?理想情况下应该是这样的:

var mail = ExchangeService.GetFirstUnreadEmailAndMarkItAsRead()
exchangewebservices ews-managed-api
2个回答
1
投票

不,没有。 EWS GetItems 调用不会修改项目。


0
投票

下面是我实现此目的的 PowerShell 代码。我使用具有模拟权限的服务帐户在 Windows 任务计划程序中运行此程序。

首先,我有一个功能“Connect-EWS”——这主要归功于 Automativity.com

function Connect-EWS {
param(
    [parameter(Mandatory = $True)]
    [string]
    $DiscoverUrl        
)

# First import the DLL, else none of the EWS classes will be available

Try{
    Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
}
Catch{
    Write-Error "Error importing C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
    Write-Error $_.Exception
    Break
}

#Put your exchange version in here
$ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1

# Create the ExchangeService object
$ExchangeService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)

$ExchangeService.UseDefaultCredentials = $true 

#Autodiscover didnt work for me, but this is how you do it:
#$ExchangeService.AutodiscoverUrl($AutoDiscoverUrl, {$true})

$ExchangeService.Url = $DiscoverUrl

# Return the object
return $ExchangeService
}

这就是我使用该函数设置的:

Write-Host 'Mark Emails Read'
$ExchangeService = Connect-EWS -DiscoverUrl "https://exchangeserver.test.local/ews/exchange.asmx"

$impersonate = "[email protected]"
$ExchangeService.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $impersonate)

$ImpersonatedFolder = New-Object Microsoft.Exchange.WebServices.Data.FolderID([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot, $impersonate)
$folderView - New-Object Microsoft.Exchange.WebServices.Data.FolderView(100)
$findFolders = $ExchangeService.FindFolders($ImpersonatedFolder,$folderView)

foreach ($folder in $findFolders)
{
   Write-Host 'Unread Items: ' $folder.UnreadCount ' (' $folder.DisplayName ')'
   $folder.MarkAllItemsAsRead($true)
}

其输出是每个文件夹的未读项目计数的打印 - 然后立即将所有内容标记为已读。

© www.soinside.com 2019 - 2024. All rights reserved.