Exchange において EWS を使用してメール メッセージからエンティティを抽出する

Exchange において EWS マネージ API または EWS を使用して、メール メッセージの本文から情報を抽出する方法を説明します。

EWS マネージ API または EWS を使用して、Exchange サーバーがメール メッセージから抽出する住所、連絡先、メール アドレス、提案された会議、電話番号、タスク、URL にアクセスできます。この情報を新しいアプリのために使用したり、既存のアプリでこの情報を使用してさまざまなアクションの次の処理を提案したりできます。たとえば、連絡先エンティティ、提案された会議、タスクのヒントがメールの中で識別された場合、お客様のアプリで、情報を事前設定して新しいアイテムの作成を提案できます。抽出されたエンティティを使用して、データの背後にある意図を十分に生かすことができます。さらに、メール メッセージのコンテンツを実行できる成果へとシームレスに統合できるよう、ユーザーを支援します。

住所、連絡先、メール アドレス、提案された会議、電話番号、タスク、URL のエンティティの抽出機能は、Exchange ストアのすべてのアイテムに組み込まれています。 EWS マネージ API を使用している場合、Item.Bind メソッドを呼び出し、Item.EntityExtractionResult プロパティでエンティティを取得します。 EWS を使用している場合、GetItem 操作を呼び出し、EntityExtractionResult 要素ですべての抽出されたエンティティを取得します。 抽出されたエンティティの結果を取得した後、各エンティティのコレクションをたどって関連情報を収集できます。 たとえば、提案された会議が抽出された場合、提案された会議の件名、出席者リスト、開始時刻、終了時刻を取得できます。

表 1. 抽出されたエンティティを含む EWS マネージ API のプロパティと EWS の要素

抽出されたエンティティ EWS マネージ API のプロパティ EWS の要素
住所
EntityExtractionResult.Addresses
Addresses
連絡先
EntityExtractionResult.Contacts
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

EWS マネージ API を使用して、メールからすべてのエンティティを抽出する

次のコード例は、サーバーが抽出したすべてのエンティティを Item.Bind メソッドを使用して表示する方法を示しています。その後、抽出されたエンティティとそのプロパティのすべてを列挙します。

この例では、service は有効な ExchangeService オブジェクトで、ItemId は移動またはコピー対象のメール メッセージの Id であると想定しています。

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/1/0104 2:00:00 PM です。 これは、サーバーによって抽出された開始時刻と終了時刻が、エンコードされた日付であるために発生します。 提案された会議での dateTime 値を解釈する方法について詳しくは、「[MS OXCEXT]:クライアント拡張機能のメッセージ オブジェクト プロトコル」をご覧ください。

EWS を使用して、メールからすべてのエンティティを抽出する

次のコード例は、GetItem 操作と EntityExtractionResult 要素を使用して、アイテムから抽出されたエンティティを取得する方法を示しています。

これは、Bind メソッドを使用して EWS マネージ API を使用することによりメールからのすべてのエンティティを抽出する際に、EWS マネージ API が送信する XML 要求でもあります。

ItemId 要素の値は、読みやすいよう短縮してあります。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="https://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 メッセージで応答します。このメッセージには、ResponseCode の値として NoError が含まれており、それは、メール メッセージが正常に取得されたことを示しています。 応答には、抽出されたエンティティごとに 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="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns="https://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="https://schemas.microsoft.com/exchange/services/2006/messages"
                       xmlns:t="https://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/1/0104 2:00:00 PM です。 これは、サーバーによって抽出された開始時刻と終了時刻が、エンコードされた日付であるために発生します。 提案された会議での dateTime 値の解釈について詳しくは、「[MS OXCEXT]: クライアント拡張機能のメッセージ オブジェクト プロトコル」をご覧ください。

関連項目