Search code examples
google-calendar-api

Embedding script for Google Calendar text description


I am trying to set the description of a Google Calendar event to have a different selected presenter that is chosen in a rotatory manner (it is a slide deck that needs to be presented by a different person each week). The Python script specifying the rationale would work as the following

import datetime
people = ['Person 1', 'Person 2', 'Person 3']
year, week, day = datetime.date.today().isocalendar()
print(people[week_of_year % len(people)])

the resulting person from this calculation would show up in the calendar event description. Is there any tool to do that?


Solution

  • I was not able to find a way to create a recurrent event with different descriptions for each event.

    However, I found a workaround for you using Events: patch. You first create an event using Events: insert, get the ID of the event you created with Events: list, and after that, then get the ID of the recurrences using Events: instances. Lastly, you use Events: patch to add the new description.

    It might sound long, but I'm adding a sample with explanations on how to use it.

    # impor the libraries that you will use for the calendar API
    
    from __future__ import print_function
    
    import os.path
    
    from google.auth.transport.requests import Request
    from google.oauth2.credentials import Credentials
    from google_auth_oauthlib.flow import InstalledAppFlow
    from googleapiclient.discovery import build
    from googleapiclient.errors import HttpError
    
    # The scopes that we need to use based on the Google documentation
    # I added the information in the reference at the end of the answer
    
    SCOPES = ['https://www.googleapis.com/auth/calendar', 
            'https://www.googleapis.com/auth/calendar.events']
    
    # creation of the credential, I use as a base the Google Documentation "Python quickstart"
    
    def main():
        creds = None
    
        if os.path.exists('token.json'):
            creds = Credentials.from_authorized_user_file('token.json', SCOPES)
        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    'credentials.json', SCOPES)
                creds = flow.run_local_server(port=0)
            with open('token.json', 'w') as token:
                token.write(creds.to_json())
    
        try:
            service = build('calendar', 'v3', credentials=creds)
    
            # The list of people that will be use in each event 
            peoples = ['Person 1', 'Person 2', 'Person 3', 'Person 4']
            number_week = 0
    
            event = {
                # Event title
                'summary': 'Testing create description',
                # A test description will be replaced later, so you can add anything you want to it. 
                'description': 'test',
                # The start and end dates need to be in ISO-8601 date format
                # and the time zone needs to be formatted as an IANA Time Zone Database name, e.g. "Europe/Zurich 
                'start': {
                    'dateTime': '2022-10-28T09:00:00-07:00',
                    'timeZone': 'America/Los_Angeles',
                },
                'end': {
                    'dateTime': '2022-10-28T17:00:00-07:00',
                    'timeZone': 'America/Los_Angeles',
                },
                'recurrence': [
                # You can change the recurrence of the event 
                # for this example is a weekly event, and it has 4 recurrences
                    'RRULE:FREQ=WEEKLY;COUNT=4'
                ],
                # The list of attendees
                'attendees': [
                    {'email': 'test@email.xyz'},
                    {'email': 'test2@email.xyz'},
                ],
                'reminders': {
                    'useDefault': False,
                    'overrides': [
                    {'method': 'email', 'minutes': 24 * 60},
                    {'method': 'popup', 'minutes': 10},
                    ],
                },
                }
    
            # We use insert to create the event
            event = service.events().insert(calendarId='primary', body=event).execute()
            # You can use the print in the next line to see the information about the event while you are testing
            # print('Event created: %s' % (event.get('htmlLink')))
            page_token = None
    
            # Search for the event, using the method list and the event title q='Testing create description'
            # you can use any other search key to get the event ID
            events = service.events().list(calendarId='primary', pageToken=page_token, q='Testing create description').execute()  
                  
            # get the ID of the event
            for event in events['items']:
                # print(event['id'])
                id_event = event['id']
    
    
                # Will search the ID of the recurrences of the event using the method instances 
                # e.g. xxxxxxxxxxxxxxxxx_20221028T160000Z                    
                while True:
                    recurrences_for_events = service.events().instances(calendarId='primary', eventId=id_event,
                                          pageToken=page_token).execute()
    
                    # run the dictionary of each iteration     
                    for recurrence_instance in recurrences_for_events['items']:
                        id_to_update = recurrence_instance['id']
                        # I used the next print just to review the IDs of each event
                        # print(id_to_update)
    
                        # Create the new body of the event with the name of the people in the list of peoples
                        # instead of using year, week, day = datetime.date.today().isocalendar(). I use a simple counter to iterate on the list
                        body = {
                            'description': peoples[number_week],                        
                        }
                        # update the event description with patch
                        updated_event = service.events().patch(calendarId='primary', eventId=id_to_update, body=body).execute()
                        # print(updated_event['description'])
                        # next patch in case you have a large recurrence of the event
                        page_token = events.get('nextPageToken')
                        number_week += 1
    
                        # This will reset the counter, in case the number of people is less than the recurrences of the event
                        if number_week >= len(peoples):
                            number_week = 0
    
                    if not page_token:
                        break
                
    
        except HttpError as error:
            print('An error occurred: %s' % error)
    
    
    if __name__ == '__main__':
        main()
    

    If the recurrent event has already been created, you only need to use the imports until the number_week = 0, and the part from:

    events = service.events().list(calendarId='primary', pageToken=page_token, q='Testing create description').execute() 
    

    To the end, you might need to modify the for loop to only run once per recurrence.

    Reference: