Obtener acceso a un calendario como delegado mediante EWS en Exchange

Obtenga información sobre cómo obtener acceso a un calendario como delegado mediante la API administrada de EWS o EWS en Exchange.

Puede usar EWS o la API administrada de EWS para conceder a un delegado de usuario acceso a la carpeta Calendario del propietario de un buzón. A continuación, el delegado puede crear convocatorias de reunión en nombre del propietario del buzón, crear citas, responder a convocatorias de reunión y recuperar, actualizar y eliminar reuniones de la carpeta Calendario del propietario del buzón, según sus permisos.

Como delegado, se usan los mismos métodos y operaciones para tener acceso a la carpeta Calendario del propietario de un buzón de correo que se usa para acceder a la carpeta Calendario propia. La principal diferencia es que tiene que usar acceso explícito para buscar o crear un elemento de calendario o subcarpeta de calendario y, después de identificar el id. de elemento o el identificador de carpeta, puede usar acceso implícito para obtener, actualizar o eliminar el elemento.

Tabla 1. Métodos de API administrada de EWS y operaciones de EWS para acceder a un calendario como delegado

Si quiere... Usar este método de API administrada de EWS... Use esta operación EWS...
Crear una reunión o cita como delegado
Appointment.Save donde el parámetro FolderId proporciona acceso explícito a la carpeta Calendario del propietario del buzón
CreateItem donde el elemento Mailbox especifica el EmailAddress del propietario del buzón
Crear varias reuniones o citas como delegado
ExchangeService.CreateItems donde el parámetro FolderId proporciona acceso explícito a la carpeta Calendario del propietario del buzón
CreateItem donde el elemento Mailbox especifica el EmailAddress del propietario del buzón
Buscar una cita o reunión como delegado
ExchangeService.FindItems donde el parámetro FolderId proporciona acceso explícito a la carpeta Calendario del propietario del buzón
FindItem donde el elemento Mailbox especifica el EmailAddress del propietario del buzón
Obtener una cita o reunión como delegado
Appointment.Bind
GetItem
Actualizar una cita o reunión como delegado
Appointment.Bind seguido de Appointment.Update
GetItem seguido de UpdateItem
Eliminar una cita o reunión como delegado
Appointment.Bind seguido de Appointment.Delete
GetItem seguido de DeleteItem

Nota:

En los ejemplos de código de este artículo, primary@contoso.com es el propietario del buzón.

Tareas de requisitos previos

Para que un usuario pueda acceder a la carpeta Calendario del propietario de un buzón como delegado, el usuario debe estar agregado como delegado con permisos a la carpeta Calendario del propietario del buzón.

Un delegado debe tener un buzón adjunto a su cuenta para actualizar el calendario de un propietario del buzón.

Si un delegado solo necesita trabajar con convocatorias de reunión y respuestas, puede agregar el delegado a la carpeta Calendario y usar el valor de enumeración de la API administrada de EWS predeterminado MeetingRequestsDeliveryScope.DelegatesAndSendInformationToMe o el valor del elemento de EWS DeliverMeetingRequests a DelegatesAndSendInformationToMe para enviar las solicitudes al delegado y mensajes informativos al propietario del buzón. No es necesario que el delegado tenga acceso a la carpeta Bandeja de entrada del propietario del buzón.

Crear una reunión o cita como delegado mediante la API administrada de EWS

La API administrada de EWS permite usar el objeto de servicio para que el usuario delegado cree elementos de calendario para el propietario del buzón. En este ejemplo se muestra cómo usar el método Guardar para crear una reunión y enviar convocatorias de reunión a los asistentes.

En este ejemplo se supone que service es un objeto ExchangeService válido para el delegado y que se han concedido al delegado los permisos adecuados para la carpeta Calendario del propietario del buzón.

private static void DelegateAccessCreateMeeting(ExchangeService service)
{
    Appointment meeting = new Appointment(service);
    // Set the properties on the meeting object to create the meeting.
    meeting.Subject = "Team building exercise";
    meeting.Body = "Let's learn to really work as a team and then have lunch!";
    meeting.Start = DateTime.Now.AddDays(2);
    meeting.End = meeting.Start.AddHours(4);
    meeting.Location = "Conference Room 12";
    meeting.RequiredAttendees.Add("sadie@contoso.com");
    meeting.ReminderMinutesBeforeStart = 60;
    // Save the meeting to the Calendar folder for 
    // the mailbox owner and send the meeting request.
    // This method call results in a CreateItem call to EWS.
    meeting.Save(new FolderId(WellKnownFolderName.Calendar, 
        "primary@contoso.com"), 
        SendInvitationsMode.SendToAllAndSaveCopy);
    // Verify that the meeting was created.
    Item item = Item.Bind(service, meeting.Id, new PropertySet(ItemSchema.Subject));
    Console.WriteLine("\nMeeting created: " + item.Subject + "\n");
}

