Поделиться через


Извлечение сущности из сообщения электронной почты с помощью 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]: Протокол объекта сообщений расширения клиента.

См. также