Exchange で EWS を使用してバッチ処理でメール メッセージを処理する

Exchange で EWS マネージ API または EWS を使用して、1 回の呼び出しで複数のメール メッセージの作成、取得、更新、削除をバッチ処理する方法について説明します。

EWS マネージ API または EWS を使用すると、メール メッセージのバッチ操作を行い、クライアントが Exchange サーバーを呼び出す回数を減らせます。 EWS マネージ API を使用してメール メッセージの作成、取得、更新、削除、送信のバッチ操作を行う場合、ExchangeService オブジェクト メソッドを使用します。1 つのメール メッセージを対象とする場合には EmailMessage オブジェクト メソッドを使用します。 EWS を使用する場合は、同じ操作を使用して 1 つのメール メッセージの処理とバッチ処理のどちらも行えます。

表 1. メール メッセージをバッチ処理するための EWS マネージ API メソッドと EWS 操作

目的 使用する EWS マネージ API メソッド 使用する EWS 操作
バッチ処理でメール メッセージを作成する
ExchangeService.CreateItems
CreateItem
バッチ処理でメール メッセージを取得する
ExchangeService.BindToItems
GetItem
バッチ処理でメール メッセージを更新する
ExchangeService.UpdateItems
UpdateItem
バッチ処理でメール メッセージを削除する
ExchangeService.DeleteItems
DeleteItem

この記事では、EWS マネージ API または EWS を使用してメール メッセージのバッチ処理を行うための基本的なタスクの実行方法について説明します。

EWS マネージ API を使用してバッチ処理でメール メッセージを作成する

次の例に示されているように、EWS マネージ API CreateItems メソッドを使用すると、バッチ処理でメッセージを作成できます。 この例では、3 つの EmailMessage オブジェクトをローカルに作成し、それぞれのメッセージをコレクションに追加してから、メッセージのコレクションをパラメーターにして CreateItems メソッドを呼び出します。

この例では、service が有効な ExchangeService オブジェクトであり、ユーザーが Exchange サーバーから既に認証されていると想定しています。

public static Collection<ItemId> CreateDraftEmailInBatch(ExchangeService service)
{
    // These are unsaved local instances of an EmailMessage object.
    // Despite the required parameter of an ExchangeService object (service), no call
    // to an Exchange server is made when the objects are instantiated.
    // A call to the Exchange server is made when the service.CreateItems() method is called.
    EmailMessage message1 = new EmailMessage(service);
    EmailMessage message2 = new EmailMessage(service);
    EmailMessage message3 = new EmailMessage(service);
    // Set the properties on the first message.
    message1.Subject = "Project priorities";
    message1.Body = "(1) Buy pizza, (2) Eat pizza";
    message1.ToRecipients.Add("sadie@contoso.com");
    // Set the properties on the second message.
    message2.Subject = "Company Soccer Team";
    message2.Body = "Are you interested in joining?";
    message2.ToRecipients.Add("magdalena@contoso.com");
    // Set the properties on the third message.
    message3.Subject = "Code Blast";
    message3.Body = "Are you interested in getting together to finish the methods for the ContosoLive project?";
    message3.ToRecipients.Add("mack@contoso.com");
    // Add the EmailMessage objects to a collection.
    Collection<EmailMessage> messageItems = new Collection<EmailMessage>() { message1, message2, message3 };
    // Create the batch of email messages on the server.
    // This method call results in an CreateItem call to EWS.
    ServiceResponseCollection<ServiceResponse> response = service.CreateItems(messageItems, WellKnownFolderName.Drafts, MessageDisposition.SaveOnly, null);
    // Instantiate a collection of item IDs to populate from the values that are returned by the Exchange server.
    Collection<ItemId> itemIds = new Collection<ItemId>();
    // Collect the item IDs from the created email messages.
    foreach (EmailMessage message in messageItems)
    {
        try
        {
            itemIds.Add(message.Id);
            Console.WriteLine("Email message '{0}' created successfully.", message.Subject);
        }
        catch (Exception ex)
        {
            // Print out the exception and the last eight characters of the item ID.
            Console.WriteLine("Exception while creating message {0}: {1}", message.Id.ToString().Substring(144), ex.Message);
        }
    }
    // Check for success of the CreateItems method call.
    if (response.OverallResult == ServiceResult.Success)
    {
            Console.WriteLine("All locally created messages were successfully saved to the Drafts folder.");
            Console.WriteLine("\r\n");
    }

    // If the method did not return success, print the result message for each email.
    else
    {
        int counter = 1;
        foreach (ServiceResponse resp in response)
        {
            // Print out the result and the last eight characters of the item ID.
            Console.WriteLine("Result (message {0}), id {1}: {2}", counter, itemIds[counter - 1].ToString().Substring(144), resp.Result);
            Console.WriteLine("Error Code: {0}", resp.ErrorCode);
            Console.WriteLine("ErrorMessage: {0}\r\n", resp.ErrorMessage);
            Console.WriteLine("\r\n");
            counter++;
        }
    }
    return itemIds;
}

この例では、下書きフォルダーにメッセージを保存しますが、メッセージは送信しません。 メッセージを送信する方法の詳細については、「EWS マネージ API を使用してバッチ処理でメール メッセージを送信する」を参照してください。

EWS を使用してバッチ処理でメール メッセージを作成する

次のコード例に示されているように、CreateItem EWS 操作を使用して、バッチ処理でメール メッセージを作成できます。 これは、EWS マネージ API を使用してバッチ処理でメール メッセージを作成する際に、EWS マネージ API が送信する XML 要求でもあります。

<?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="Exchange2007_SP1" />
  </soap:Header>
  <soap:Body>
    <m:CreateItem MessageDisposition="SaveOnly">
      <m:SavedItemFolderId>
        <t:DistinguishedFolderId Id="drafts" />
      </m:SavedItemFolderId>
      <m:Items>
        <t:Message>
          <t:Subject>Project priorities</t:Subject>
          <t:Body BodyType="HTML">(1) Buy pizza, (2) Eat pizza</t:Body>
          <t:ToRecipients>
            <t:Mailbox>
              <t:EmailAddress>sadie@contoso.com</t:EmailAddress>
            </t:Mailbox>
          </t:ToRecipients>
        </t:Message>
        <t:Message>
          <t:Subject>Company Soccer Team</t:Subject>
          <t:Body BodyType="HTML">Are you interested in joining?</t:Body>
          <t:ToRecipients>
            <t:Mailbox>
              <t:EmailAddress>magdalena@contoso.com</t:EmailAddress>
            </t:Mailbox>
          </t:ToRecipients>
        </t:Message>
        <t:Message>
          <t:Subject>Code Blast</t:Subject>
          <t:Body BodyType="HTML">Are you interested in getting together to finish the methods for the ContosoLive project?</t:Body>
          <t:ToRecipients>
            <t:Mailbox>
              <t:EmailAddress>mack@contoso.com</t:EmailAddress>
            </t:Mailbox>
          </t:ToRecipients>
        </t:Message>
      </m:Items>
    </m:CreateItem>
  </soap:Body>
</soap:Envelope>

サーバーは、CreateItem 要求に CreateItemResponse メッセージで応答します。このメッセージには、それぞれの新しいメッセージが正常に作成および保存されたことを示す、NoErrorResponseCode 値が含まれます。

この例では、下書きフォルダーにメッセージを保存しますが、メッセージは送信しません。 メッセージを送信する方法の詳細については、「EWS を使用してバッチ処理でメール メッセージを送信する」を参照してください。

EWS マネージ API を使用してバッチ処理でメール メッセージを送信する

バッチ処理でメール メッセージを送信するには、バッチ処理でのメール メッセージの作成に使用するコードと同じコードを使用します。ただし、一部の CreateItems メソッドのパラメーターは変更します。 そのため、EWS マネージ API を使用してメール メッセージを送信するには、バッチ処理でのメール メッセージの作成に使用するコードを使用して、CreateItems メソッドへの呼び出しを次の例の呼び出しに置き換えます。 この例では、メッセージは送信済みアイテム フォルダーに作成されます。またメッセージがローカルに保存されるだけでなく送信されるように、メッセージの処理方法を MessageDisposition.SendAndSaveCopy に変更しています。

// Create and send the batch of email messages on the server.
// This method call results in an CreateItem call to EWS.
ServiceResponseCollection<ServiceResponse> response = service.CreateItems(messageItems, WellKnownFolderName.SentItems, MessageDisposition.SendAndSaveCopy, null);

EWS を使用してバッチ処理でメール メッセージを送信する

