Допустим, вы купили себе Confluence и используете его для планирования совещаний. Потом вы захотели иметь календарь всех совещаний, и чтобы он напоминал сотрудникам о них. И купили Team Calendar.
Теперь, чтобы запланировать совещание, вам нужно сначала создать страничку в Confluence, а потом руками завести совещание в Team Calendar.
На данный момент, нет готовой интеграции для автоматического создания событий из страничек, и REST API не опубликован.
Исходники скрипта
#set ($D='$') <script type="text/javascript"> $(document).ready(function() { $('#submitevent').click( function () { var row = AJS.$('.plugin-tabmeta-details table th:contains("startDate")').parent(); var startDate = AJS.$('td', row).text().replace( /(\d+) (\w+) (\d{4})[^d]+/, "$2 $1, $3"); row = AJS.$('.plugin-tabmeta-details table th:contains("calendar")').parent(); var calendar = AJS.$('td', row).text(); row = AJS.$('.plugin-tabmeta-details table th:contains("startTime")').parent(); var startTime = AJS.$('td', row).text(); row = AJS.$('.plugin-tabmeta-details table th:contains("endTime")').parent(); var endTime = AJS.$('td', row).text(); row = AJS.$('.plugin-tabmeta-details table th:contains("where")').parent(); var where = AJS.$('td', row).text(); #set ($persons="") #set ($datahtml = $renderContext.getEntity().getBodyAsString()) #foreach ($stringList in $datahtml.split("ri:userkey=\"")) #if ($stringList.matches("\w+\".*")) #set ($userkey=$stringList.substring(0,$stringList.indexOf('"'))) #if ($persons.length()>0) #set ($persons=$persons+", ") #end #set ($persons=$persons+"'"+$userkey+"'") #end #end console.log(calendar+" "+startDate+" "+startTime+" "+endTime+" "+where+" "+$persons); ${D}.ajax({ url: 'https://YOURCONFLUENCEURL/rest/calendar-services/1.0/calendar/events.json', //Your api url type: 'PUT', //type is any HTTP method data: { originalSubCalendarId:'', originalStartDate:'', subCalendarId:calendar, uid:'', eventType:'other', originalEventType:'', customEventTypeId:'', originalCustomEventTypeId:'', childSubCalendarId:'', what:'Fridays Meeting', person:[$persons], startDate:startDate, startTime:startTime, endDate:startDate, endTime:endTime, allDayEvent:false, freq:'', byday:'', interval:1, until:'', repeatEnds:false, recurrenceId:'', editAllInRecurrenceSeries:false, where:where, url:window.location.href, description:'', userTimeZoneId: 'Asia/Yekaterinburg' }, //Data as js object success: function () { $('.eventcreationresults').html(startDate+" "+startTime+" created!"); } }); }); }); </script> <form> <div class="eventcreationresults">...</div> <input id="submitevent" type="button" value="Create Event"> </form>
Создайте новый макрос в Confluence с этим кодом. Назовите его, например, {fridaymeetingeventcreation}
Теперь создайте новую страницу и добавьте на неё Page Properties с вот такими полями:
В конце Page Properties вставьте макрос {fridaymeetingeventcreation}
Проверьте, если всё работает, то включите эти макросы в шаблон страницы совещания и радуйтесь. Идентификатор календаря подсмотрите через Developer Console (F12) в Chrome.
При создании повестки, заполняйте свойства страницы. После сохранения страницы ОДИН раз нажмите Create Event, после чего удаляйте макрос {fridaymeetingeventcreation} из страницы, чтобы его больше никто не нажал. Скрипт не проверяет – существует ли событие уже. И скрипт не умеет обновлять существующее событие. И пока относитесь с подозрением к нему вообще, перепроверяйте созданные события.
Если мероприятие начинается в 11 и заканчивается в 12, то это 11:00 AM и 12:00 PM! В противном случае будет ошибка (конец мероприятия раньше начала)
Комментарии по исходнику
Я стал создавать разные тестовые события и записывать содержимое запроса через Developer Console (F12) в моём браузере Chrome
Выяснилось, что при создании события улетает PUT-запрос на /rest/calendar-services/1.0/calendar/events.json
Пример аргументов REST запроса:
originalSubCalendarId:”,
originalStartDate:”,
subCalendarId:’4caacdf7-f012-4444-b36a-0b509d61db04′,
uid:”,
eventType:’other’,
originalEventType:”,
customEventTypeId:”,
originalCustomEventTypeId:”,
childSubCalendarId:”,
what:’Fridays Meeting’,
person:[‘4028e4ed4f4a9806014f4a9a26a800f5′,’4028e4ed4f4a9806014f4a9a25f900bc’,’4028e4ed4f4a9806014f4a9a1e4f0001′,’4028e4ed4f4a9806014f4a9a25ef00aa’,’4028e4ed4f4a9806014f4a9a26aa00fd’,’4028e4ed4f4a9806014f4a9a2538003d’],
startDate:startDate,
startTime:startTime,
endDate:startDate,
endTime:endTime,
allDayEvent:false,
freq:”,
byday:”,
interval:1,
until:”,
repeatEnds:false,
recurrenceId:”,
editAllInRecurrenceSeries:false,
where:where,
url:window.location.href,
description:”,
userTimeZoneId: ‘Asia/Yekaterinburg’
Даты имеют формат “May 3, 2017”, время имеет формат “11:00 AM”, участники митинга указываются внутренними идентификаторами.
Постскриптум
Люди с прямыми руками могут переделать скрипт так, чтобы он при вставке макроса просил заполнить нужные поля визардом. Это красивее и правильней. И, конечно, можно получать идентификатор события и не позволять второй раз добавлять событие в календарь. И ещё было бы круто уметь апдейтить мероприятие.
Если вы что-то из этого сделали – напишите мне, я тоже буду рад воспользоваться вашими наработками.