title: How to Accept and add Categories to RequiredAttendees Appointments using Exchange Web Services
body: <p>I’m using ExchangeService(ExchangeVersion.Exchange2010_SP1)</p>
  
  <p>I want to Accept and add Categories to RequiredAttendees Appointments.  To do this i need to find these Appointments.</p>
  
  <p>My understanding in EWS is that on Save of an Appointment that has RequiredAttendees a new Meeting Request is created for each of the ‘required attendees’.</p>
  
  <p>How can I access the Appointments that were created automatically for the ‘required attendees’?  These are shown in the required attendees Calendars as Appointments, along with a Meeting Request.</p>
  
  <p>I have managed to do a crude find on the Subject (steps below)</p>
  
  <ol>
  <li>Connect to server as Organiser</li>
  <li>Create Appointment</li>
  <li>Set Subject</li>
  <li>Add Required Attendee</li>
  <li><p>Save Appointment</p></li>
  <li><p>Connect to server as Required Attendee from step 4</p></li>
  <li>Find Appointment that has Subject at step 3</li>
  <li>Add Categories to Appointment at step 7</li>
  <li>Update Appointment at step 7</li>
  <li>Accept Appointment at step 7</li>
  </ol>
  
  <p>And this does work, but concerned users will change the Subject.</p>
  
  <p>I have tried adding an Extended Property and value to the Appointment created by the Organiser and then FindItems for the Extended Property value in the Appointments connected as the Required Attendee.  This does not work.</p>
  
  <p>Is there a preferred method for what I’m trying to accomplish?</p>
  
  <p>Thank you</p>
  
  <pre><code>Private Shared ReadOnly m_organiserEmailAddress As String = "Organiser@test.com"
  Private Shared ReadOnly m_eventIdExtendedPropertyDefinition As New ExtendedPropertyDefinition(DefaultExtendedPropertySet.Meeting, "EventId", MapiPropertyType.Long)
  
  '--&gt; start here
  Public Shared Function SaveToOutlookCalendar(eventCalendarItem As EventCalendarItem) As String
  
      If eventCalendarItem.Id Is Nothing Then
          'new
          Dim newAppointment = EventCalendarItemMapper.SaveNewAppointment(eventCalendarItem)
          'set the Id
          eventCalendarItem.Id = newAppointment.Id.UniqueId.ToString()
          'accept the calendar item on behalf of the Attendee
          EventCalendarItemMapper.AcceptAppointmentAsAttendees(newAppointment)
          Return eventCalendarItem.Id
      Else
          'update existing appointment
          Return EventCalendarItemMapper.UpdateAppointment(eventCalendarItem)
      End If
  
  
  End Function
  
  Private Shared Sub ConnectToServer(Optional autoUser As String = "")
  
      If autoUser = "" Then
          _service.Url = New Uri(ExchangeWebServicesUrl)
      Else
          _service.AutodiscoverUrl(autoUser)
      End If
  
  End Sub
  
  Private Shared Sub ImpersonateUser(userEmail As String)
  
      _service.Credentials = New NetworkCredential(ImpersonatorUsername, ImpersonatorPassword, Domain)
      _service.ImpersonatedUserId = New ImpersonatedUserId(ConnectingIdType.SmtpAddress, userEmail)
  
  End Sub
  
  Private Shared Function SaveNewAppointment(eventCalendarItem As EventCalendarItem) As Appointment
  
      Try
          ConnectToServer(m_organiserEmailAddress)
          ImpersonateUser(m_organiserEmailAddress)
  
          Dim appointment As New Appointment(_service) With {
                     .Subject = eventCalendarItem.Subject}
  
          'add attendees
          For Each attendee In eventCalendarItem.Attendees
              appointment.RequiredAttendees.Add(attendee.Email)
          Next
  
          'add categories
          For Each category In eventCalendarItem.Categories
              appointment.Categories.Add(Globals.GetEnumDescription(category))
          Next
  
          'add EventId = 5059 as an extended property of the appointment
          appointment.SetExtendedProperty(m_eventIdExtendedPropertyDefinition, 5059)
  
          appointment.Save(SendInvitationsMode.SendOnlyToAll)
  
          Return appointment
      Catch
          Throw New Exception("Can't save appointment")
      End Try
  
  
  End Function
  
  Private Shared Sub AcceptAppointmentAsAttendees(appointment As Appointment)
  
      For Each attendee In appointment.RequiredAttendees
          Try
              ConnectToServer(attendee.Address.ToString())
              ImpersonateUser(attendee.Address.ToString())
  
              For Each a In FindRelatedAppiontments(appointment)
                  a.Categories.Add(Globals.GetEnumDescription(CalendarItemCategory.Workshop))
                  a.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone)
                  a.Accept(True)
              Next
  
          Catch
              Throw
          End Try
      Next
  End Sub
  
  Private Shared Function FindRelatedAppiontments(appointment As Appointment) As List(Of Appointment)
  
      Dim view As New ItemView(1000)
      Dim foundAppointments As New List(Of Appointment)
  
      view.PropertySet =
          New PropertySet(New PropertyDefinitionBase() {m_eventIdExtendedPropertyDefinition})
  
      'Extended Property value = 5059
      Dim searchFilter = New SearchFilter.IsEqualTo(m_eventIdExtendedPropertyDefinition, 5059)
  
      For Each a In _service.FindItems(WellKnownFolderName.Calendar, searchFilter, view)
          If a.ExtendedProperties.Count &gt; 0 Then
              foundAppointments.Add(appointment.Bind(_service, CType(a.Id, ItemId)))
          End If
      Next
  
      Return foundAppointments
  
  End Function
  </code></pre>