Copy Outlook Calendar Events with Logic Apps or Power Automate
Automatically sync multiple Outlook Calendars to one ‘main’ Calendar
Working as a consultant sometimes means having multiple mail addresses and calendars to manage. Up until now, I added Calendar events from my client manually to my ‘main’ calendar, just to keep it up to date for my colleagues and avoid two meetings at the same time.
After multiple attempts of trying to fix this through the outlook client, I decided to try a different approach. Logic Apps and Power Automate have out of the box connectors for Office 365 Outlook.
What looked like a very simple solution at first, escalated pretty quickly. Besides adding a new event, I wanted to handle updates and deletes as well.
I’ll give a detailed description of the Logic App I created. All steps can be reproduced in Power Automate as well.
Logic App Setup
Trigger to start the process
To trigger the app, I used the Office 365 connector ‘When an event is added, updated, or deleted (V3)’. This connector makes use of the Microsoft Graph API. The trigger is authenticated with the credentials of the account from which you want to send the events (source calendar). This new version of the connector is triggered almost instantly when an event gets added, updated, or deleted in the connected Calendar. The type of event is displayed in the ‘Action Type’ field.
After the trigger we initialize a variable, we need this in a later stadium for updated events.
Switch on Action Type
Depending on the ‘Action Type’ we define different actions. For this, I use a ‘Switch’ action. Let’s start with the simple one, ‘added’.
Added logic
If the ‘Action Type’ equals ‘added’ I want to add a new event to my ‘main’ outlook account. The connector used is ‘Create event (V4)’. This one is authenticated with the ‘target’ account. The information I use to create the event is derived from the trigger. There are two adjustments I made compared to the original appointment.
1. The subject; I added something to recognize the source calendar. In this case, a short name to recognize the client: ‘ABC:’.
2. The body; I am not interested in the original body of the appointment. The only thing I add here is the ‘Id’ field. I need this later on when updating existing appointments.
If you like you can set additional parameters, like reminders and how it is displayed in the Calendar.
Updated
If the ‘Action Type’ is ‘updated’ I want to change the existing event in the target calendar, when it is not there, I want to add it. This is where it gets a little more complicated, but not undoable.
Get Events
The first thing to do is to check the target calendar if we can find the event that needs to be updated. We do this with the ‘Get events (V4)’ action. The action uses an OData protocol to get the events from your account.
My intuition was to filter the results on the ‘Id’-field we added to the body of the event. But I kept getting errors, probably because the body is Html. To solve this we need two steps:
- Get a list of events by Subject
- Loop through the list to find the right event
To filter the results of the ‘Get events’ we can use the following expression:
contains(Subject, '@{triggerBody()?['subject']}')
Loop through all Events
Now we will try to find the right event by looking for the ‘Id’ field in the body of the event.
If we find the right event, we delete it and create it again with the new information. After that, we set the variable to ‘true’.
In the delete action, it is important to use the ‘Id’ that we get from the ‘Get Events’ action because this corresponds with the previously created event.
Add if Event wasn’t found
If for any reason the event is not found, I want to add those too. For this, we initialized the variable at the top level of the Logic App. If the event was not found in the previous step, the variable will still be ‘false’. Meaning that we are missing this event in our target calendar. Thus we create it in the same way we did in the first added action
Deleted
When an event is deleted in the source calendar, I want to remove it from the target calendar as well. Basically, I do the same steps as when the ‘Action Type’ is ‘updated’. There is one downside, the trigger returns very little information about the event. There is only the ‘Id’ of the event we can search for in the body of the appointments. This means I can only filter on the short name I added in the subject to filter the results.
Not filtering the query in the ‘Get Events’ action can take significantly more time and therefore is more expensive in the end.
Wrap Up
That’s it! We can now add appointments from one calendar to another, update them if they change, and delete them when needed!
I admit it is not a perfect solution. Recurring appointments from the source calendar are not handled in the best way.
And I would really like to add a category to the created events. The Graph API docs tell me that it should be possible, but I didn’t manage to get it working with these Office 365 Connectors.
Let me know if you see any improvements!