EDIT 1: I was typing this content but when I clicked post I had an authentication issue... 3 hours of work... gone... As I am not going to do this again for a while, I will just be posting the pictures and editing the text later.
EDIT 2: I have adapted the content and made it a little friendlier to read with some explanation 🙂 If you keep attention to this blog, you'll see that sections are adapted over time as I hit the "post" button quite frequently to not have the scenario of yesterday happening again.
Dear Reader,
When you want to build a flow app or a powerapps, you need to make sure you come well prepared. You need to make sure what the end goal is and how you will reach that goal. In this guide I will tell you how I designed this flow app and my logic behind this. I do this for 2 reasons. Exposure in the community and so I do not forget myself.
The reason why I needed to create this application was because I wanted to synchronize my agenda calendar with my car. Since the car I am driving does not support Office 365, but google calendar does, I wanted to sync my agenda to a "car calendar" account without management overhead of managing 2 calendars. Please join me in this journey of automation below.
Why should you trust this "blog"? I might not be a Microsoft representative, but I am someone who breathes automation on many layers. Optimization in a company is my strength and I have gone freelance to provide other enterprises with this service.
The first thing you need to know is to create a good flowchart (this is something else than a flow app). the flowchart is needed so you can go through your process easily. Let's start with creating one.
The flowchart you need to follow:
The flow you need to follow
It is important to know, that you need to check your flowchart its "soundness" and go through each single scenario. Your process can start with three triggers:
- When an event is added in an Office 365 specific calendar
- When an event is modified in an Office 365 specific calendar
- When an event is deleted in an Office 365 specific calendar
Start from the beginning and make sure you don't end up in a loop or with a "flow" you are stuck. All scenario's need to be covered. Once you have that ready, you can start creating your flow application. This is important as automation has a very high impact if done without caution. Imagine not having a flow for removing an event? What do you do if you have a recurrence set up for 10 years with a break between 12:00-13:00? You remove this event in Office 365 but it stays in your Google calendar? As this will create 1 event for each single event you have, you can't hit "delete all" and you have to delete all 1-by-1. When going through this flowchart, think of the consequences for not implementing a certain scenario, what is the impact for you? Make sure to cover that as well.
Next you will find the entire flow, I will go through each single field and explain why I do certain settings. In case something is not explained, please refer to it in the comments or check if the setting is a standard setting set by flow.
The entire flow:
How to synchronize Office 365 Calendar to Google Calendar
Let's go through them one by one:
Trigger conditions
This is the trigger. Once you login to the account that is needed, you can choose a calendar. Whenever an item is:
- Created
- Deleted
- Modified
This triggers the flow app.
Let's zoom in on fetching events from Google Calendar part
Get all Google calendar items that contain the same ID as the Outlook item.
We search for all items that are within the Google Calendar that have the same ID as the event that triggered this flow app. this is to check if the event exists in the calendar you are going to copy to. In case you don't know why, checkout the flowchart shown in the beginning.
This flow action returns a JSON object. To get content out of this JSON object, you need to parse the object. Parsing can be seen as "reading out" the object and making sure you can utilize the properties of the object easily. I'll show you how I found the template and what data is in the object.
Parse a JSON object, as the object itself will never be empty but a certain property we are interested in is.
Get all events back as an object and get the event list property.
To see what code is in that object, you can send a notification. That notification (phone / email / ...) contains the JSOn object and that is how you can see what is inside.
Add this event to look at an object
Object itself if you want to copy and paste it for your own use cases.
"""
{
"kind": "calendar#events",
"etag": "\"************************\"",
"summary": "julio********************",
"updated": "2020-01-26T20:49:12.357Z",
"timeZone": "Europe/Berlin",
"accessRole": "owner",
"defaultReminders": [
{
"method": "popup",
"minutes": 30
}
],
"items": []
}
"""
I did not write the code myself. I load a sample in the parse JSON flow action and then flow will generate the correct code for you. It is very easy to do. Just copy paste the above code into the sample page.
To get the correct code in, click on generate from sample:
Click the generate from sample button
In this new page, copy and paste the code from above.
Copy and paste the flow sample JSON code from above
The code will be generated and will give you the option to use the properties in an easy way.
Once the sample code is injected, you can call specific properties from that flow event
Now you have parsed the JSON object, let's look at the action to see if the list is empty:
Check if the list that was fetched is empty
Code expression on the left:
empty(body('Parse_JSON-object_of_fetched_events_and_get_all_items_out')?['items'])
Code expression on the right:
true
explanation:
empty() = Returns true if an object, array, or string is empty. Explicitly for our use case this means whatever object is in there, if that object empty, it will return a boolean true. If it is not empty, it will return a boolean false. That returned value is checked against the static value true. If boolean true = true --> object is empty, if boolean false = true --> object is not empty. This is how we can use flow to check whether the list is empty or not. If you just fill in the JSON object here, it will never be empty, as the JSON object always exists, but the "event list" property from that JSON object could be empty.
Explenation of the empty() functionBody(your flow action here) = an alias for actions(your flow action here).outputs.body --> it returns the objects its content. If the object is an array, the returned object is an array. If the object is a string, it is a string, if the object is an object, it is an object. you get the point 🙂
Body function explainedParse_JSON-object_of_fetched_events_and_get_all_items_out = the name of the flow event. If you have spaces in the name, replace them with underscores/
?['items'] --> select the 'items' property from that event but do not error if the property is empty. that is why the '?' character is there.
This is all code explained. Let's continue with the flow.
If yes = list is empty
If no = list contained an event
What to do in case of the list being empty or notLet's go in the flow of not finding a calendar item first.
In case the list is empty, this is what needs to happenYou can see nothing happens when the action trigger = deleted.
Please see the flowchart why I do nothing here. Can you provide the answer why? 🙂
If any other trigger action, the event needs to be created.
Create a google calendar event and add the event ID in the bodyThis is where the flow could end. Mostly I like to check upon my flow and give myself a good notification. that's why I add this at the end:
custom notification depending where it triggeredThe other flow is almost the same, just don't create an event and update it instead. (as you found one with the exact ID already present in the Google Calendar.)
Also remove the event from Google Calendar if the event trigger was a delete trigger. otherwise you will have an item still visible in google while it should not be there.
The entire flow if an event is found before
This is the end of the post. The pictures should be self explanatory. In case you have any questions, feel free to comment on this blog. I should receive a notification about this.
Need more advanced help? Send me a message and let's see how I can be of service 🙂