バッチ処理でメール メッセージを送信するには、バッチ処理でのメール メッセージの作成に使用するコードと同じコードを使用します。ただし、CreateItem 操作の一部の属性値は変更します。 そのため、EWS を使用してメール メッセージを送信するには、バッチ処理でのメール メッセージの作成に使用するコードを使用して、次のコード例に示すように、MessageDisposition 値を "SendAndSaveCopy" に変更し、DistinguishedFolderId を "sentitems" に変更します。

<m:CreateItem MessageDisposition="SendAndSaveCopy">
  <m:SavedItemFolderId>
    <t:DistinguishedFolderId Id="sentitems" />
  </m:SavedItemFolderId>

サーバーは、CreateItem 要求に CreateItemResponse メッセージで応答します。このメッセージには、それぞれの新しいメッセージが正常に作成および送信されたことを示す、NoErrorResponseCode 値が含まれます。

EWS マネージ API を使用してバッチ処理でメール メッセージを取得する

次の例に示されているように、EWS マネージ API BindToItems メソッドを使用すると、バッチ処理でメール メッセージを取得できます。

この例では、service が有効な ExchangeService オブジェクトであり、ユーザーが Exchange サーバーから既に認証されていると想定しています。

public static Collection<EmailMessage> BatchGetEmailItems(ExchangeService service, Collection<ItemId> itemIds)
{
    // 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, EmailMessageSchema.Subject, EmailMessageSchema.ToRecipients);
    // Get the items from the server.
    // This method call results in a GetItem call to EWS.
    ServiceResponseCollection<GetItemResponse> response = service.BindToItems(itemIds, propSet);

    // Instantiate a collection of EmailMessage objects to populate from the values that are returned by the Exchange server.
    Collection<EmailMessage> messageItems = new Collection<EmailMessage>();
    foreach (GetItemResponse getItemResponse in response)
    {
        try
        {
            Item item = getItemResponse.Item;
            EmailMessage message = (EmailMessage)item;
            messageItems.Add(message);
            // Print out confirmation and the last eight characters of the item ID.
            Console.WriteLine("Found item {0}.", message.Id.ToString().Substring(144));
        }
        catch (Exception ex)
        {
           Console.WriteLine("Exception while getting a message: {0}", ex.Message);
        }
    }
    // Check for success of the BindToItems method call.
    if (response.OverallResult == ServiceResult.Success)
    {
        Console.WriteLine("All email messages retrieved successfully.");
        Console.WriteLine("\r\n");
    }
        return messageItems;
}

EWS を使用してバッチ処理でメール メッセージを取得する

次のコード例に示されている GetItem EWS 操作とコードを使用して、バッチ処理でメール メッセージを取得できます。 これは、EWS マネージ API を使用してバッチ処理でメール メッセージを取得する際に、EWS マネージ API が送信する XML 要求でもあります。

ItemId 属性と ChangeKey 属性は読みやすいように短縮されています。

<?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="Exchange2007_SP1" />
  </soap:Header>
  <soap:Body>
    <m:GetItem>
      <m:ItemShape>
        <t:BaseShape>IdOnly</t:BaseShape>
        <t:AdditionalProperties>
          <t:FieldURI FieldURI="item:Subject" />
          <t:FieldURI FieldURI="message:ToRecipients" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:ItemIds>
        <t:ItemId Id="m4NxAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKB0" />
        <t:ItemId Id="m4NyAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKB1" />
        <t:ItemId Id="m4NzAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKB2" />
      </m:ItemIds>
    </m:GetItem>
  </soap:Body>
</soap:Envelope>

サーバーは GetItem 要求に GetItemResponse メッセージで応答します。このメッセージには、それぞれの要求されたメッセージのファースト クラス プロパティが含まれます。

EWS マネージ API を使用してバッチ処理でメール メッセージを更新する

次の例に示されているように、EWS マネージ API の UpdateItems メソッドを使用すると、バッチ処理でメール メッセージを取得できます。

書き込み可能なメール メッセージ プロパティの一覧については、「Exchange における EWS でのメールのプロパティと要素」を参照してください。

下書きメッセージを更新してから送信する方法の詳細については、「EWS マネージ API を使用してメール メッセージを送信する」を参照してください。

この例では、service が有効な ExchangeService オブジェクトであり、ユーザーが Exchange サーバーから既に認証されていると想定しています。

