'Calendar info using confluence API

I have a Confluence page which has a Calendar inside it (please check photo below). Calendar I am trying to pull information from this calendar, like how many events in each day. nothing more.

i used a code from stackoverflow that reads Confluence page using API. but the json response does not contain any data about the calendar inside the page.

`import requests
import json
from requests.auth import HTTPDigestAuth
confluence_host = "https://confluence.tools.mycompany.com"
url = confluence_host + '/rest/api/content/'
page_id = "36013799"
page = requests.get(url=url + page_id,
                       params={'expand': 'body.storage'},
                   auth=('my_user', 'my_password') ).json()`

Even if i write, html = page['body']['storage']['value'] and check its output, it only gives this:

name="calendar" ac:schema-version="1" ac:macro-id="99a26d73-abaa-45a1-92cc-0edafec567f5">72da4ae5-4888-46dd-9078-0299b51ab815,743a55b4-7b3b-4e00-b102-90d95916de8d

Is there any way to get the calendar info ?

Thanks



Solution 1:[1]

You are using Team Calendar in your page and Team Calendar is a plugin in your page. Technically, /rest/api/content only gives you the content of the page not the Content of the Plugins. As far as I know, Team Calendar doesn't have Public Rest API as you can see on CONFSERVER-51323 but you can get the data that you want from the database instead of REST API since Team Calendar has already creates couple of AO Tables in your database.

Solution 2:[2]

I found it easiest to get the subscribe link to the calendar then use an iCalendar library to parse the data. Make sure the subscribe button gives you a link with a {guid}.ics and not undefined.ics - To solve that I had to go to the calendars link in the main confluence space and then select it from the dropdown. You may have to create an empty calendar so you can select a cal.

Solution 3:[3]

I was able by looking at the GET and PUT, there is a rest API used by the javascript plugin (rest/calendar-services/1.0/calendar/events.json):

you need to find out your: subCalendarId='yourID'

urlC = 'https://yourconfluence.com/rest/calendar-services/1.0/calendar/events.json?subCalendarId=40xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&userTimeZoneId=America%2FMexico_City&start=2018-11-28T00%3A00%3A00Z&end=2018-11-28T00%3A00%3A00Z'

r = requests.get(urlC, auth=("myuser", "mypass"), timeout=15)

that will return all the records on that period:

a = r.json()

a.keys()

[u'events', u'success']

a['success']

True

type(a['events'])

list

len(a['events'])

61

Use the following data in a PUT to add new events:

data = { "subCalendarId": "xxx-xxx-xxx", "eventType": "custom", "customEventTypeId": "xxx-xxx-xxx", "what": "My Test", "person": "xxxxxxxxxxxxxxxxx", "startDate": "28-Nov-2018", "startTime": "15:00", "endDate": "28-Nov-2018", "endTime": "16:00", "allDayEvent": "false", "editAllInRecurrenceSeries": "true", "where": "Some Place", "description": "My testing Case", "userTimeZoneId": "America/Mexico_City",}

urlC = 'https://yourconfluence.com/rest/calendar-services/1.0/calendar/events.json'

r = requests.put(urlC, auth=('username', 'pass'), data=data, timeout=15)

that will return a 'success': true with the new entry:

u'{"success":true,"subCalendar":{"reminderMe":false,........}}

Solution 4:[4]

After going through the developer console in chrome, After analyzing the format of the payload and required authentication details I found solution for this,

My problem statement was little different I have to add the event to confluence calendar, Both adding event and extracting event will follow the same process.

There are few cookies which are required for authentication like JSESSIONID and seraphConfluence Which will be stored in the application -> cookies in chrome developer tool. and also we require the subCalenderid and Id Type which can be taken from the application-> local storage in in chrome developer tool.

and also , The confluence will send request using 'application/x-www-form-urlencoded' as Content-Type, So in the data we should have it in encoded format, For this we can use below code to convert to that format

import urllib
urllib.parse.quote_plus('May 4, 2022') 

output:

'May+4%2C+2022'

And also date and type should be in the MMM D, YYYY and h:MM A format you can use arrow python package to do the work

arrow.utcnow.format(MMM D, YYYY)

output

May 4, 2022

Below there is a string from the request payload in chrome when it send put request when we click add event , if we analyse the string we can see that we have

confirmRemoveInvalidUsers=false&childSubCalendarId=&customEventTypeId=asdfghjk-asdf-asdf-asfg-sdfghjssdfgh&eventType=custom&isSingleJiraDate=false&originalSubCalendarId=&originalStartDate=&originalEventType=&originalCustomEventTypeId=&recurrenceId=&subCalendarId=asdfghjk-asdf-asdf-asdg-asdfghjkl&uid=&what=test&startDate=May+4%2C+2022&startTime=&endDate=May+4%2C+2022&endTime=&allDayEvent=true&rruleStr=&until=&editAllInRecurrenceSeries=true&where=&url=&description=&userTimeZoneId=America%2FNew_York

After analysing it we can come to conclution we have to replace start date,enddate , start and end time, what , where , subcalendar id and type and other fields with our code and send the request.

Below is the code which will do that

def addEventtoCalender():
    reqUrl = 'https://confluence.yourdomain.com/rest/calendar-services/1.0/calendar/events.json'
    authDetails = getConfluenceAuthenticationDetails()
    what=urllib.parse.quote_plus('WHAT field data')
    startDate = urllib.parse.quote_plus(arrow.utcnow().format('MMM D, YYYY'))
    startTime=urllib.parse.quote_plus(arrow.utcnow().format('h:MM A'))
    endDate=urllib.parse.quote_plus(arrow.utcnow().format('MMM D, YYYY'))
    endTime=urllib.parse.quote_plus(arrow.utcnow().shift(hours=+1).format('h:MM A'))
    where=urllib.parse.quote_plus('WHERE field data')
    url=urllib.parse.quote_plus('https://yoururl.com')
    description=urllib.parse.quote_plus('test test test')
    customEventTypeId = authDetails['CONFLUENCE_CUSTOM_EVENT_TYPE_ID'] #subcalender type
    subCalendarId = authDetails['CONFLUENCE_SUBCALENDAR_ID']
    seraphConfluence =  authDetails['CONFLUENCE_SERAPH_CONFLUENCE']
    JSESSIONID = authDetails['CONFLUENCE_JSESSION_ID']
    data = f'confirmRemoveInvalidUsers=false&childSubCalendarId=&customEventTypeId={customEventTypeId}&eventType=custom&isSingleJiraDate=false&originalSubCalendarId=&originalStartDate=&originalEventType=&originalCustomEventTypeId=&recurrenceId=&subCalendarId={subCalendarId}&uid=&what={what}&startDate={startDate}&startTime={startTime}&endDate={endDate}&endTime={endTime}&allDayEvent=false&rruleStr=&until=&editAllInRecurrenceSeries=true&where={where}&url={url}&description={description}&userTimeZoneId=America%2FNew_York'
 
    headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Cookie': f'seraph.confluence={seraphConfluence}; JSESSIONID={JSESSIONID}'
    }
    res = requests.put(url=reqUrl,data=data,headers=headers,verify=False)

Above code will replicate the whole process of adding event to calendar. You can use the same approach to replicate getting all event between particular dates.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Saleh Parsa
Solution 2 Frobbit
Solution 3
Solution 4 Subramanya Krishna