Tenga en cuenta que al guardar el elemento, la llamada al método Guardar debe identificar la carpeta Calendario del propietario del buzón. Si no se especifica la carpeta Calendario del propietario del buzón, la convocatoria de reunión se guarda en el calendario del delegado y no en la carpeta Calendario del propietario del buzón. Puede incluir la carpeta Calendario del propietario del buzón en la llamada al método Guardar de dos maneras. Se recomienda crear una instancia nueva del objeto FolderId mediante el WellKnownFolderName y la dirección SMTP del propietario del buzón.

meeting.Save(new FolderId(WellKnownFolderName.Calendar,
    "primary@contoso.com"), SendInvitationsMode.SendToAllAndSaveCopy);

Sin embargo, también puede Enlazar primero a la carpeta Calendario y, después, usar el identificador de la carpeta en la llamada al método Guardar. Tenga en cuenta, sin embargo, que esto crea una llamada EWS adicional.

    // Identify the mailbox owner's SMTP address
    // and bind to their Calendar folder.
    Mailbox primary = new Mailbox("primary@contoso.com"); 
    Folder primaryCalendar = Folder.Bind(service, 
        new FolderId(WellKnownFolderName.Calendar, primary)); 
…
    // Save the meeting to the Calendar folder for the mailbox owner and send the meeting request.
    meeting.Save(primaryCalendar.Id, 
        SendInvitationsMode.SendToAllAndSaveCopy);

Crear una reunión o cita como delegado mediante EWS

EWS permite usar el objeto de servicio para que el usuario delegado cree elementos de calendario para el propietario del buzón. En este ejemplo se muestra cómo usar la operación CreateItem para crear una reunión y enviar convocatorias de reunión a los asistentes.

Esta también es la solicitud XML que la API administrada de EWS envía cuando se usa el método Guardar para crear una reunión o cita como delegado.

El encabezado SOAP se ha quitado del ejemplo siguiente por motivos de brevedad.

<?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:Body>
    <m:CreateItem SendMeetingInvitations="SendToAllAndSaveCopy">
      <m:SavedItemFolderId>
        <t:DistinguishedFolderId Id="calendar">
          <t:Mailbox>
            <t:EmailAddress>primary@contoso.com</t:EmailAddress>
          </t:Mailbox>
        </t:DistinguishedFolderId>
      </m:SavedItemFolderId>
      <m:Items>
        <t:CalendarItem>
          <t:Subject>Team building exercise</t:Subject>
          <t:Body BodyType="HTML">Let's learn to really work as a 
              team and then have lunch!</t:Body>
          <t:ReminderMinutesBeforeStart>60</t:ReminderMinutesBeforeStart>
          <t:Start>2014-03-09T23:26:33.756-05:00</t:Start>
          <t:End>2014-03-10T03:26:33.756-05:00</t:End>
          <t:Location>Conference Room 12</t:Location>
          <t:RequiredAttendees>
            <t:Attendee>
              <t:Mailbox>
                <t:EmailAddress>sadie@contoso.com</t:EmailAddress>
              </t:Mailbox>
            </t:Attendee>
          </t:RequiredAttendees>
        </t:CalendarItem>
      </m:Items>
    </m:CreateItem>
  </soap:Body>
</soap:Envelope>

El servidor responde a la solicitud CreateItem con un mensaje CreateItemResponse que incluye un valor de elemento ResponseCode de NoError, lo que indica que la reunión se creó correctamente. La respuesta también contiene el identificador de elemento de la reunión recién creada.

Buscar una reunión o cita como delegado mediante la API administrada de EWS

Para buscar una reunión, debe usar uno de los métodos ExchangeService.FindItems que incluye un parámetro FolderId para poder especificar la carpeta Calendario del propietario del buzón.