public static Collection<EmailMessage> BatchUpdateEmailItems(ExchangeService service, Collection<EmailMessage> messageItems)
{
    // Update the subject of each message locally.
    foreach (EmailMessage message in messageItems)
    {
        // Update the Subject of the email.
        message.Subject = "Updated subject at " + DateTime.Now;
        // Print out confirmation with the last eight characters of the item ID and the email subject.
        Console.WriteLine("Updated local email message {0} with the subject '{1}'.", message.Id.ToString().Substring(144), message.Subject);
    }
    // Send the item updates to the server.
    // This method call results in an UpdateItem call to EWS.
    ServiceResponseCollection<UpdateItemResponse> response = service.UpdateItems(messageItems, WellKnownFolderName.Drafts, ConflictResolutionMode.AutoResolve, MessageDisposition.SaveOnly, null);
    // Check for success of the UpdateItems method call.
    if (response.OverallResult == ServiceResult.Success)
    {
        Console.WriteLine("All email messages updated successfully.\r\n");
    }
    // If the method did not return success, print the result message for each email.
    else
    {
        Console.WriteLine("All emails were not successfully saved on the server.\r\n");
        int counter = 1;
        foreach (ServiceResponse resp in response)
        {
            Console.WriteLine("Result for (message {0}): {1}", counter, resp.Result);
            Console.WriteLine("Error Code: {0}", resp.ErrorCode);
            Console.WriteLine("ErrorMessage: {0}\r\n", resp.ErrorMessage);
            counter++;
        }
    }
    return messageItems;
}

EWS を使用してバッチ処理でメール メッセージを更新する

次のコード例に示されているように、EWS の GetItem 操作を使用して、バッチ処理でメール メッセージを更新できます。 これは、EWS マネージ API を使用してバッチ処理でメール メッセージを更新する際に、EWS マネージ API が送信する XML 要求でもあります。

書き込み可能なメール メッセージ要素の一覧については、「Exchange における EWS でのメールのプロパティと要素」を参照してください。

下書きメッセージを更新してから送信する方法の詳細については、「EWS を使用して下書きメール メッセージを送信する」を参照してください。

<?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="Exchange2007_SP1" />
  </soap:Header>
  <soap:Body>
    <m:UpdateItem MessageDisposition="SaveOnly"
                  ConflictResolution="AutoResolve">
      <m:SavedItemFolderId>
        <t:DistinguishedFolderId Id="drafts" />
      </m:SavedItemFolderId>
      <m:ItemChanges>
        <t:ItemChange>
          <t:ItemId Id="m4OVAAA="
                    ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKCy" />
          <t:Updates>
            <t:SetItemField>
              <t:FieldURI FieldURI="item:Subject" />
              <t:Message>
                <t:Subject>Updated subject at 1/17/2014 2:58:09 PM</t:Subject>
              </t:Message>
            </t:SetItemField>
          </t:Updates>
        </t:ItemChange>
        <t:ItemChange>
          <t:ItemId Id="m4OWAAA="
                    ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKCz" />
          <t:Updates>
            <t:SetItemField>
              <t:FieldURI FieldURI="item:Subject" />
              <t:Message>
                <t:Subject>Updated subject at 1/17/2014 2:58:09 PM</t:Subject>
              </t:Message>
            </t:SetItemField>
          </t:Updates>
        </t:ItemChange>
        <t:ItemChange>
          <t:ItemId Id="m4OXAAA="
                    ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKC0" />
          <t:Updates>
            <t:SetItemField>
              <t:FieldURI FieldURI="item:Subject" />
              <t:Message>
                <t:Subject>Updated subject at 1/17/2014 2:58:09 PM</t:Subject>
              </t:Message>
            </t:SetItemField>
          </t:Updates>
        </t:ItemChange>
      </m:ItemChanges>
    </m:UpdateItem>
  </soap:Body>
</soap:Envelope>

サーバーは UpdateItem 要求に応答し、ResponseCodeNoError を含む UpdateItemResponse メッセージが返されます。これは、各更新プログラムがサーバーに正常に保存されたことを示します。 競合はすべて ConflictResult 要素で報告されます。

EWS マネージ API を使用してバッチ処理でメール メッセージを削除する

次の例に示されているように、EWS マネージ API の DeleteItems メソッドを使用すると、バッチ処理でメッセージを削除できます。

