air

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 30, 2026 License: MIT Imports: 32 Imported by: 0

README

Air - Web UI Server

This package implements a local web server providing a modern web interface for Nylas email and calendar.

Usage

nylas air              # Start web UI on http://localhost:7365
nylas air --port 3000  # Custom port
nylas air --no-browser # Start without opening browser
nylas air --encrypted  # Enable encryption for cached data
nylas air --clear-cache # Clear all cached data before starting

Architecture

Air is a self-contained HTTP server with embedded static assets (HTML, CSS, JS).

Core Files

All files are ≤500 lines for maintainability.

Server Core (refactored from server.go):

  • server.go (51 lines) - Server struct definition
  • server_lifecycle.go (315 lines) - HTTP server setup, routing, lifecycle
  • server_stores.go (67 lines) - Cache store accessors
  • server_sync.go (187 lines) - Background sync logic
  • server_offline.go (98 lines) - Offline queue processing
  • server_converters.go (116 lines) - Domain to cache conversions
  • server_template.go (163 lines) - Template handling
  • server_modules_test.go (523 lines) - Unit tests for server modules

Other Core:

  • air.go - Entry point, CLI command
  • middleware.go - Auth, CORS, logging middleware
  • data.go - Grant store, configuration persistence
Handler Organization

Email Handlers:

  • handlers_email.go (522 lines) - /api/emails, /api/send
  • handlers_drafts.go (531 lines) - /api/drafts
  • handlers_bundles.go - Email categorization into smart bundles

Calendar Handlers (refactored from handlers_calendar.go):

  • handlers_calendars.go (108 lines) - /api/calendars
  • handlers_events.go (520 lines) - /api/events
  • handlers_calendar_helpers.go (159 lines) - Helpers and converters

Contact Handlers (refactored from handlers_contacts.go):

  • handlers_contacts.go (190 lines) - /api/contacts listing
  • handlers_contacts_crud.go (320 lines) - CRUD operations
  • handlers_contacts_search.go (194 lines) - Search and groups
  • handlers_contacts_helpers.go (308 lines) - Helpers and demo data

AI Handlers (refactored from handlers_ai.go):

  • handlers_ai_types.go (92 lines) - Type definitions
  • handlers_ai_summarize.go (165 lines) - /api/ai/summarize
  • handlers_ai_smart.go (225 lines) - /api/ai/smart-replies
  • handlers_ai_thread.go (192 lines) - /api/ai/thread-summary
  • handlers_ai_complete.go (216 lines) - /api/ai/complete
  • handlers_ai_config.go (227 lines) - /api/ai/config

Productivity - Send Features (refactored from handlers_productivity_send.go):

  • types_productivity_send.go (82 lines) - Type definitions
  • handlers_scheduled_send.go (177 lines) - /api/scheduled
  • handlers_undo_send.go (148 lines) - /api/undo-send
  • handlers_templates.go (259 lines) - /api/templates
  • handlers_templates_helpers.go (100 lines) - Template utilities

Productivity - Inbox Features (refactored from handlers_productivity_inbox.go):

  • handlers_splitinbox_types.go (84 lines) - Type definitions
  • handlers_splitinbox_config.go (164 lines) - /api/inbox/split
  • handlers_splitinbox_categorize.go (148 lines) - Categorization logic
  • handlers_snooze_types.go (37 lines) - Type definitions
  • handlers_snooze_handlers.go (126 lines) - /api/snooze
  • handlers_snooze_parser.go (142 lines) - Natural language parser

Other Handlers:

  • handlers_types.go - Shared types (EmailResponse, EventResponse, etc.)
  • handlers_config.go - /api/config, /api/grants
  • handlers_availability.go (527 lines) - /api/availability
  • handlers_cache.go - /api/cache
  • handlers_productivity_*.go - Focus mode, reply later, analytics, etc.
Static Assets
Directory Contents
static/ HTML templates
static/css/ Stylesheets
static/js/ JavaScript modules

API Endpoints

Email
  • GET /api/emails - List emails
  • GET /api/emails/:id - Get single email
  • POST /api/send - Send email
  • PUT /api/emails/:id - Update (mark read, star, etc.)
  • DELETE /api/emails/:id - Trash email
Drafts
  • GET /api/drafts - List drafts
  • POST /api/drafts - Create draft
  • PUT /api/drafts/:id - Update draft
  • DELETE /api/drafts/:id - Delete draft
Calendar
  • GET /api/events - List events
  • POST /api/events - Create event
  • GET /api/calendars - List calendars
  • GET /api/availability - Check availability
Productivity Features
  • GET/PUT /api/inbox/split - Split inbox configuration
  • POST /api/inbox/categorize - Categorize email
  • GET/POST/DELETE /api/inbox/vip - VIP senders
  • GET/POST/DELETE /api/snooze - Snooze emails
  • GET/POST/DELETE /api/scheduled - Scheduled send
  • GET/PUT/POST /api/undo-send - Undo send config
  • GET/POST /api/templates - Email templates
AI Features
  • POST /api/ai/summarize - Email summary
  • POST /api/ai/smart-replies - Generate reply suggestions
  • POST /api/ai/enhanced-summary - Detailed analysis
  • POST /api/ai/auto-label - Auto-categorization
  • POST /api/ai/thread-summary - Thread overview

Test Organization

File Tests
*_test.go Unit tests (handler logic)
integration_*.go Integration tests (require build tag)

Integration test files:

  • integration_base_test.go - Shared helpers (testServer())
  • integration_core_test.go - Config, grants, folders
  • integration_email_test.go - Email operations
  • integration_calendar_test.go - Calendar operations
  • integration_contacts_test.go - Contact operations
  • integration_cache_test.go - Cache operations
  • integration_ai_test.go - AI features
  • integration_middleware_test.go - Middleware tests
  • integration_productivity_test.go - Productivity features (focus, reply later, notetaker, etc.)
  • integration_bundles_test.go - Email bundle categorization

Cache Subsystem

The cache/ subdirectory contains the offline cache implementation:

  • SQLite-based local storage
  • Email, event, contact, and attachment caching
  • Search query parsing
  • Encryption support

Documentation

Overview

Package air provides a modern web-based email client interface for the Nylas CLI. Air is designed to be a lightweight, keyboard-driven email client that runs locally.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CORSMiddleware

func CORSMiddleware(next http.Handler) http.Handler

CORSMiddleware adds CORS headers for local development. This allows the frontend to make API requests.

func CacheMiddleware

func CacheMiddleware(next http.Handler) http.Handler

CacheMiddleware adds appropriate cache headers for static assets. This reduces server load and improves perceived performance.

func CompressionMiddleware

func CompressionMiddleware(next http.Handler) http.Handler

