Skip to content

Работа с контр-предложениями посредством XIMSS API

1. Создание контр-предложения

Контр-предложение позволяет участнику события предложить новое время и/или длительность события. Для создания контр-предложения существующий calendarAccept расширяется двумя новыми атрибутами:

  • proposedTimeStart - новое время начала события,

  • proposedDuration - предлагаемая длительность события в секундах.

По полю uid идентифицируется событие, на которое создается контр-предложение. В поле replyComment записывается комментарий участника, сопровождающий новое предложение. Метод vcalendar method устанавливается как "COUNTER". Каждый участник может сделать неограниченное количество контр-предложений на событие, но каждое новое контр-предложение будет затирать предыдущее.

Пример запроса:

xml
<calendarAccept calendar="Calendar-CM-0" id="2" PARTSTAT="TENTATIVE" proposedDuration="3600" proposedTimeStart="20241217T222413">
  <icalendar xmlns="urn:ietf:params:xml:ns:xcal">
    <vcalendar method="COUNTER">
      <vevent>
        <organizer>organizer@example.com</organizer>
        <summary>Team Meeting</summary>
        <uid>123456789</uid>
        <dtstart>20241217T182413</dtstart>
        <dtend>20241217T192413</dtend>
        <priority>5</priority>
        <sequence>0</sequence>
        <busystatus>BUSY</busystatus>
        <attendee CN="John Doe" ROLE="REQ-PARTICIPANT" RSVP="true">johndoe@example.com</attendee>
      </vevent>
    </vcalendar>
  </icalendar>
  <replyComment>Looking forward to the meeting!</replyComment>
</calendarAccept>

При создании контр-предложения организатору отправляется почтовое уведомление.

2. Просмотр контр-предложений

Для поиска событий и просмотра связанных контр-предложений используются операции findEvents и calendarRead.

Использование findEvents

Запрос findEvents возвращает список событий в указанном временном интервале. Если событие содержит контр-предложение, возвращается тег hasCounters со значением true.

Пример запроса:

xml
input:
<findEvents calendar="Calendar-CM-0" id="4" items="0" timeFrom="20241226T000000" timeTill="20241227T000000" />

output:
    <events id="4" calendar="Calendar-CM-0" timeFrom="20241226T000000" timeTill="20241227T000000" items="1">
        <event UID="2" itemUID="867600962.6.test_pollxxrqiowdoqg" timeFrom="20241226T083205" duration="3600" busystatus="BUSY" priority="5" organizer="yes" attendees="3">
            <summary>This is a default event with a default name</summary>
            <hasCounters>true</hasCounters>
        </event>
    </events>

Использование calendarRead

При открытии события в календаре организатора через calendarRead возвращаются теги counter, содержащие детали каждого контр-предложения: время начала, время окончания, временную метку, комментарий (если есть) и email автора контр-предложения. Число тегов counter соответствует количеству участников, сделавших контр-предложения.

Пример запроса:

xml
<calendarRead calendar="Calendar-CM-0" id="5" UID="3" />

Пример ответа:

xml
<counter CN="test_rinpmrdwuojudpu@dm.test" COMMENT="Looking forward to the meeting!" DTEND="20250121T140928Z" DTSTAMP="20250121T113928Z" DTSTART="20250121T133928Z">test_rinpmrdwuojudpu@dm.test</counter>
<counter CN="test_ulgxqnagosnuwlv@dm.test" COMMENT="Looking forward to the meeting!" DTEND="20250114T133316Z" DTSTAMP="20250114T120316Z" DTSTART="20250114T130316Z">test_ulgxqnagosnuwlv@dm.test</counter>

В календаре участника возвращается только один тег counter, так как участник может сделать только одно контр-предложение.

Пример ответа:

xml
<counter COMMENT="Looking forward to the meeting!" DTEND="20250114T133316Z" DTSTAMP="20250114T060316Z" DTSTART="20250114T130316Z" />

3. Принятие COUNTER организатором

Принятие контр-предложения выполняется через операцию calendarPublish. После обновления события:

  • Запрос findEvents больше не возвращает тег hasCounters.

  • Запрос calendarRead больше не возвращает теги counter.

Пример запроса:

