@@ -418,6 +418,13 @@ export class GoogleCalendar
418418 calendarId : string ,
419419 initialSync : boolean
420420 ) : Promise < void > {
421+ // Hoist callback token retrieval outside loop - saves N-1 subrequests
422+ const callbackToken = await this . get < Callback > ( "event_callback_token" ) ;
423+ if ( ! callbackToken ) {
424+ console . warn ( "No callback token found, skipping event processing" ) ;
425+ return ;
426+ }
427+
421428 // Get user email for RSVP tagging
422429 for ( const event of events ) {
423430 try {
@@ -448,7 +455,7 @@ export class GoogleCalendar
448455
449456 // Check if this is a recurring event instance (exception)
450457 if ( event . recurringEventId && event . originalStartTime ) {
451- await this . processEventInstance ( event , calendarId , initialSync ) ;
458+ await this . processEventInstance ( event , calendarId , initialSync , callbackToken ) ;
452459 } else {
453460 // Regular or master recurring event
454461 const activityData = transformGoogleEvent ( event , calendarId ) ;
@@ -538,10 +545,7 @@ export class GoogleCalendar
538545 const hasDescription = description && description . trim ( ) . length > 0 ;
539546 const hasLinks = links . length > 0 ;
540547
541- const callbackToken = await this . get < Callback > (
542- "event_callback_token"
543- ) ;
544- if ( ! callbackToken || ! activityData . type ) {
548+ if ( ! activityData . type ) {
545549 continue ;
546550 }
547551
@@ -599,7 +603,8 @@ export class GoogleCalendar
599603 private async processEventInstance (
600604 event : GoogleEvent ,
601605 calendarId : string ,
602- initialSync : boolean
606+ initialSync : boolean ,
607+ callbackToken : Callback
603608 ) : Promise < void > {
604609 const originalStartTime =
605610 event . originalStartTime ?. dateTime || event . originalStartTime ?. date ;
@@ -675,11 +680,6 @@ export class GoogleCalendar
675680
676681 // Send occurrence data to the twist via callback
677682 // The twist will decide whether to create or update the master activity
678- const callbackToken = await this . get < Callback > ( "event_callback_token" ) ;
679- if ( ! callbackToken ) {
680- console . warn ( "No callback token found for occurrence update" ) ;
681- return ;
682- }
683683
684684 // Build a minimal NewActivity with source and occurrences
685685 // The twist's createActivity will upsert the master activity
@@ -698,8 +698,9 @@ export class GoogleCalendar
698698 authToken : string
699699 ) : Promise < void > {
700700 // Validate webhook authenticity
701- const channelId = request . headers [ "X-Goog-Channel-ID" ] ;
702- const channelToken = request . headers [ "X-Goog-Channel-Token" ] ;
701+ // Headers are normalized to lowercase by HTTP standards
702+ const channelId = request . headers [ "x-goog-channel-id" ] ;
703+ const channelToken = request . headers [ "x-goog-channel-token" ] ;
703704
704705 if ( ! channelId || ! channelToken ) {
705706 throw new Error ( "Invalid webhook headers" ) ;
0 commit comments