CompressionMiddleware adds gzip compression to responses. This significantly reduces bandwidth and improves load times.

func GetTrackingPixelURL

func GetTrackingPixelURL(emailID string) string

GetTrackingPixelURL returns the tracking pixel URL for an email

func IsFocusModeActive

func IsFocusModeActive() bool

IsFocusModeActive returns whether focus mode is active

func IsSenderAllowed

func IsSenderAllowed(email string) (bool, string)

IsSenderAllowed checks if a sender is allowed

func MethodOverrideMiddleware

func MethodOverrideMiddleware(next http.Handler) http.Handler

MethodOverrideMiddleware allows using X-HTTP-Method-Override header. This enables REST methods in environments that only support GET/POST.

func NewAirCmd

func NewAirCmd() *cobra.Command

NewAirCmd creates the air command.

func ParseBool

func ParseBool(query url.Values, key string) bool

ParseBool is a standalone helper for parsing boolean values. Deprecated: Use QueryParams.GetBool() instead for new code.

func ParseInt

func ParseInt(query url.Values, key string, defaultVal, minVal, maxVal int) int

ParseInt is a standalone helper for parsing an integer with bounds. Deprecated: Use QueryParams.GetInt() instead for new code.

func ParseInt64

func ParseInt64(query url.Values, key string, defaultVal int64) int64

ParseInt64 is a standalone helper for parsing int64 values. Deprecated: Use QueryParams.GetInt64() instead for new code.

func ParseLimit

func ParseLimit(query url.Values, defaultVal int) int

ParseLimit is a standalone helper for parsing limit with standard bounds. Deprecated: Use QueryParams.GetLimit() instead for new code.

func PerformanceMonitoringMiddleware

func PerformanceMonitoringMiddleware(next http.Handler) http.Handler

PerformanceMonitoringMiddleware tracks request timing and adds performance headers. This helps identify slow endpoints and enables browser performance monitoring.

func RecordAIUsage

func RecordAIUsage(task string, tokens int, cost float64)

RecordAIUsage records AI usage for a task

func RecordEmailReceived

func RecordEmailReceived()

RecordEmailReceived records a received email

func RecordEmailSent

func RecordEmailSent()

RecordEmailSent records a sent email

func RecordInboxZero

func RecordInboxZero()

RecordInboxZero records achieving inbox zero

func RegisterEmailForTracking

func RegisterEmailForTracking(emailID, recipient string)

RegisterEmailForTracking registers an email for read tracking

func SecurityHeadersMiddleware

func SecurityHeadersMiddleware(next http.Handler) http.Handler

SecurityHeadersMiddleware adds security headers to all responses. This improves security posture and prevents common attacks.

func ShouldAllowNotification

func ShouldAllowNotification(senderEmail string) bool

ShouldAllowNotification checks if notification should be shown

Types

type AIConfig

type AIConfig struct {
	Provider    string            `json:"provider"` // claude, openai, ollama, groq
	Model       string            `json:"model"`    // claude-3-opus, gpt-4, etc.
	APIKey      string            `json:"apiKey,omitempty"`
	BaseURL     string            `json:"baseUrl,omitempty"`
	MaxTokens   int               `json:"maxTokens"`
	Temperature float64           `json:"temperature"`
	TaskModels  map[string]string `json:"taskModels"`  // task -> model mapping
	UsageBudget float64           `json:"usageBudget"` // Monthly budget in USD
	UsageSpent  float64           `json:"usageSpent"`  // Current month spend
	Enabled     bool              `json:"enabled"`
}

AIConfig represents AI provider configuration

type AIRequest

type AIRequest struct {
	EmailID string `json:"email_id"`
	Prompt  string `json:"prompt"`
}

AIRequest represents an AI summarization request.

type AIResponse

type AIResponse struct {
	Success bool   `json:"success"`
	Summary string `json:"summary"`
	Error   string `json:"error,omitempty"`
}

AIResponse represents the AI response.

type AIUsageStats

type AIUsageStats struct {
	TotalRequests  int            `json:"totalRequests"`
	TotalTokens    int            `json:"totalTokens"`
	TotalCost      float64        `json:"totalCost"`
	RequestsByTask map[string]int `json:"requestsByTask"`
	TokensByTask   map[string]int `json:"tokensByTask"`
}

AIUsageStats represents AI usage statistics

type Attachment

type Attachment struct {
	Name string
	Size string
	Icon string
}

Attachment represents an email attachment.

type AttachmentResponse

type AttachmentResponse struct {
	ID          string `json:"id"`
	Filename    string `json:"filename"`
	ContentType string `json:"content_type"`
	Size        int64  `json:"size"`
}

AttachmentResponse represents an email attachment.

type Attendee

type Attendee struct {
	Name   string
	Avatar string
	Color  string
}

Attendee represents an event attendee.

type AutoLabelRequest

type AutoLabelRequest struct {
	EmailID string `json:"email_id"`
	Subject string `json:"subject"`
	From    string `json:"from"`
	Body    string `json:"body"`
}

AutoLabelRequest represents a request to auto-label an email.

type AutoLabelResponse

type AutoLabelResponse struct {
	Success  bool     `json:"success"`
	Labels   []string `json:"labels"`
	Category string   `json:"category"` // Primary category
	Priority string   `json:"priority"` // "high", "normal", "low"
	Error    string   `json:"error,omitempty"`
}

AutoLabelResponse represents the auto-label response.

type AvailabilityRequest

type AvailabilityRequest struct {
	StartTime       int64    `json:"start_time"`
	EndTime         int64    `json:"end_time"`
	DurationMinutes int      `json:"duration_minutes"`
	Participants    []string `json:"participants"` // Email addresses
	IntervalMinutes int      `json:"interval_minutes,omitempty"`
}

AvailabilityRequest represents a request to find available times.

type AvailabilityResponse

type AvailabilityResponse struct {
	Slots   []AvailableSlotResponse `json:"slots"`
	Message string                  `json:"message,omitempty"`
}

AvailabilityResponse represents available meeting slots.

type AvailableSlotResponse

type AvailableSlotResponse struct {
	StartTime int64    `json:"start_time"`
	EndTime   int64    `json:"end_time"`
	Emails    []string `json:"emails,omitempty"`
}

AvailableSlotResponse represents a single available time slot.

type Bundle

type Bundle struct {
	ID          string       `json:"id"`
	Name        string       `json:"name"`
	Icon        string       `json:"icon"`
	Description string       `json:"description"`
	Rules       []BundleRule `json:"rules"`
	Collapsed   bool         `json:"collapsed"`
	Count       int          `json:"count"`
	UnreadCount int          `json:"unreadCount"`
	LastUpdated time.Time    `json:"lastUpdated"`
}