xml
<calendarPublish calendar="Calendar-CM-0" id="4">
  <icalendar xmlns="urn:ietf:params:xml:ns:xcal">
    <vcalendar method="PUBLISH">
      <vevent>
        <organizer xmlns="">test_svTMBLerAyANhCa@dm.test</organizer>
        <summary xmlns="">This is a default event with a default name</summary>
        <dtstart xmlns="">20241226T161335</dtstart>
        <dtend xmlns="">20241226T171335</dtend>
        <priority xmlns="">5</priority>
        <sequence xmlns="">0</sequence>
        <busystatus xmlns="">BUSY</busystatus>
        <uid xmlns="">a6c6000d-b841-464c-9ccb-444d01b05c98</uid>
        <attendee xmlns="" CN="test_hmQzuLXvYUDfYwm@dm.test" ROLE="REQ-PARTICIPANT" RSVP="true">mailto:test_hmQzuLXvYUDfYwm@dm.test</attendee>
        <attendee xmlns="" CN="test_IhUkBsmHSfvDAMi@dm.test" ROLE="REQ-PARTICIPANT" RSVP="true">mailto:test_IhUkBsmHSfvDAMi@dm.test</attendee>
        <attendee xmlns="" CN="test_svTMBLerAyANhCa@dm.test" ROLE="REQ-PARTICIPANT" RSVP="true">mailto:test_svTMBLerAyANhCa@dm.test</attendee>
      </vevent>
    </vcalendar>
  </icalendar>
</calendarPublish>

4. Отклонение COUNTER организатором

Отклонение контр-предложения выполняется через calendarDecline, который был дополнен новым атрибутом:

  • attendeeEmail — email участника, чье контр-предложение отклоняется.

Для удаления контр-предложения исключительно из календаря организатора (без уведомления участника) используется атрибут sendReply, установленный в no. Если он не задан, то по умолчанию равен yes. При наличии комментария в replyComment уведомление отправляется участнику в любом случае.

Пример запроса:

xml
<calendarDecline attendeeEmail="test_AFIupljYoUYUudi@dm.test" calendar="Calendar-CM-0" id="4" sendReply="no">
  <icalendar xmlns="urn:ietf:params:xml:ns:xcal">
    <vcalendar method="DECLINECOUNTER">
      <vevent>
        <organizer xmlns="">mailto:test_PDlFeDcjMSEqcRk@dm.test</organizer>
        <summary xmlns="">This is a default event with a default name</summary>
        <uid xmlns="">63c96617-0444-4256-abdb-e3a1b5d4ba76</uid>
        <dtstart xmlns="">20241226T133713</dtstart>
        <dtend xmlns="">20241226T143713</dtend>
        <priority xmlns="">5</priority>
        <sequence xmlns="">0</sequence>
        <attendee xmlns="" CN="mailto:test_AFIupljYoUYUudi@dm.test" ROLE="REQ-PARTICIPANT" RSVP="true">mailto:test_AFIupljYoUYUudi@dm.test</attendee>
        <attendee xmlns="" CN="mailto:test_lYHYugddTQglibH@dm.test" ROLE="REQ-PARTICIPANT" RSVP="true">mailto:test_lYHYugddTQglibH@dm.test</attendee>
        <attendee xmlns="" CN="mailto:test_PDlFeDcjMSEqcRk@dm.test" ROLE="REQ-PARTICIPANT" RSVP="true">mailto:test_PDlFeDcjMSEqcRk@dm.test</attendee>
      </vevent>
    </vcalendar>
  </icalendar>
  <replyComment>I'm sorry, but I can't take the counter proposal.</replyComment>
</calendarDecline>

Структура хранения контр-предложения в базе данных (X-CGATE-COUNTER)

X-CGATE-COUNTER;
COMMENT="Looking forward to the meeting!";
DTSTAMP=20250121T113047Z;
DTSTART=20250121T123047Z;
DTEND=20250121T130047Z;
CN="test_timpwywlttclckx@dm.test":
MAILTO:test_timpwywlttclckx@dm.test

Контр-предложение в данном формате представляет собой строку параметров, хранящую альтернативное время встречи, комментарий и информацию об участнике, сделавшем предложение.

Разберем состав этой записи:

  1. X-CGATE-COUNTER (Ключ для хранения контр-предложения) Используется как идентификатор контр-предложения в системе. Предотвращает конфликты с другими календарными системами (Google, Apple, MS Exchange).

  2. COMMENT="Looking forward to the meeting!" (Комментарий) Текстовый комментарий от участника.

  3. DTSTAMP=20250121T113047Z (Временная метка контр-предложения) Время создания контр-предложения. Позволяет определить, когда было отправлено предложение. Полезно для обработки последовательности изменений.

  4. DTSTART=20250121T123047Z (Предложенное время начала) Дата и время начала предложенного слота. Формат UTC.

  5. DTEND=20250121T130047Z (Предложенное время окончания) Дата и время окончания предложенного слота. Формат UTC (YYYYMMDDTHHMMSSZ).

  6. CN="test_timpwywlttclckx@dm.test" (Имя участника, отправившего контр-предложение) Common Name (CN) участника.

  7. MAILTO:test_timpwywlttclckx@dm.test (Email участника) Email-адрес участника, предложившего изменения.