この例では、service が有効な ExchangeService オブジェクトであり、ユーザーが Exchange サーバーから既に認証されていると想定しています。

public static void BatchDeleteEmailItems(ExchangeService service, Collection<ItemId> itemIds)
{
    // Delete the batch of email message objects.
    // This method call results in an DeleteItem call to EWS.
    ServiceResponseCollection<ServiceResponse> response = service.DeleteItems(itemIds, DeleteMode.SoftDelete, null, AffectedTaskOccurrence.AllOccurrences);

    // Check for success of the DeleteItems method call.
    // DeleteItems returns success even if it does not find all the item IDs.
    if (response.OverallResult == ServiceResult.Success)
    {
        Console.WriteLine("Email messages deleted successfully.\r\n");
    }
    // If the method did not return success, print a message.
    else
    {
        Console.WriteLine("Not all email messages deleted successfully.\r\n");
    }
}

EWS を使用してバッチ処理でメール メッセージを削除する

次のコード例に示されているように、EWS の DeleteItem 操作を使用して、バッチ処理でメール メッセージを削除できます。 これは、EWS マネージ API を使用してバッチ処理でメール メッセージを削除する際に、EWS マネージ API が送信する XML 要求でもあります。

<?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="Exchange2007_SP1" />
  </soap:Header>
  <soap:Body>
    <m:DeleteItem DeleteType="SoftDelete"
                  AffectedTaskOccurrences="AllOccurrences">
      <m:ItemIds>
        <t:ItemId Id="m4OkAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKDE" />
        <t:ItemId Id="m4OlAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKDF" />
        <t:ItemId Id="m4OmAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKDG" />
      </m:ItemIds>
    </m:DeleteItem>
  </soap:Body>
</soap:Envelope>

サーバーは、DeleteItem 要求に DeleteItemResponse メッセージで応答します。このメッセージには、削除された各アイテムの NoErrorResponseCode 値が含まれます。 項目 ID が見つからなかった場合も、操作によって成功が返されることに注意してください。

バッチ処理が正常に完了したことを確認する

バッチ処理された要求の 1 つ以上の電子メール メッセージを要求どおりに処理できない場合、失敗したメール メッセージごとにエラーが返され、バッチ内の残りの電子メールが期待どおりに処理されます。 バッチ処理でエラーが発生するのは、アイテムが削除された場合、そのため、アイテムを送信、取得、または更新できない場合、またはアイテムが別のフォルダーに移動した場合、そのため新しい項目 ID を持ち、送信されたアイテム ID で変更できない場合です。 このセクションの情報では、電子メール メッセージのバッチ処理でエラーに関するエラーの詳細を取得する方法を示します。

EWS マネージ API を使用してバッチ処理が成功したかどうかは、ServiceResponseCollectionOverallResult プロパティが ServiceResult.Success と等しいかどうかを調べることで確認できます。 等しい場合は、すべてのメールが正常に処理されています。 OverallResultServiceResult.Success と等しくない場合は、1 つ以上のメールが正常に処理されていません。 ServiceResponseCollection で返される各オブジェクトには、次のプロパティが含まれます。

これらのプロパティには、メール メッセージを要求どおりに処理できなかった原因についての情報が含まれます。 この記事の例では、エラーが生じた各メッセージの ResultErrorCodeErrorMessage が出力されます。 これらの結果を使用して問題を調査できます。

EWS でバッチ処理が成功したことを確認するには、各処理対象アイテムの ResponseClass 属性を調べます。 すべての応答メッセージの派生元となる基本タイプの ResponseMessageType の基本構造を次に示します。

<ResponseMessage ResponseClass="Success | Warning | Error">
            <MessageText/>
            <ResponseCode/>
            <DescriptiveLinkKey/>
            <MessageXml/>
</ResponseMessage>

ResponseClass 属性は、メールが正常に処理された場合には Success に設定され、正常に処理されなかった場合には Error に設定されます。 メール メッセージの場合には、バッチ処理中に Warning が示されることはありません。 ResponseClassSuccess の場合、それに続く ResponseCode 要素は必ず NoError に設定されます。 ResponseClassError の場合、MessageTextResponseCodeMessageXml の各要素の値を確認し、問題の原因を特定する必要があります。 DescriptiveLinkKey は現在使用されていません。

関連項目