Bundle represents an email bundle/category

type BundleRule

type BundleRule struct {
	Field    string `json:"field"`    // from, to, subject, domain
	Operator string `json:"operator"` // contains, equals, matches, startsWith
	Value    string `json:"value"`
	Priority int    `json:"priority"`
}

BundleRule defines matching criteria for emails

type BundleStore

type BundleStore struct {
	// contains filtered or unexported fields
}

BundleStore manages bundles in memory

func NewBundleStore

func NewBundleStore() *BundleStore

NewBundleStore creates a new bundle store with defaults

type BundledEmail

type BundledEmail struct {
	EmailID  string `json:"emailId"`
	BundleID string `json:"bundleId"`
	Score    int    `json:"score"` // Match confidence
}

BundledEmail represents an email assigned to a bundle

type CacheAccountInfo

type CacheAccountInfo struct {
	Email        string     `json:"email"`
	SizeBytes    int64      `json:"size_bytes"`
	EmailCount   int        `json:"email_count"`
	EventCount   int        `json:"event_count"`
	ContactCount int        `json:"contact_count"`
	LastSync     *time.Time `json:"last_sync,omitempty"`
}

CacheAccountInfo contains cache info for a single account.

type CacheSearchResponse

type CacheSearchResponse struct {
	Results []CacheSearchResult `json:"results"`
	Query   string              `json:"query"`
	Total   int                 `json:"total"`
}

CacheSearchResponse represents the search results response.

type CacheSearchResult

type CacheSearchResult struct {
	Type     string `json:"type"` // "email", "event", "contact"
	ID       string `json:"id"`
	Title    string `json:"title"`
	Subtitle string `json:"subtitle"`
	Date     int64  `json:"date"` // Unix timestamp
}

CacheSearchResult represents a single search result.

type CacheSettingsResponse

type CacheSettingsResponse struct {
	Enabled             bool   `json:"cache_enabled"`
	MaxSizeMB           int    `json:"cache_max_size_mb"`
	TTLDays             int    `json:"cache_ttl_days"`
	SyncIntervalMinutes int    `json:"sync_interval_minutes"`
	OfflineQueueEnabled bool   `json:"offline_queue_enabled"`
	EncryptionEnabled   bool   `json:"encryption_enabled"`
	Theme               string `json:"theme"`
	DefaultView         string `json:"default_view"`
	CompactMode         bool   `json:"compact_mode"`
	PreviewPosition     string `json:"preview_position"`
}

CacheSettingsResponse represents cache settings.

type CacheStatusResponse

type CacheStatusResponse struct {
	Enabled           bool               `json:"enabled"`
	Online            bool               `json:"online"`
	Accounts          []CacheAccountInfo `json:"accounts"`
	TotalSizeBytes    int64              `json:"total_size_bytes"`
	PendingActions    int                `json:"pending_actions"`
	LastSync          *time.Time         `json:"last_sync,omitempty"`
	SyncInterval      int                `json:"sync_interval_minutes"`
	EncryptionEnabled bool               `json:"encryption_enabled"`
}

CacheStatusResponse represents the cache status API response.

type CacheSyncResponse

type CacheSyncResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message,omitempty"`
	Error   string `json:"error,omitempty"`
}

CacheSyncResponse represents the sync trigger response.

type Calendar

type Calendar struct {
	ID        string
	Name      string
	Color     string
	IsPrimary bool
}

Calendar represents a calendar.

type CalendarResponse

type CalendarResponse struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
	Timezone    string `json:"timezone,omitempty"`
	IsPrimary   bool   `json:"is_primary"`
	ReadOnly    bool   `json:"read_only"`
	HexColor    string `json:"hex_color,omitempty"`
}

CalendarResponse represents a calendar in API responses.

type CalendarsResponse

type CalendarsResponse struct {
	Calendars []CalendarResponse `json:"calendars"`
}

CalendarsResponse represents the calendars list API response.

type CategorizedEmail

type CategorizedEmail struct {
	EmailID       string        `json:"email_id"`
	Category      InboxCategory `json:"category"`
	MatchedRule   string        `json:"matched_rule,omitempty"`
	CategorizedAt int64         `json:"categorized_at"`
}

CategorizedEmail represents an email with its category.

type CategoryRule

type CategoryRule struct {
	ID          string        `json:"id"`
	Category    InboxCategory `json:"category"`
	Type        string        `json:"type"` // "sender", "domain", "subject", "header"
	Pattern     string        `json:"pattern"`
	IsRegex     bool          `json:"is_regex"`
	Priority    int           `json:"priority"` // Higher priority rules are checked first
	Description string        `json:"description,omitempty"`
	CreatedAt   int64         `json:"created_at"`
}

CategoryRule defines a rule for categorizing emails.

type CompleteRequest

type CompleteRequest struct {
	Text      string `json:"text"`
	MaxLength int    `json:"maxLength"`
	Context   string `json:"context,omitempty"`
}

CompleteRequest represents a smart compose request

type CompleteResponse

type CompleteResponse struct {
	Suggestion string  `json:"suggestion"`
	Confidence float64 `json:"confidence"`
}

CompleteResponse represents a smart compose response

type ConferencingResponse

type ConferencingResponse struct {
	Provider string `json:"provider,omitempty"`
	URL      string `json:"url,omitempty"`
}

ConferencingResponse represents video conferencing details.

type ConfigStatusResponse

type ConfigStatusResponse struct {
	Configured   bool   `json:"configured"`
	Region       string `json:"region"`
	ClientID     string `json:"client_id,omitempty"`
	HasAPIKey    bool   `json:"has_api_key"`
	GrantCount   int    `json:"grant_count"`
	DefaultGrant string `json:"default_grant,omitempty"`
}

ConfigStatusResponse represents the config status API response.

type ConflictsResponse

type ConflictsResponse struct {
	Conflicts []EventConflict `json:"conflicts"`
	HasMore   bool            `json:"has_more"`
}

ConflictsResponse represents conflicting events.

type Contact

type Contact struct {
	ID          string
	Name        string
	Email       string
	Role        string
	Company     string
	Avatar      string
	AvatarColor string
	IsVIP       bool
	Letter      string // For alphabetical grouping
}

Contact represents a contact.

type ContactActionResponse

type ContactActionResponse struct {
	Success bool             `json:"success"`
	Contact *ContactResponse `json:"contact,omitempty"`
	Message string           `json:"message,omitempty"`
	Error   string           `json:"error,omitempty"`
}

ContactActionResponse represents the response for contact actions (create/update/delete).

type ContactAddressResponse

