Skip to content

Commit 0b4d8ad

Browse files
committed
📜 Docs: separate recurring events doc into two for clarity
1 parent fdf4de5 commit 0b4d8ad

2 files changed

Lines changed: 277 additions & 184 deletions

File tree

Lines changed: 1 addition & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Recurring Events
1+
# Recurring Events - Overview
22

33
## Core Concepts
44

@@ -176,186 +176,3 @@ Google Calendar uses specific ID patterns to identify events:
176176
- Helps maintain history
177177
- Allows for potential restoration
178178
- Maintains relationships between events
179-
180-
## Synchronization Workflow
181-
182-
### Overview
183-
184-
Synchronizing recurring events with Google Calendar involves:
185-
186-
1. Initial setup and watching for changes
187-
2. Receiving notifications when changes occur
188-
3. Fetching the changed events
189-
4. Analyzing the changes
190-
5. Updating your database accordingly
191-
192-
### Initial Setup
193-
194-
1. **Watch for Changes**
195-
196-
- Set up a webhook to receive notifications from Google Calendar
197-
- Store the `nextSyncToken` from the initial sync
198-
- This token is crucial for incremental updates
199-
200-
2. **Initial Sync**
201-
- Fetch all events for the calendar
202-
- Store the final `nextSyncToken` for future use
203-
- This establishes your baseline state
204-
205-
### Change Detection
206-
207-
When changes occur in Google Calendar:
208-
209-
1. **Notification Received**
210-
211-
- Google sends a notification to your webhook
212-
- The notification indicates which calendar changed
213-
- No event details are included in the notification
214-
215-
2. **Fetch Changes**
216-
- Use the stored `nextSyncToken` to fetch only changed events
217-
- Google returns:
218-
- Modified events
219-
- New events
220-
- Deleted events (marked as "cancelled")
221-
- A new `nextSyncToken` for the next sync
222-
223-
```mermaid
224-
sequenceDiagram
225-
participant User
226-
participant Google
227-
participant Webhook
228-
participant App
229-
participant DB
230-
231-
Note over User,DB: Initial Setup
232-
User->>Google: Create Recurring Event
233-
Google->>App: Send Notification
234-
App->>Google: Fetch Changes
235-
Google-->>App: Return Events + nextSyncToken
236-
App->>DB: Store Events & Token
237-
238-
Note over User,DB: Sync Changes
239-
User->>Google: Modify Event
240-
Google->>Webhook: Send Notification
241-
Webhook->>App: Forward Notification
242-
App->>Google: Fetch Changes (with token)
243-
Google-->>App: Return Changes + new token
244-
App->>App: Analyze Changes
245-
App->>DB: Update Database
246-
App->>DB: Store new token
247-
```
248-
249-
## Splitting Series
250-
251-
### Problem Summary
252-
253-
When users modify recurring events in Google Calendar using "this and following" operations, we need to handle the resulting series splits in our sync system. These splits can occur in two scenarios:
254-
255-
1. Delete "this and following" - splits the series and deletes future instances
256-
257-
2. Edit "this and following" - splits the series and creates a new series with modified properties
258-
259-
The challenge is that Google Calendar's API sends these changes in potentially multiple payloads, and we can't rely on receiving all related changes in a single payload or in a specific order.
260-
261-
### Solution Overview
262-
263-
Treat each change as an independent operation based on the event's properties, not on payload combinations or ID patterns. This approach is more reliable as it:
264-
265-
1. Uses documented API properties
266-
267-
2. Doesn't rely on payload ordering
268-
269-
3. Handles each change atomically
270-
271-
4. Works consistently across all operation types
272-
273-
### Approach
274-
275-
Whenever a series is split, delete the following instances
276-
277-
- Don't worry about what caused the split -- differentiating between editing 'this and following' vs deleting 'this and following'
278-
279-
Has recurrence with UNTIL? → Original series being split
280-
Has recurringEventId? → Instance or new series
281-
Has status: "cancelled"? → Cancelled instance
282-
Has originalStartTime? → Modified instance
283-
284-
### Design Flow: Detecting Series Splits
285-
286-
```mermaid
287-
288-
graph TD
289-
290-
A[Receive Google Calendar Event] --> B{Has recurringEventId?}
291-
292-
B -->|Yes| C{Status = cancelled?}
293-
294-
C -->|Yes| D[Delete Instance]
295-
296-
C -->|No| E[Update Instance]
297-
298-
B -->|No| F[Fetch Current State]
299-
300-
F --> G{Is Series Split?}
301-
302-
G -->|Yes| H[Update Original Series]
303-
304-
G -->|No| I[Create/Update Series]
305-
306-
307-
308-
H --> J[Delete Future Instances]
309-
310-
I --> K[Generate New Instances]
311-
312-
313-
314-
subgraph "Series Split Detection"
315-
316-
G -->|Compare| L[UNTIL Dates]
317-
318-
L -->|Earlier| G
319-
320-
end
321-
322-
```
323-
324-
### Anti-Pattern Design Flow
325-
326-
We're sharing this flawed approach because it seems like a logical way to approach the problem, but it doesn't work. Do not do this.
327-
328-
```mermaid
329-
graph TD
330-
subgraph "Sync Process"
331-
Watch[Watch for Changes] -->|1. Notification| Notify[Receive Notification]
332-
Notify -->|2. Fetch| Fetch[Fetch Changes]
333-
Fetch -->|3. Analyze| Analyze[Analyze Changes]
334-
Analyze -->|4. Update| Update[Update Database]
335-
Update -->|5. Store Token| Token[Store nextSyncToken]
336-
end
337-
338-
subgraph "Change Types"
339-
Create[Create Series]
340-
EditOne[Edit One Instance]
341-
EditFuture[Edit This & Future]
342-
EditAll[Edit All Instances]
343-
DeleteOne[Delete Instance]
344-
DeleteAll[Delete Series]
345-
end
346-
347-
Analyze -->|determines| Create
348-
Analyze -->|determines| EditOne
349-
Analyze -->|determines| EditFuture
350-
Analyze -->|determines| EditAll
351-
Analyze -->|determines| DeleteOne
352-
Analyze -->|determines| DeleteAll
353-
```
354-
355-
The flawed assumption is that you will be able to determine the user's action based on the payloads
356-
that you receive from Google Calendar after a notification is received. Unfortunately, this is not the case.
357-
Google Calendar API batches changes, and does not return them in a way that corresponds to what
358-
caused the change.
359-
360-
Because of this, you are better off treating each change as an independent operation, without regard
361-
for what caused the change.

0 commit comments

Comments
 (0)