Skip to main content

Property Reference

This is the complete reference for all properties and methods available when writing gate functions. Consult this page while working in the Code Editor or reviewing code generated by the AI Generator.

GateEvent Properties

Every gate function receives a GateEvent object. It contains the event's core data plus computed convenience properties that simplify common checks.

Core Properties

These are the fundamental properties of every calendar event:

PropertyTypeDescriptionExample Value
titlestringEvent title/summary"Team Standup"
descriptionstring | nullEvent description/notes"Daily sync meeting"
locationstring | nullEvent location"Conference Room A"
start{ dateTime: string, timeZone: string | null }Event start time (ISO 8601){ dateTime: "2026-02-14T14:00:00Z", timeZone: "America/New_York" }
end{ dateTime: string, timeZone: string | null }Event end time (ISO 8601){ dateTime: "2026-02-14T15:00:00Z", timeZone: "America/New_York" }
isAllDaybooleanWhether the event is an all-day eventfalse
status'confirmed' | 'tentative' | 'cancelled'Event confirmation status"confirmed"
showAs'free' | 'busy' | nullFree/busy status"busy"
attendeesArray<{ email: string, displayName?: string }>List of event attendees[{ email: "alice@example.com", displayName: "Alice" }]
organizer{ email: string, displayName?: string } | nullEvent organizer{ email: "bob@example.com", displayName: "Bob" }
recurrencestring[] | nullRecurrence rules (iCalendar RRULE format)["RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR"]

Computed Convenience Properties

These are read-only properties computed from the core properties. They simplify common checks so you don't have to parse dates or count arrays yourself.

PropertyTypeDescriptionExample Value
startDatestringAlias for start.dateTime (ISO 8601)"2026-02-14T14:00:00Z"
endDatestringAlias for end.dateTime (ISO 8601)"2026-02-14T15:00:00Z"
durationMinutesnumberEvent duration in minutes60
dayOfWeeknumberDay of week (0 = Sunday, 6 = Saturday)1 (Monday)
hournumberHour of day the event starts (0-23)14 (2 PM)
isWeekdaybooleanWhether the event falls on Monday-Fridaytrue
attendeeCountnumberNumber of attendees5
info

Computed properties are derived from core properties at sync time. For example, durationMinutes is calculated from start.dateTime and end.dateTime, and isWeekday is derived from dayOfWeek.

Helper Methods

GateEvent provides two helper methods for common pattern matching. Both perform case-insensitive matching.

MethodSignatureReturnsDescription
hasAttendee(pattern)(pattern: string) => booleanbooleanSearches attendee email addresses for the given pattern
matches(pattern)(pattern: string) => booleanbooleanSearches the event title and description for the given pattern

hasAttendee(pattern)

Performs a case-insensitive search across all attendee email addresses. Returns true if any attendee's email contains the pattern.

// Check for a specific attendee
event.hasAttendee('alice@example.com') // exact email match

// Check for a domain
event.hasAttendee('@company.com') // any attendee from company.com

// Case-insensitive
event.hasAttendee('Alice@Example.COM') // matches "alice@example.com"

matches(pattern)

Performs a case-insensitive search across both the event title and description. Returns true if either field contains the pattern.

// Match by keyword
event.matches('standup') // matches "Daily Standup", "STANDUP MEETING", etc.

// Matches in title or description
event.matches('confidential') // true if title OR description contains "confidential"
tip

Use matches() for simple keyword filtering instead of manually checking event.title and event.description with string operations. It handles null descriptions and case-insensitivity for you.

GateResult Interface

The gate function must return a GateResult object (or a simple boolean). Here is the full interface:

interface GateResult {
pass: boolean;
reason?: string;
transform?: {
title?: string;
description?: string;
visibility?: 'default' | 'public' | 'private';
showAs?: 'free' | 'busy';
};
}

Fields

FieldTypeRequiredDescription
passbooleanYestrue = sync the event to the target calendar. false = block (skip) the event.
reasonstringNoHuman-readable explanation for the decision. Max 200 characters. Most useful when pass is false -- the reason appears in sync logs.
transformobjectNoOverride event properties on the synced copy. Only applies when pass is true.

Transform Fields

FieldTypeMax LengthDescription
titlestring500 charsReplace the event title on the synced copy
descriptionstring5,000 charsReplace the event description on the synced copy
visibility'default' | 'public' | 'private'--Change the event visibility
showAs'free' | 'busy'--Change the free/busy status
tip

Transforms only modify the synced copy on the target calendar. The original event on the source calendar is never changed.

Return Types

The gate function can return any of these types:

Boolean

The simplest return type. true passes the event, false blocks it:

function gate(event: GateEvent): boolean {
return event.isWeekday;
}

GateResult

An object with pass, optional reason, and optional transform:

function gate(event: GateEvent): GateResult {
return {
pass: true,
reason: 'Synced normally',
transform: { title: `[Sync] ${event.title}` }
};
}

GateResult | boolean

The union type allows mixing both styles in the same function:

function gate(event: GateEvent): GateResult | boolean {
if (event.matches('confidential')) {
return { pass: false, reason: 'Blocked confidential event' };
}
return true; // pass everything else
}

Complete Example

This comprehensive gate function demonstrates multiple properties, methods, and transform options:

function gate(event: GateEvent): GateResult {
// Block confidential events entirely
if (event.matches('confidential') || event.matches('secret')) {
return { pass: false, reason: 'Blocked confidential event' };
}

// Block cancelled events
if (event.status === 'cancelled') {
return { pass: false, reason: 'Event is cancelled' };
}

// Redact personal events -- show the time block but hide details
if (event.matches('personal') || event.matches('private')) {
return {
pass: true,
transform: {
title: 'Personal Event',
description: '',
visibility: 'private'
}
};
}

// Mark solo events (no other attendees) as free
if (event.attendeeCount <= 1) {
return {
pass: true,
transform: { showAs: 'free' }
};
}

// Add prefix to large meetings (5+ attendees) for easy identification
if (event.attendeeCount >= 5) {
return {
pass: true,
transform: {
title: `[Team] ${event.title}`
}
};
}

// Pass everything else unchanged
return { pass: true };
}

This example:

  • Uses matches() for keyword filtering (confidential, personal)
  • Checks status for cancelled events
  • Uses attendeeCount for attendee-based logic
  • Applies different transforms based on conditions
  • Returns a reason for blocked events
  • Falls through to a default pass for unmatched events

Next Steps