type ContactAddressResponse struct {
	Type          string `json:"type,omitempty"`
	StreetAddress string `json:"street_address,omitempty"`
	City          string `json:"city,omitempty"`
	State         string `json:"state,omitempty"`
	PostalCode    string `json:"postal_code,omitempty"`
	Country       string `json:"country,omitempty"`
}

ContactAddressResponse represents a contact address in API responses.

type ContactEmailResponse

type ContactEmailResponse struct {
	Email string `json:"email"`
	Type  string `json:"type,omitempty"`
}

ContactEmailResponse represents a contact email in API responses.

type ContactGroupResponse

type ContactGroupResponse struct {
	ID   string `json:"id"`
	Name string `json:"name"`
	Path string `json:"path,omitempty"`
}

ContactGroupResponse represents a contact group in API responses.

type ContactGroupsResponse

type ContactGroupsResponse struct {
	Groups []ContactGroupResponse `json:"groups"`
}

ContactGroupsResponse represents the contact groups list API response.

type ContactPhoneResponse

type ContactPhoneResponse struct {
	Number string `json:"number"`
	Type   string `json:"type,omitempty"`
}

ContactPhoneResponse represents a contact phone number in API responses.

type ContactResponse

type ContactResponse struct {
	ID           string                   `json:"id"`
	GivenName    string                   `json:"given_name,omitempty"`
	Surname      string                   `json:"surname,omitempty"`
	DisplayName  string                   `json:"display_name"`
	Nickname     string                   `json:"nickname,omitempty"`
	CompanyName  string                   `json:"company_name,omitempty"`
	JobTitle     string                   `json:"job_title,omitempty"`
	Birthday     string                   `json:"birthday,omitempty"`
	Notes        string                   `json:"notes,omitempty"`
	PictureURL   string                   `json:"picture_url,omitempty"`
	Emails       []ContactEmailResponse   `json:"emails,omitempty"`
	PhoneNumbers []ContactPhoneResponse   `json:"phone_numbers,omitempty"`
	Addresses    []ContactAddressResponse `json:"addresses,omitempty"`
	Source       string                   `json:"source,omitempty"`
}

ContactResponse represents a contact in API responses.

type ContactsResponse

type ContactsResponse struct {
	Contacts   []ContactResponse `json:"contacts"`
	NextCursor string            `json:"next_cursor,omitempty"`
	HasMore    bool              `json:"has_more"`
}

ContactsResponse represents the contacts list API response.

type CreateContactRequest

type CreateContactRequest struct {
	GivenName    string                   `json:"given_name,omitempty"`
	Surname      string                   `json:"surname,omitempty"`
	Nickname     string                   `json:"nickname,omitempty"`
	CompanyName  string                   `json:"company_name,omitempty"`
	JobTitle     string                   `json:"job_title,omitempty"`
	Birthday     string                   `json:"birthday,omitempty"`
	Notes        string                   `json:"notes,omitempty"`
	Emails       []ContactEmailResponse   `json:"emails,omitempty"`
	PhoneNumbers []ContactPhoneResponse   `json:"phone_numbers,omitempty"`
	Addresses    []ContactAddressResponse `json:"addresses,omitempty"`
}

CreateContactRequest represents a request to create a contact.

type CreateEventRequest

type CreateEventRequest struct {
	CalendarID   string                     `json:"calendar_id"`
	Title        string                     `json:"title"`
	Description  string                     `json:"description,omitempty"`
	Location     string                     `json:"location,omitempty"`
	StartTime    int64                      `json:"start_time"`
	EndTime      int64                      `json:"end_time"`
	Timezone     string                     `json:"timezone,omitempty"`
	IsAllDay     bool                       `json:"is_all_day"`
	Busy         bool                       `json:"busy"`
	Participants []EventParticipantResponse `json:"participants,omitempty"`
}

CreateEventRequest represents a request to create an event.

type CreateNotetakerRequest

type CreateNotetakerRequest struct {
	MeetingLink string `json:"meetingLink"`
	JoinTime    int64  `json:"joinTime,omitempty"`
	BotName     string `json:"botName,omitempty"`
}

CreateNotetakerRequest for creating a notetaker

type DayVolume

type DayVolume struct {
	Date     string `json:"date"`
	Received int    `json:"received"`
	Sent     int    `json:"sent"`
}

DayVolume represents volume for a specific day

type DraftRequest

type DraftRequest struct {
	To           []EmailParticipantResponse `json:"to"`
	Cc           []EmailParticipantResponse `json:"cc,omitempty"`
	Bcc          []EmailParticipantResponse `json:"bcc,omitempty"`
	Subject      string                     `json:"subject"`
	Body         string                     `json:"body"`
	ReplyToMsgID string                     `json:"reply_to_message_id,omitempty"`
}

DraftRequest represents a request to create or update a draft.

type DraftResponse

type DraftResponse struct {
	ID      string                     `json:"id"`
	Subject string                     `json:"subject"`
	Body    string                     `json:"body,omitempty"`
	To      []EmailParticipantResponse `json:"to,omitempty"`
	Cc      []EmailParticipantResponse `json:"cc,omitempty"`
	Bcc     []EmailParticipantResponse `json:"bcc,omitempty"`
	Date    int64                      `json:"date"`
}

DraftResponse represents a draft in API responses.

type DraftsResponse

type DraftsResponse struct {
	Drafts []DraftResponse `json:"drafts"`
}

DraftsResponse represents the drafts list API response.

type Email

type Email struct {
	ID              string
	From            string
	FromEmail       string
	FromAvatar      string
	Subject         string
	Preview         string
	Body            string
	Time            string
	IsUnread        bool
	IsStarred       bool
	IsSelected      bool
	HasAttachment   bool
	AttachmentCount int
	Priority        string // "high", "normal", "low"
	HasAISummary    bool
	Attachments     []Attachment
}

Email represents an email message.

type EmailAnalytics

type EmailAnalytics struct {
	// Volume metrics
	TotalReceived int `json:"totalReceived"`
	TotalSent     int `json:"totalSent"`
	TotalArchived int `json:"totalArchived"`
	TotalDeleted  int `json:"totalDeleted"`

	// Response metrics
	AvgResponseTime float64 `json:"avgResponseTimeHours"`
	ResponseRate    float64 `json:"responseRate"` // percentage

	// Top senders/recipients
	TopSenders    []SenderStats `json:"topSenders"`
	TopRecipients []SenderStats `json:"topRecipients"`

	// Time-based metrics
	BusiestHour  int            `json:"busiestHour"` // 0-23
	BusiestDay   string         `json:"busiestDay"`  // Monday, Tuesday, etc.
	HourlyVolume map[int]int    `json:"hourlyVolume"`
	DailyVolume  map[string]int `json:"dailyVolume"`
	WeeklyTrend  []DayVolume    `json:"weeklyTrend"`

	// Productivity metrics
	InboxZeroCount int     `json:"inboxZeroCount"` // Times achieved inbox zero
	CurrentStreak  int     `json:"currentStreak"`  // Consecutive inbox zero days
	BestStreak     int     `json:"bestStreak"`
	FocusTimeHours float64 `json:"focusTimeHours"`

	// Period info
	PeriodStart time.Time `json:"periodStart"`
	PeriodEnd   time.Time `json:"periodEnd"`
}