static void DelegateAccessSearchWithFilter
    (ExchangeService service, SearchFilter filter)
{
    // Limit the result set to 10 items.
    ItemView view = new ItemView(10);
    view.PropertySet = new PropertySet(ItemSchema.Subject,
                                       ItemSchema.DateTimeReceived,
                                       EmailMessageSchema.IsRead);
    // Item searches do not support deep traversal.
    view.Traversal = ItemTraversal.Shallow;
    // Define the sort order.
    view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
    try
    {
        // Call FindItems to find matching calendar items. 
        // The FindItems parameters must denote the mailbox owner,
        // mailbox, and Calendar folder.
        // This method call results in a FindItem call to EWS.
        FindItemsResults<Item> results = service.FindItems(
        new FolderId(WellKnownFolderName.Calendar, 
            "primary@contoso.com"), 
            filter, 
            view);
        foreach (Item item in results.Items)
        {
            Console.WriteLine("Subject: {0}", item.Subject);
            Console.WriteLine("Id: {0}", item.Id.ToString());
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Exception while 
            enumerating results: {0}", ex.Message);
    }
}

Después de que la llamada FindItems devuelva una respuesta con un identificador, puede obtener, actualizar o eliminar esa reunión con el identificador y acceso implícito (y no es necesario especificar la dirección SMTP del propietario del buzón).

Buscar una reunión o cita como delegado mediante EWS

EWS permite usar el objeto de servicio para que el usuario delegado busque citas y reuniones que cumplan un conjunto de criterios de búsqueda. En este ejemplo se muestra cómo usar la operación FindItem para buscar reuniones en la carpeta Calendario del propietario del buzón que contengan la palabra "edificio" en el asunto.

Esta también es la solicitud XML que la API administrada de EWS envía cuando se usa el método FindItem para buscar una reunión o cita como delegado.

<?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:FindItem Traversal="Shallow">
      <m:ItemShape>
        <t:BaseShape>IdOnly</t:BaseShape>
        <t:AdditionalProperties>
          <t:FieldURI FieldURI="item:Subject" />
          <t:FieldURI FieldURI="item:DateTimeReceived" />
          <t:FieldURI FieldURI="message:IsRead" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:IndexedPageItemView MaxEntriesReturned="10"
                             Offset="0"
                             BasePoint="Beginning" />
      <m:Restriction>
        <t:Contains ContainmentMode="Substring"
                    ContainmentComparison="IgnoreCase">
          <t:FieldURI FieldURI="item:Subject" />
          <t:Constant Value="building" />
        </t:Contains>
      </m:Restriction>
      <m:SortOrder>
        <t:FieldOrder Order="Descending">
          <t:FieldURI FieldURI="item:DateTimeReceived" />
        </t:FieldOrder>
      </m:SortOrder>
      <m:ParentFolderIds>
        <t:DistinguishedFolderId Id="calendar">
          <t:Mailbox>
            <t:EmailAddress>primary@contoso.com</t:EmailAddress>
          </t:Mailbox>
        </t:DistinguishedFolderId>
      </m:ParentFolderIds>
    </m:FindItem>
  </soap:Body>
</soap:Envelope>

El servidor responde a la solicitud FindItem con un mensaje FindItemResponse que incluye el valor de elemento ResponseCode de NoError, que indica que la búsqueda se completó correctamente. La respuesta contiene un CalendarItem para las citas o reuniones que cumplan los criterios de búsqueda. En este caso, solo se encuentra una reunión.

El valor del elemento ItemId se ha abreviado para mejorar la legibilidad.

<?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="893"
                         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>
    <m:FindItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                        xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:FindItemResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:RootFolder IndexedPagingOffset="1"
                        TotalItemsInView="1"
                        IncludesLastItemInRange="true">
            <t:Items>
              <t:CalendarItem>
                <t:ItemId Id="IJpUAAA="
                          ChangeKey="DwAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAAAIKhS" />
                <t:Subject>Team building exercise</t:Subject>
                <t:DateTimeReceived>2014-03-04T21:27:22Z</t:DateTimeReceived>
              </t:CalendarItem>
            </t:Items>
          </m:RootFolder>
        </m:FindItemResponseMessage>
      </m:ResponseMessages>
    </m:FindItemResponse>
  </s:Body>
</s:Envelope>

Ahora que tiene el ItemId para la reunión que cumple sus criterios, puede obtener, actualizar o eliminar esa reunión mediante el ItemId y acceso implícito (y no es necesario especificar la dirección SMTP del propietario del buzón).

Obtener, actualizar o eliminar elementos de calendario como delegado mediante la API administrada de EWS

Puede usar la API administrada de EWS para obtener, actualizar o eliminar una reunión o cita de la misma manera que realiza estas acciones cuando no usa el acceso delegado. La única diferencia es que el objeto de servicio es para el usuario delegado. El id. de elemento incluido en la llamada al método Enlazar identifica de forma única el elemento en el almacén de buzones, en la carpeta Calendario del propietario del buzón.

Tabla 2. Métodos de API administrada de EWS para trabajar con citas y reuniones como delegado

Task Método de la API administrada de EWS Ejemplo de código
Obtener una cita o reunión
Enlazar
Obtener un elemento mediante la API administrada de EWS
Actualizar una cita o reunión
Bind seguido de Update
Actualizar una reunión mediante la API administrada de EWS
Eliminar una cita o reunión
Bind seguido de Delete
Eliminación de una reunión mediante la API administrada de EWS

Obtener, actualizar o eliminar elementos de calendario como delegado mediante EWS

Puede usar EWS para obtener, actualizar o eliminar una reunión o cita de la misma manera que realiza estas acciones cuando no usa el acceso delegado. La única diferencia es que el objeto de servicio es para el usuario delegado. El id. de elemento incluido en la llamada al método GetItem identifica de forma única el elemento en el almacén de buzones, en la carpeta Calendario del propietario del buzón.

Tabla 3. Operaciones de EWS para trabajar con citas y reuniones como delegado

Task Operación de EWS Ejemplo de código
Obtener una cita o reunión
GetItem
Obtener un elemento mediante EWS
Actualizar una cita o reunión
GetItem seguido de UpdateItem
Actualizar una reunión mediante EWS
Eliminar una cita o reunión
GetItem seguido de DeleteItem
Eliminar una reunión mediante EWS

Recursos adicionales