Events carry more structure than emails — a title lives under one key, a start time lives in a nested dict. What's the clean way to pull both into one row?
Read summary off the event for the title, reach into start.dateTime for the timestamp, then pass both as one row to the append call?
Exactly. event.get("start", {}) first to grab the nested dict safely, then .get("dateTime", "") for the string. Two layers, two defaults, no crashes:
events = toolset.execute_action(Action.GOOGLECALENDAR_FIND_EVENT, {"query": query})
items = events.get("items", [])
for event in items:
title = event.get("summary", "")
start = event.get("start", {}).get("dateTime", "").get("start", {}).get("dateTime", "") chained — if start is missing, the {} default keeps the second .get safe?
Exactly. An empty dict still supports .get, so the second call returns "". Your row always has two strings in it regardless of what shape the event carries:
def calendar_to_sheet(query: str, spreadsheet_id: str) -> int:
events = toolset.execute_action(Action.GOOGLECALENDAR_FIND_EVENT, {"query": query})
items = events.get("items", [])
count = 0
for event in items:
title = event.get("summary", "")
start = event.get("start", {}).get("dateTime", "")
toolset.execute_action(Action.GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND, {
"spreadsheetId": spreadsheet_id, "range": "Sheet1",
"values": [[title, start]], "valueInputOption": "USER_ENTERED",
})
count += 1
return countWhat if an event has no summary — is an empty title useful or should I skip it?
Depends on the downstream use. Appending a blank cell keeps row alignment so column 1 is always "title"; skipping keeps the log tidy but breaks positional analysis. For a growing log, keep everything and filter later.
So every matching event becomes a row — title column, timestamp column — ready for pivots or charts?
That is the payoff of a structured log. A pivot table on two clean columns beats a scroll through a calendar every time.
TL;DR: Reach into nested dicts with .get(key, {}) before the next .get — every layer defaults.
summary is the title, start.dateTime is the timestampevent.get("start", {}).get("dateTime", "") is two safe hops[title, start] lands as two columns in the sheet| Layer | Default |
|---|---|
event.get("start", {}) | empty dict |
.get("dateTime", "") | empty string |
| row fallback | ["", ""] — columns stay aligned |
Events carry more structure than emails — a title lives under one key, a start time lives in a nested dict. What's the clean way to pull both into one row?
Read summary off the event for the title, reach into start.dateTime for the timestamp, then pass both as one row to the append call?
Exactly. event.get("start", {}) first to grab the nested dict safely, then .get("dateTime", "") for the string. Two layers, two defaults, no crashes:
events = toolset.execute_action(Action.GOOGLECALENDAR_FIND_EVENT, {"query": query})
items = events.get("items", [])
for event in items:
title = event.get("summary", "")
start = event.get("start", {}).get("dateTime", "").get("start", {}).get("dateTime", "") chained — if start is missing, the {} default keeps the second .get safe?
Exactly. An empty dict still supports .get, so the second call returns "". Your row always has two strings in it regardless of what shape the event carries:
def calendar_to_sheet(query: str, spreadsheet_id: str) -> int:
events = toolset.execute_action(Action.GOOGLECALENDAR_FIND_EVENT, {"query": query})
items = events.get("items", [])
count = 0
for event in items:
title = event.get("summary", "")
start = event.get("start", {}).get("dateTime", "")
toolset.execute_action(Action.GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND, {
"spreadsheetId": spreadsheet_id, "range": "Sheet1",
"values": [[title, start]], "valueInputOption": "USER_ENTERED",
})
count += 1
return countWhat if an event has no summary — is an empty title useful or should I skip it?
Depends on the downstream use. Appending a blank cell keeps row alignment so column 1 is always "title"; skipping keeps the log tidy but breaks positional analysis. For a growing log, keep everything and filter later.
So every matching event becomes a row — title column, timestamp column — ready for pivots or charts?
That is the payoff of a structured log. A pivot table on two clean columns beats a scroll through a calendar every time.
TL;DR: Reach into nested dicts with .get(key, {}) before the next .get — every layer defaults.
summary is the title, start.dateTime is the timestampevent.get("start", {}).get("dateTime", "") is two safe hops[title, start] lands as two columns in the sheet| Layer | Default |
|---|---|
event.get("start", {}) | empty dict |
.get("dateTime", "") | empty string |
| row fallback | ["", ""] — columns stay aligned |
Create a free account to get started. Paid plans unlock all tracks.