EmailAnalytics represents email analytics data

type EmailParticipantResponse

type EmailParticipantResponse struct {
	Name  string `json:"name"`
	Email string `json:"email"`
}

EmailParticipantResponse represents an email participant.

type EmailResponse

type EmailResponse struct {
	ID          string                     `json:"id"`
	ThreadID    string                     `json:"thread_id,omitempty"`
	Subject     string                     `json:"subject"`
	Snippet     string                     `json:"snippet"`
	Body        string                     `json:"body,omitempty"`
	From        []EmailParticipantResponse `json:"from"`
	To          []EmailParticipantResponse `json:"to,omitempty"`
	Cc          []EmailParticipantResponse `json:"cc,omitempty"`
	Date        int64                      `json:"date"` // Unix timestamp
	Unread      bool                       `json:"unread"`
	Starred     bool                       `json:"starred"`
	Folders     []string                   `json:"folders,omitempty"`
	Attachments []AttachmentResponse       `json:"attachments,omitempty"`
}

EmailResponse represents an email in API responses.

type EmailTemplate

type EmailTemplate struct {
	ID         string            `json:"id"`
	Name       string            `json:"name"`
	Subject    string            `json:"subject,omitempty"`
	Body       string            `json:"body"`
	Shortcut   string            `json:"shortcut,omitempty"`  // e.g., "/thanks", "/intro"
	Variables  []string          `json:"variables,omitempty"` // Placeholders like {{name}}, {{company}}
	Category   string            `json:"category,omitempty"`  // "greeting", "follow-up", "closing"
	UsageCount int               `json:"usage_count"`
	CreatedAt  int64             `json:"created_at"`
	UpdatedAt  int64             `json:"updated_at"`
	Metadata   map[string]string `json:"metadata,omitempty"`
}

EmailTemplate represents a reusable email template.

type EmailsResponse

type EmailsResponse struct {
	Emails     []EmailResponse `json:"emails"`
	NextCursor string          `json:"next_cursor,omitempty"`
	HasMore    bool            `json:"has_more"`
}

EmailsResponse represents the emails list API response.

type EnhancedSummaryRequest

type EnhancedSummaryRequest struct {
	EmailID string `json:"email_id"`
	Subject string `json:"subject"`
	From    string `json:"from"`
	Body    string `json:"body"`
}

EnhancedSummaryRequest represents an enhanced summary request.

type EnhancedSummaryResponse

type EnhancedSummaryResponse struct {
	Success     bool     `json:"success"`
	Summary     string   `json:"summary"`
	ActionItems []string `json:"action_items"`
	Sentiment   string   `json:"sentiment"` // "positive", "neutral", "negative", "urgent"
	Category    string   `json:"category"`  // "meeting", "task", "fyi", "question", "social"
	Error       string   `json:"error,omitempty"`
}

EnhancedSummaryResponse represents the enhanced summary with action items and sentiment.

type Event

type Event struct {
	ID             string
	Title          string
	Description    string
	StartTime      string
	EndTime        string
	Location       string
	IsFocusTime    bool
	IsAISuggestion bool
	Attendees      []Attendee
	Tags           []string
}

Event represents a calendar event.

type EventActionResponse

type EventActionResponse struct {
	Success bool           `json:"success"`
	Event   *EventResponse `json:"event,omitempty"`
	Message string         `json:"message,omitempty"`
	Error   string         `json:"error,omitempty"`
}

EventActionResponse represents the response for event actions (create/update/delete).

type EventConflict

type EventConflict struct {
	Event1 EventResponse `json:"event1"`
	Event2 EventResponse `json:"event2"`
}

EventConflict represents a scheduling conflict.

type EventParticipantResponse

type EventParticipantResponse struct {
	Name   string `json:"name,omitempty"`
	Email  string `json:"email"`
	Status string `json:"status,omitempty"`
}

EventParticipantResponse represents an event participant.

type EventResponse

type EventResponse struct {
	ID           string                     `json:"id"`
	CalendarID   string                     `json:"calendar_id"`
	Title        string                     `json:"title"`
	Description  string                     `json:"description,omitempty"`
	Location     string                     `json:"location,omitempty"`
	StartTime    int64                      `json:"start_time"`
	EndTime      int64                      `json:"end_time"`
	Timezone     string                     `json:"timezone,omitempty"`
	IsAllDay     bool                       `json:"is_all_day"`
	Status       string                     `json:"status,omitempty"`
	Busy         bool                       `json:"busy"`
	Participants []EventParticipantResponse `json:"participants,omitempty"`
	Conferencing *ConferencingResponse      `json:"conferencing,omitempty"`
	HtmlLink     string                     `json:"html_link,omitempty"`
}

EventResponse represents an event in API responses.

type EventsResponse

type EventsResponse struct {
	Events     []EventResponse `json:"events"`
	NextCursor string          `json:"next_cursor,omitempty"`
	HasMore    bool            `json:"has_more"`
}

EventsResponse represents the events list API response.

type FocusModeSettings

type FocusModeSettings struct {
	DefaultDuration    int      `json:"defaultDuration"`    // minutes
	PomodoroWork       int      `json:"pomodoroWork"`       // minutes
	PomodoroBreak      int      `json:"pomodoroBreak"`      // minutes
	PomodoroLongBreak  int      `json:"pomodoroLongBreak"`  // minutes
	SessionsBeforeLong int      `json:"sessionsBeforeLong"` // sessions before long break
	HideNotifications  bool     `json:"hideNotifications"`
	HideEmailList      bool     `json:"hideEmailList"`
	MuteSound          bool     `json:"muteSound"`
	AllowedSenders     []string `json:"allowedSenders"` // VIP list that can interrupt
	AutoReplyEnabled   bool     `json:"autoReplyEnabled"`
	AutoReplyMessage   string   `json:"autoReplyMessage"`
}

FocusModeSettings represents focus mode preferences

type FocusModeState

type FocusModeState struct {
	IsActive      bool      `json:"isActive"`
	StartedAt     time.Time `json:"startedAt,omitempty"`
	EndsAt        time.Time `json:"endsAt,omitempty"`
	Duration      int       `json:"duration"` // minutes
	PomodoroMode  bool      `json:"pomodoroMode"`
	SessionCount  int       `json:"sessionCount"`
	BreakDuration int       `json:"breakDuration"` // minutes
	InBreak       bool      `json:"inBreak"`
}

