Извлечение сущности из сообщения электронной почты с помощью EWS в Exchange
Узнайте, как извлечь сведения из текста сообщения электронной почты с помощью управляемого API EWS или EWS в Exchange.
Управляемый API EWS или EWS можно использовать для доступа к адресам, контактам, адресам электронной почты, предложениям собраний, номерам телефонов, задачам и URL-адресам, извлекаемых сервером Exchange Server из сообщений электронной почты. Затем вы можете использовать эти сведения для новых приложений или предложить дальнейшие действия в существующих приложениях. Например, если в сообщении электронной почты указана сущность контакта, предложение собрания или предложение задачи, приложение может предложить создать новый элемент с предварительно заполненными сведениями. Используя извлеченные сущности, вы можете извлечь выгоду из намерения, лежащего в основе данных, и помочь пользователям легко интегрировать содержимое сообщения электронной почты в практические результаты.
Извлечение сущностей для адресов, контактов, адресов электронной почты, предложений собраний, номеров телефонов, задач и URL-адресов уже встроено в каждый элемент в хранилище Exchange. Если вы используете управляемый API EWS, свойство Item.EntityExtractionResult извлекает сущности для вас в вызове метода Item.Bind . Если вы используете EWS, элемент EntityExtractionResult получает все извлеченные сущности в вызове операции GetItem . После получения результатов извлеченных сущностей можно пройтись по каждой коллекции сущностей, чтобы собрать соответствующую информацию. Например, если предложение собрания было извлечено, можно получить рекомендуемую тему собрания, список участников, время начала и время окончания.
Таблица 1. Свойства управляемого API EWS и элементы EWS, содержащие извлеченные сущности
Извлеченная сущность | Свойство Управляемого API EWS | Элемент EWS |
---|---|---|
Addresses |
EntityExtractionResult.Addresses |
Addresses |
Контакты |
EntityExtractionResult.Contacts |
Контакты |
Адреса электронной почты |
EntityExtractionResult.EmailAddresses |
EmailAddresses |
Предложения о собрании |
EntityExtractionResult.MeetingSuggestions |
MeetingSuggestions |
Номера телефонов |
EntityExtractionResult.PhoneNumbers |
PhoneNumbers |
Рекомендации по задачам |
EntityExtractionResult.TaskSuggestions |
TaskSuggestions |
URL-адреса |
EntityExtractionResult.Urls |
Urls |
Так как извлечение сущностей зависит от распознавания естественного языка, распознавание сущностей может быть недетерминированным, а успех иногда зависит от контекста. Чтобы продемонстрировать, как работает распознавание естественного языка, в примерах в этой статье в качестве входных данных используется следующее сообщение электронной почты.
From: Ronnie Sturgis
To: Sadie Daniels
Subject: Dinner party
Hi Sadie
Are you free this Friday at 7 to join us for a dinner party at our house?
We're at 789 International Blvd, St Paul MN 55104.
Our number is 612-555-0158 if you have trouble finding it.
Please RSVP to either myself or Mara (mara@contoso.com) before Friday morning. Best for you organics (http://www.bestforyouorganics.com) will be catering so we can fully enjoy ourselves!
Also, can you forward this to Magdalena? I don't have her contact information.
See you then!
Ronnie
Извлечение всех сущностей из сообщения электронной почты с помощью управляемого API EWS
В следующем примере кода показано, как отобразить все сущности, извлеченные сервером, с помощью метода Item.Bind , а затем перечислить каждую из извлеченных сущностей и их свойства.
В этом примере предполагается, что служба является допустимым объектом ExchangeService , а ItemId — идентификатором сообщения электронной почты для перемещения или копирования.
public static void ExtractEntities(ExchangeService service, ItemId ItemId)
{
// Create a property set that limits the properties returned
// by the Bind method to only those that are required.
PropertySet propSet = new PropertySet(BasePropertySet.IdOnly, ItemSchema.EntityExtractionResult);
// Get the item from the server.
// This method call results in an GetItem call to EWS.
Item item = Item.Bind(service, ItemId, propSet);
Console.WriteLine("The following entities have been extracted from the message:");
Console.WriteLine(" ");
// If address entities are extracted from the message, print the results.
if (item.EntityExtractionResult != null)
{
if (item.EntityExtractionResult.Addresses != null)
{
Console.WriteLine("--------------------Addresses---------------------------");
foreach (AddressEntity address in item.EntityExtractionResult.Addresses)
{
Console.WriteLine("Address: {0}", address.Address);
}
Console.WriteLine(" ");
}
// If contact entities are extracted from the message, print the results.
if (item.EntityExtractionResult.Contacts != null)
{
Console.WriteLine("--------------------Contacts----------------------------");
foreach (ContactEntity contact in item.EntityExtractionResult.Contacts)
{
Console.WriteLine("Addresses: {0}", contact.Addresses);
Console.WriteLine("Business name: {0}", contact.BusinessName);
Console.WriteLine("Contact string: {0}", contact.ContactString);
Console.WriteLine("Email addresses: {0}", contact.EmailAddresses);
Console.WriteLine("Person name: {0}", contact.PersonName);
Console.WriteLine("Phone numbers: {0}", contact.PhoneNumbers);
Console.WriteLine("URLs: {0}", contact.Urls);
}
Console.WriteLine(" ");
}
// If email address entities are extracted from the message, print the results.
if (item.EntityExtractionResult.EmailAddresses != null)
{
Console.WriteLine("--------------------Email addresses---------------------");
foreach (EmailAddressEntity email in item.EntityExtractionResult.EmailAddresses)
{
Console.WriteLine("Email addresses: {0}", email.EmailAddress);
}
Console.WriteLine(" ");
}
// If meeting suggestion entities are extracted from the message, print the results.
if (item.EntityExtractionResult.MeetingSuggestions != null)
{
Console.WriteLine("--------------------Meeting suggestions-----------------");
foreach (MeetingSuggestion meetingSuggestion in item.EntityExtractionResult.MeetingSuggestions)
{
Console.WriteLine("Meeting subject: {0}", meetingSuggestion.Subject);
Console.WriteLine("Meeting string: {0}", meetingSuggestion.MeetingString);
foreach (EmailUserEntity attendee in meetingSuggestion.Attendees)
{
Console.WriteLine("Attendee name: {0}", attendee.Name);
Console.WriteLine("Attendee user ID: {0}", attendee.UserId);
}
Console.WriteLine("Start time: {0}", meetingSuggestion.StartTime);
Console.WriteLine("End time: {0}", meetingSuggestion.EndTime);
Console.WriteLine("Location: {0}", meetingSuggestion.Location);
}
Console.WriteLine(" ");
}
// If phone number entities are extracted from the message, print the results.
if (item.EntityExtractionResult.PhoneNumbers != null)
{
Console.WriteLine("--------------------Phone numbers-----------------------");
foreach (PhoneEntity phone in item.EntityExtractionResult.PhoneNumbers)
{
Console.WriteLine("Original phone string: {0}", phone.OriginalPhoneString);
Console.WriteLine("Phone string: {0}", phone.PhoneString);
Console.WriteLine("Type: {0}", phone.Type);
}
Console.WriteLine(" ");
}
// If task suggestion entities are extracted from the message, print the results.
if (item.EntityExtractionResult.TaskSuggestions != null)
{
Console.WriteLine("--------------------Task suggestions--------------------");
foreach (TaskSuggestion task in item.EntityExtractionResult.TaskSuggestions)
{
foreach (EmailUserEntity assignee in task.Assignees)
{
Console.WriteLine("Assignee name: {0}", assignee.Name);
Console.WriteLine("Assignee user ID: {0}", assignee.UserId);
}
Console.WriteLine("Task string: {0}", task.TaskString);
}
Console.WriteLine(" ");
}
// If URL entities are extracted from the message, print the results.
if (item.EntityExtractionResult.Urls != null)
{
Console.WriteLine("--------------------URLs--------------------------------");
foreach (UrlEntity url in item.EntityExtractionResult.Urls)
{
Console.WriteLine("URL: {0}", url.Url);
}
Console.WriteLine(" ");
}
}
// If no entities are extracted from the message, print the result.
else if (item.EntityExtractionResult == null)
{
Console.WriteLine("No entities extracted");
}
}
На консоли отображаются следующие выходные данные.
The following entities have been extracted from the message:
--------------------Addresses---------------------------
Address: 789 International Blvd, St Paul MN 55104
--------------------Contacts----------------------------
Addresses:
Business name:
Contact string: Mara (mara@contoso.com)
Email addresses: mara@contoso.com
Person name: Mara
Phone numbers:
URLs:
--------------------Email addresses---------------------
Email addresses: mara@contoso.com
--------------------Meeting suggestions-----------------
Meeting subject: dinner party
Meeting string: Are you free this Friday at 7 to join us for a dinner party at our house?
Attendee name: Ronnie Sturgis
Attendee user ID: ronnie@contoso.com
Attendee name: Sadie Daniels
Attendee user ID: sadie@cntoso.com
Start time: 10/1/0104 2:00:00 PM
End time: 10/1/0104 2:30:00 PM
Location:
--------------------Phone numbers-----------------------
Original phone string: 612-555-0158
Phone string: 6125550158
Type: Unspecified
--------------------Task suggestions--------------------
Assignee name: Sadie Daniels
Assignee user ID: sadie@contoso.com
Task string: Also, can you forward this to Magdalena?
--------------------URLs--------------------------------
URL: http://www.bestforyouorganics.com
Обратите внимание, что все адреса, контакты, адреса электронной почты, номера телефонов, задачи и URL-адреса были извлечены должным образом. Предложение собрания, однако, немного более сложное. Обратите внимание, что время начала и окончания предложения собрания не является ожидаемым. Время начала в сообщении электронной почты — "эта пятница в 7", но извлеченное значение для времени начала — 10.01.0104 14:00:00. Это связано с тем, что время начала и время окончания, извлеченные сервером, являются кодированными датами. Дополнительные сведения о том, как интерпретировать значения dateTime в предложениях собраний, см. в разделе [MS-OXCEXT]: Протокол объекта сообщения расширения клиента.
Извлечение всех сущностей из сообщения электронной почты с помощью EWS
В следующем примере кода показано, как использовать операцию GetItem и элемент EntityExtractionResult для получения извлеченных сущностей из элемента.
Это также XML-запрос, который отправляется управляемым API EWS при использовании метода Bind для извлечения всех сущностей из сообщения электронной почты с помощью управляемого API EWS.
Значение элемента ItemId укорочено для удобства чтения.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:RequestServerVersion Version="Exchange2013" />
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:FieldURI FieldURI="item:EntityExtractionResult" />
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
<t:ItemId Id="sVC5AAA=" />
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
Сервер отвечает на запрос GetItemсообщением GetItemResponse , которое содержит значение ResponseCodeNoError, указывающее, что сообщение электронной почты было успешно получено. Ответ также включает EntityExtractionResult для каждой извлеченной сущности.
Значение элемента ItemId укорочено для удобства чтения.
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="883"
MinorBuildNumber="10"
Version="V2_10"
xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="sVC5AAA="
ChangeKey="CQAAABYAAAD32nSTjepyT63rYH17n9THAAAOOqJN" />
<t:EntityExtractionResult>
<t:Addresses>
<t:AddressEntity>
<t:Position>LatestReply</t:Position>
<t:Address>789 International Blvd, St Paul MN 55104</t:Address>
</t:AddressEntity>
</t:Addresses>
<t:MeetingSuggestions>
<t:MeetingSuggestion>
<t:Position>LatestReply</t:Position>
<t:Attendees>
<t:EmailUser>
<t:Name>Ronnie Sturgis</t:Name>
<t:UserId>ronnie@contoso.com</t:UserId>
</t:EmailUser>
<t:EmailUser>
<t:Name>Sadie Daniels</t:Name>
<t:UserId>sadie@contoso.com</t:UserId>
</t:EmailUser>
</t:Attendees>
<t:Subject>dinner party</t:Subject>
<t:MeetingString>Are you free this Friday at 7 to join us for a dinner party at our house?</t:MeetingString>
<t:StartTime>0104-10-01T19:00:00Z</t:StartTime>
<t:EndTime>0104-10-01T19:30:00Z</t:EndTime>
</t:MeetingSuggestion>
</t:MeetingSuggestions>
<t:TaskSuggestions>
<t:TaskSuggestion>
<t:Position>LatestReply</t:Position>
<t:TaskString>Also, can you forward this to Magdalena?</t:TaskString>
<t:Assignees>
<t:EmailUser>
<t:Name>Sadie Daniels</t:Name>
<t:UserId>sadie@contoso.com</t:UserId>
</t:EmailUser>
</t:Assignees>
</t:TaskSuggestion>
</t:TaskSuggestions>
<t:EmailAddresses>
<t:EmailAddressEntity>
<t:Position>LatestReply</t:Position>
<t:EmailAddress>mara@contoso.com</t:EmailAddress>
</t:EmailAddressEntity>
</t:EmailAddresses>
<t:Contacts>
<t:Contact>
<t:Position>LatestReply</t:Position>
<t:PersonName>Mara</t:PersonName>
<t:EmailAddresses>
<t:EmailAddress>mara@contoso.com</t:EmailAddress>
</t:EmailAddresses>
<t:ContactString>Mara (mara@contoso.com</t:ContactString>
</t:Contact>
</t:Contacts>
<t:Urls>
<t:UrlEntity>
<t:Position>LatestReply</t:Position>
<t:Url>http://www.bestforyouorganics.com</t:Url>
</t:UrlEntity>
</t:Urls>
<t:PhoneNumbers>
<t:Phone>
<t:Position>LatestReply</t:Position>
<t:OriginalPhoneString>612-555-0158</t:OriginalPhoneString>
<t:PhoneString>6125550158</t:PhoneString>
<t:Type>Unspecified</t:Type>
</t:Phone>
</t:PhoneNumbers>
</t:EntityExtractionResult>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
Обратите внимание, что все адреса, контакты, адреса электронной почты, номера телефонов, задачи и URL-адреса были извлечены должным образом. Предложение собрания, однако, немного более сложное. Обратите внимание, что время начала и окончания предложения собрания не является ожидаемым. Время начала в сообщении электронной почты было "в эту пятницу в 7", но извлеченное значение для времени начала 10/01/0104 14:00:00. Это связано с тем, что время начала и время окончания, извлеченные сервером, являются кодированными датами. Дополнительные сведения об интерпретации значений dateTime в предложениях собраний см. в разделе [MS-OXCEXT]: Протокол объекта сообщений расширения клиента.