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:
| Property | Type | Description | Example Value |
|---|---|---|---|
title | string | Event title/summary | "Team Standup" |
description | string | null | Event description/notes | "Daily sync meeting" |
location | string | null | Event 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" } |
isAllDay | boolean | Whether the event is an all-day event | false |
status | 'confirmed' | 'tentative' | 'cancelled' | Event confirmation status | "confirmed" |
showAs | 'free' | 'busy' | null | Free/busy status | "busy" |
attendees | Array<{ email: string, displayName?: string }> | List of event attendees | [{ email: "alice@example.com", displayName: "Alice" }] |
organizer | { email: string, displayName?: string } | null | Event organizer | { email: "bob@example.com", displayName: "Bob" } |
recurrence | string[] | null | Recurrence 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.
| Property | Type | Description | Example Value |
|---|---|---|---|
startDate | string | Alias for start.dateTime (ISO 8601) | "2026-02-14T14:00:00Z" |
endDate | string | Alias for end.dateTime (ISO 8601) | "2026-02-14T15:00:00Z" |
durationMinutes | number | Event duration in minutes | 60 |
dayOfWeek | number | Day of week (0 = Sunday, 6 = Saturday) | 1 (Monday) |
hour | number | Hour of day the event starts (0-23) | 14 (2 PM) |
isWeekday | boolean | Whether the event falls on Monday-Friday | true |
attendeeCount | number | Number of attendees | 5 |
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.
| Method | Signature | Returns | Description |
|---|---|---|---|
hasAttendee(pattern) | (pattern: string) => boolean | boolean | Searches attendee email addresses for the given pattern |
matches(pattern) | (pattern: string) => boolean | boolean | Searches 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"
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
| Field | Type | Required | Description |
|---|---|---|---|
pass | boolean | Yes | true = sync the event to the target calendar. false = block (skip) the event. |
reason | string | No | Human-readable explanation for the decision. Max 200 characters. Most useful when pass is false -- the reason appears in sync logs. |
transform | object | No | Override event properties on the synced copy. Only applies when pass is true. |
Transform Fields
| Field | Type | Max Length | Description |
|---|---|---|---|
title | string | 500 chars | Replace the event title on the synced copy |
description | string | 5,000 chars | Replace the event description on the synced copy |
visibility | 'default' | 'public' | 'private' | -- | Change the event visibility |
showAs | 'free' | 'busy' | -- | Change the free/busy status |
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
statusfor cancelled events - Uses
attendeeCountfor 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
- Try the examples in the Code Editor
- Generate functions from descriptions with the AI Generator
- Start from a Template for common scenarios
- Build conditions visually with the Visual Builder