FocusModeState represents the current focus mode state

type FocusTimeSuggestion

type FocusTimeSuggestion struct {
	StartHour int    `json:"startHour"`
	EndHour   int    `json:"endHour"`
	Day       string `json:"day"`
	Reason    string `json:"reason"`
	Score     int    `json:"score"` // 1-100, higher is better
}

FocusTimeSuggestion represents a suggested focus time block

type Folder

type Folder struct {
	ID          string
	Name        string
	Icon        string
	Count       int
	UnreadCount int
	IsActive    bool
}

Folder represents an email folder.

type FolderResponse

type FolderResponse struct {
	ID           string `json:"id"`
	Name         string `json:"name"`
	SystemFolder string `json:"system_folder,omitempty"`
	TotalCount   int    `json:"total_count"`
	UnreadCount  int    `json:"unread_count"`
}

FolderResponse represents a folder in API responses.

type FoldersResponse

type FoldersResponse struct {
	Folders []FolderResponse `json:"folders"`
}

FoldersResponse represents the folders list API response.

type FreeBusyCalendarResponse

type FreeBusyCalendarResponse struct {
	Email     string             `json:"email"`
	TimeSlots []TimeSlotResponse `json:"time_slots"`
}

FreeBusyCalendarResponse represents a calendar's busy times.

type FreeBusyRequest

type FreeBusyRequest struct {
	StartTime int64    `json:"start_time"`
	EndTime   int64    `json:"end_time"`
	Emails    []string `json:"emails"`
}

FreeBusyRequest represents a request to get free/busy info.

type FreeBusyResponse

type FreeBusyResponse struct {
	Data []FreeBusyCalendarResponse `json:"data"`
}

FreeBusyResponse represents free/busy data for participants.

type Grant

type Grant struct {
	ID       string `json:"id"`
	Email    string `json:"email"`
	Provider string `json:"provider"`
}

Grant represents an authenticated account for API responses.

type GrantInfo

type GrantInfo struct {
	ID        string
	Email     string
	Provider  string
	IsDefault bool
}

GrantInfo represents an authenticated account for the UI.

type GrantsResponse

type GrantsResponse struct {
	Grants       []Grant `json:"grants"`
	DefaultGrant string  `json:"default_grant"`
}

GrantsResponse represents the grants list API response.

type InboxCategory

type InboxCategory string

InboxCategory represents an email category for split inbox.

const (
	CategoryPrimary     InboxCategory = "primary"
	CategoryVIP         InboxCategory = "vip"
	CategoryNewsletters InboxCategory = "newsletters"
	CategoryUpdates     InboxCategory = "updates"
	CategorySocial      InboxCategory = "social"
	CategoryPromotions  InboxCategory = "promotions"
	CategoryForums      InboxCategory = "forums"
)

type Label

type Label struct {
	Name  string
	Color string
}

Label represents an email label.

type MediaResponse

type MediaResponse struct {
	RecordingURL   string `json:"recordingUrl,omitempty"`
	TranscriptURL  string `json:"transcriptUrl,omitempty"`
	RecordingSize  int64  `json:"recordingSize,omitempty"`
	TranscriptSize int64  `json:"transcriptSize,omitempty"`
	ExpiresAt      int64  `json:"expiresAt,omitempty"`
}

MediaResponse for notetaker media

type NLSearchRequest

type NLSearchRequest struct {
	Query string `json:"query"`
}

NLSearchRequest represents a natural language search request

type NLSearchResponse

type NLSearchResponse struct {
	From       string `json:"from,omitempty"`
	To         string `json:"to,omitempty"`
	Subject    string `json:"subject,omitempty"`
	DateAfter  string `json:"dateAfter,omitempty"`
	DateBefore string `json:"dateBefore,omitempty"`
	HasAttach  bool   `json:"hasAttachment,omitempty"`
	IsUnread   bool   `json:"isUnread,omitempty"`
	Keywords   string `json:"keywords,omitempty"`
}

NLSearchResponse represents parsed search parameters

type NotetakerResponse

type NotetakerResponse struct {
	ID            string `json:"id"`
	State         string `json:"state"`
	MeetingLink   string `json:"meetingLink"`
	MeetingTitle  string `json:"meetingTitle"`
	JoinTime      string `json:"joinTime,omitempty"`
	Provider      string `json:"provider,omitempty"`
	HasRecording  bool   `json:"hasRecording"`
	HasTranscript bool   `json:"hasTranscript"`
	CreatedAt     string `json:"createdAt,omitempty"`
	IsExternal    bool   `json:"isExternal,omitempty"`
	ExternalURL   string `json:"externalUrl,omitempty"`
	Attendees     string `json:"attendees,omitempty"`
	Summary       string `json:"summary,omitempty"`
}

NotetakerResponse represents a notetaker for the UI

type NotetakerSource

type NotetakerSource struct {
	From       string `json:"from"`
	Subject    string `json:"subject"`
	LinkDomain string `json:"linkDomain"`
}

NotetakerSource represents a source for fetching notetaker emails

type PageData

type PageData struct {
	// User info
	UserName   string
	UserEmail  string
	UserAvatar string

	// Auth & Config (Phase 2)
	Configured     bool
	ClientID       string
	Region         string
	HasAPIKey      bool
	DefaultGrantID string
	Provider       string
	Grants         []GrantInfo

	// Email data
	Folders       []Folder
	Emails        []Email
	SelectedEmail *Email

	// Calendar data
	Calendars []Calendar
	Events    []Event

	// Contacts data
	Contacts []Contact

	// UI state
	ActiveView    string // "email", "calendar", "contacts"
	ActiveFolder  string
	UnreadCount   int
	SyncedAt      time.Time
	AccountsCount int
}

PageData contains all data needed to render the Air UI.

type PendingSend

type PendingSend struct {
	ID        string                     `json:"id"`
	To        []EmailParticipantResponse `json:"to"`
	Cc        []EmailParticipantResponse `json:"cc,omitempty"`
	Bcc       []EmailParticipantResponse `json:"bcc,omitempty"`
	Subject   string                     `json:"subject"`
	Body      string                     `json:"body"`
	CreatedAt int64                      `json:"created_at"`
	SendAt    int64                      `json:"send_at"` // When grace period expires
	Cancelled bool                       `json:"cancelled"`
}

PendingSend represents a message in the undo grace period.

type QueryParams

type QueryParams struct {
	// contains filtered or unexported fields
}

QueryParams wraps url.Values with convenience methods for common parsing patterns.

func NewQueryParams

func NewQueryParams(values url.Values) *QueryParams

NewQueryParams creates a QueryParams wrapper from url.Values.

func (*QueryParams) Get

func (q *QueryParams) Get(key string) string

Get returns the first value for the given key, or empty string if not present.

func (*QueryParams) GetBool

func (q *QueryParams) GetBool(key string) bool

GetBool parses a boolean query parameter. Returns true only if the value is exactly "true".

func (*QueryParams) GetBoolPtr

func (q *QueryParams) GetBoolPtr(key string) *bool

GetBoolPtr parses a boolean query parameter and returns a pointer. Returns nil if the parameter is not present, otherwise returns pointer to the bool value.

func (*QueryParams) GetInt

func (q *QueryParams) GetInt(key string, defaultVal, minVal, maxVal int) int

GetInt parses an integer query parameter with bounds checking. Returns defaultVal if the parameter is missing, empty, invalid, or out of bounds.

func (*QueryParams) GetInt64

func (q *QueryParams) GetInt64(key string, defaultVal int64) int64

GetInt64 parses an int64 query parameter (e.g., Unix timestamps). Returns defaultVal if the parameter is missing, empty, or invalid.

func (*QueryParams) GetLimit

func (q *QueryParams) GetLimit(defaultVal int) int

GetLimit parses a "limit" parameter with standard bounds (1-200, default 50).

func (*QueryParams) GetString

func (q *QueryParams) GetString(key, defaultVal string) string

GetString returns the parameter value, or defaultVal if empty.

func (*QueryParams) Has

func (q *QueryParams) Has(key string) bool

Has returns true if the parameter is present (even if empty).

type ReadReceipt

type ReadReceipt struct {
	EmailID   string    `json:"emailId"`
	Recipient string    `json:"recipient"`
	OpenedAt  time.Time `json:"openedAt,omitempty"`
	OpenCount int       `json:"openCount"`
	Device    string    `json:"device,omitempty"`
	Location  string    `json:"location,omitempty"`
	UserAgent string    `json:"userAgent,omitempty"`
	IsOpened  bool      `json:"isOpened"`
}

ReadReceipt represents a read receipt for a sent email

type ReadReceiptSettings

type ReadReceiptSettings struct {
	Enabled          bool `json:"enabled"`
	TrackOpens       bool `json:"trackOpens"`
	TrackClicks      bool `json:"trackClicks"`
	ShowNotification bool `json:"showNotification"`
	BlockTracking    bool `json:"blockTracking"` // Block tracking pixels in received emails
}

ReadReceiptSettings represents user settings for read receipts

type ReplyLaterItem

type ReplyLaterItem struct {
	EmailID     string    `json:"emailId"`
	Subject     string    `json:"subject"`
	From        string    `json:"from"`
	AddedAt     time.Time `json:"addedAt"`
	RemindAt    time.Time `json:"remindAt,omitempty"`
	DraftID     string    `json:"draftId,omitempty"`
	Notes       string    `json:"notes,omitempty"`
	Priority    int       `json:"priority"` // 1=high, 2=medium, 3=low
	IsCompleted bool      `json:"isCompleted"`
}

ReplyLaterItem represents an email in the reply later queue

func GetPendingReminders

func GetPendingReminders() []*ReplyLaterItem

GetPendingReminders returns items with reminders due

type ScheduledSendRequest

type ScheduledSendRequest struct {
	To            []EmailParticipantResponse `json:"to"`
	Cc            []EmailParticipantResponse `json:"cc,omitempty"`
	Bcc           []EmailParticipantResponse `json:"bcc,omitempty"`
	Subject       string                     `json:"subject"`
	Body          string                     `json:"body"`
	SendAt        int64                      `json:"send_at,omitempty"`         // Unix timestamp
	SendAtNatural string                     `json:"send_at_natural,omitempty"` // Natural language
}

ScheduledSendRequest represents a request to schedule an email.

type ScheduledSendResponse

type ScheduledSendResponse struct {
	Success    bool   `json:"success"`
	ScheduleID string `json:"schedule_id,omitempty"`
	SendAt     int64  `json:"send_at"`
	Message    string `json:"message,omitempty"`
	Error      string `json:"error,omitempty"`
}

ScheduledSendResponse represents a scheduled send response.

type ScreenedSender

type ScreenedSender struct {
	Email       string    `json:"email"`
	Name        string    `json:"name,omitempty"`
	Domain      string    `json:"domain"`
	FirstSeen   time.Time `json:"firstSeen"`
	EmailCount  int       `json:"emailCount"`
	SampleSubj  string    `json:"sampleSubject,omitempty"`
	Status      string    `json:"status"`                // pending, allowed, blocked
	Destination string    `json:"destination,omitempty"` // inbox, feed, paper_trail
}

ScreenedSender represents a sender pending approval

type ScreenerStore

type ScreenerStore struct {
	// contains filtered or unexported fields
}

ScreenerStore manages screened senders

type SendMessageRequest

type SendMessageRequest struct {
	To           []EmailParticipantResponse `json:"to"`
	Cc           []EmailParticipantResponse `json:"cc,omitempty"`
	Bcc          []EmailParticipantResponse `json:"bcc,omitempty"`
	Subject      string                     `json:"subject"`
	Body         string                     `json:"body"`
	ReplyToMsgID string                     `json:"reply_to_message_id,omitempty"`
}

SendMessageRequest represents a request to send a message directly.

type SendMessageResponse

type SendMessageResponse struct {
	Success   bool   `json:"success"`
	MessageID string `json:"message_id,omitempty"`
	Message   string `json:"message,omitempty"`
	Error     string `json:"error,omitempty"`
}

SendMessageResponse represents the response for sending a message.

type SenderStats

type SenderStats struct {
	Email    string  `json:"email"`
	Name     string  `json:"name,omitempty"`
	Count    int     `json:"count"`
	AvgReply float64 `json:"avgReplyTimeHours,omitempty"`
}

SenderStats represents stats for a sender/recipient

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server represents the Air web UI server.

func NewDemoServer

func NewDemoServer(addr string) *Server

NewDemoServer creates an Air server in demo mode with sample data.

func NewServer

func NewServer(addr string) *Server

NewServer creates a new Air server.

func (*Server) IsOnline

func (s *Server) IsOnline() bool

IsOnline returns whether the server has network connectivity.

func (*Server) SetOnline

func (s *Server) SetOnline(online bool)

SetOnline updates the online status.

func (*Server) Start

func (s *Server) Start() error

Start starts the HTTP server.

func (*Server) Stop

func (s *Server) Stop() error

Stop gracefully stops the server and background processes.

type SetDefaultGrantRequest

type SetDefaultGrantRequest struct {
	GrantID string `json:"grant_id"`
}

SetDefaultGrantRequest represents the request to set default grant.

type SetDefaultGrantResponse

type SetDefaultGrantResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message,omitempty"`
	Error   string `json:"error,omitempty"`
}

SetDefaultGrantResponse represents the response for setting default grant.

type SmartReplyRequest

type SmartReplyRequest struct {
	EmailID   string `json:"email_id"`
	Subject   string `json:"subject"`
	From      string `json:"from"`
	Body      string `json:"body"`
	ReplyType string `json:"reply_type"` // "reply" or "reply_all"
}

SmartReplyRequest represents a request for smart reply suggestions.

type SmartReplyResponse

type SmartReplyResponse struct {
	Success bool     `json:"success"`
	Replies []string `json:"replies"`
	Error   string   `json:"error,omitempty"`
}

SmartReplyResponse represents the smart reply suggestions.

type SnoozeRequest

type SnoozeRequest struct {
	EmailID     string `json:"email_id"`
	SnoozeUntil int64  `json:"snooze_until,omitempty"` // Explicit Unix timestamp
	Duration    string `json:"duration,omitempty"`     // Natural language: "1h", "2d", "tomorrow 9am"
}

SnoozeRequest represents a request to snooze an email.

type SnoozeResponse

type SnoozeResponse struct {
	Success     bool   `json:"success"`
	EmailID     string `json:"email_id"`
	SnoozeUntil int64  `json:"snooze_until"`
	Message     string `json:"message,omitempty"`
}

SnoozeResponse represents a snooze operation response.

type SnoozedEmail

type SnoozedEmail struct {
	EmailID        string `json:"email_id"`
	SnoozeUntil    int64  `json:"snooze_until"` // Unix timestamp
	OriginalFolder string `json:"original_folder,omitempty"`
	CreatedAt      int64  `json:"created_at"`
}

SnoozedEmail represents a snoozed email.

type SplitInboxConfig

type SplitInboxConfig struct {
	Enabled    bool            `json:"enabled"`
	Categories []InboxCategory `json:"categories"`
	VIPSenders []string        `json:"vip_senders"` // Email addresses marked as VIP
	Rules      []CategoryRule  `json:"rules"`
}

SplitInboxConfig holds the split inbox configuration.

type SplitInboxResponse

type SplitInboxResponse struct {
	Config     SplitInboxConfig                  `json:"config"`
	Categories map[InboxCategory]int             `json:"category_counts"`
	Recent     map[InboxCategory][]EmailResponse `json:"recent,omitempty"`
}

SplitInboxResponse represents the split inbox API response.

type TemplateListResponse

type TemplateListResponse struct {
	Templates []EmailTemplate `json:"templates"`
	Total     int             `json:"total"`
}

TemplateListResponse represents a list of templates.

type ThreadMessage

type ThreadMessage struct {
	From    string `json:"from"`
	Subject string `json:"subject"`
	Body    string `json:"body"`
	Date    int64  `json:"date"`
}

ThreadMessage represents a message in a thread for summarization.

type ThreadSummaryRequest

type ThreadSummaryRequest struct {
	ThreadID string          `json:"thread_id"`
	Messages []ThreadMessage `json:"messages"`
}

ThreadSummaryRequest represents a request to summarize a thread.

type ThreadSummaryResponse

type ThreadSummaryResponse struct {
	Success      bool     `json:"success"`
	Summary      string   `json:"summary"`
	KeyPoints    []string `json:"key_points"`
	ActionItems  []string `json:"action_items"`
	Participants []string `json:"participants"`
	Timeline     string   `json:"timeline"` // Brief timeline of the conversation
	NextSteps    string   `json:"next_steps,omitempty"`
	MessageCount int      `json:"message_count"`
	Error        string   `json:"error,omitempty"`
}

ThreadSummaryResponse represents the thread summary response.

type TimeSlotResponse

type TimeSlotResponse struct {
	StartTime int64  `json:"start_time"`
	EndTime   int64  `json:"end_time"`
	Status    string `json:"status"` // busy, free
}

TimeSlotResponse represents a busy or free time slot.

type UndoSendConfig

type UndoSendConfig struct {
	Enabled        bool `json:"enabled"`
	GracePeriodSec int  `json:"grace_period_sec"` // Default: 10 seconds
}

UndoSendConfig holds undo send configuration.

type UndoSendResponse

type UndoSendResponse struct {
	Success   bool   `json:"success"`
	MessageID string `json:"message_id,omitempty"`
	Message   string `json:"message,omitempty"`
	Error     string `json:"error,omitempty"`
	TimeLeft  int    `json:"time_left_sec,omitempty"`
}

UndoSendResponse represents an undo send operation response.

type UpdateContactRequest

type UpdateContactRequest struct {
	GivenName    *string                  `json:"given_name,omitempty"`
	Surname      *string                  `json:"surname,omitempty"`
	Nickname     *string                  `json:"nickname,omitempty"`
	CompanyName  *string                  `json:"company_name,omitempty"`
	JobTitle     *string                  `json:"job_title,omitempty"`
	Birthday     *string                  `json:"birthday,omitempty"`
	Notes        *string                  `json:"notes,omitempty"`
	Emails       []ContactEmailResponse   `json:"emails,omitempty"`
	PhoneNumbers []ContactPhoneResponse   `json:"phone_numbers,omitempty"`
	Addresses    []ContactAddressResponse `json:"addresses,omitempty"`
}

UpdateContactRequest represents a request to update a contact.

type UpdateEmailRequest

type UpdateEmailRequest struct {
	Unread  *bool    `json:"unread,omitempty"`
	Starred *bool    `json:"starred,omitempty"`
	Folders []string `json:"folders,omitempty"`
}

UpdateEmailRequest represents a request to update an email.

type UpdateEmailResponse

type UpdateEmailResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message,omitempty"`
	Error   string `json:"error,omitempty"`
}

UpdateEmailResponse represents the response for updating an email.

type UpdateEventRequest

type UpdateEventRequest struct {
	Title        *string                    `json:"title,omitempty"`
	Description  *string                    `json:"description,omitempty"`
	Location     *string                    `json:"location,omitempty"`
	StartTime    *int64                     `json:"start_time,omitempty"`
	EndTime      *int64                     `json:"end_time,omitempty"`
	Timezone     *string                    `json:"timezone,omitempty"`
	IsAllDay     *bool                      `json:"is_all_day,omitempty"`
	Busy         *bool                      `json:"busy,omitempty"`
	Participants []EventParticipantResponse `json:"participants,omitempty"`
}

UpdateEventRequest represents a request to update an event.

Directories

Path Synopsis
Package cache provides local SQLite caching for Nylas Air.
Package cache provides local SQLite caching for Nylas Air.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL