Complete API documentation for Sterling Library, a Google Apps Script library for intelligent task automation.
Initializes and returns a Processor instance with all automation methods.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
gTaskListId |
string | ✅ | Google Tasks list ID |
calendarId |
string | ✅ | Google Calendar ID (e.g., 'primary' or email address) |
geminiApiKey |
string | ✅ | Gemini API key from Google AI Studio |
geminiModel |
string | ✅ | Gemini model name (e.g., 'gemini-3-flash-preview') |
todoistApiKey |
string | ✅ | Todoist API token from Todoist Settings |
label |
string | ✅ | Default label for synced tasks |
todoistProjectId |
string | ✅ | Todoist project ID for new tasks |
promptInstructions |
object | ✅ | Drive file IDs for AI prompts (see below) |
driveFolders |
array | Optional | Array of Drive folder objects for AI context (default: []) |
workTimeBlocks |
array | Optional | Work hour blocks for scheduling (default: see below) |
bufferMinutes |
number | Optional | Buffer time between events in minutes (default: 0) |
promptInstructions object:
{
agents_prompt: 'DRIVE_FILE_ID', // System prompt for AI agent
calendar_instructions_prompt: 'DRIVE_FILE_ID' // Instructions for calendar processing
}driveFolders array:
[
{ name: 'People', id: 'FOLDER_ID' },
{ name: 'Meetings', id: 'FOLDER_ID' },
{ name: 'Projects', id: 'FOLDER_ID' }
]workTimeBlocks array (default):
[
{ start: "09:00", end: "12:00" }, // Morning block
{ start: "13:00", end: "17:00" } // Afternoon block
]Returns: Processor instance with public methods
Example:
const processor = Sterling.main({
gTaskListId: 'YOUR_GTASK_LIST_ID',
calendarId: 'primary',
geminiApiKey: 'YOUR_GEMINI_API_KEY',
geminiModel: 'gemini-3-flash-preview',
todoistApiKey: 'YOUR_TODOIST_API_KEY',
todoistProjectId: 'YOUR_PROJECT_ID',
label: 'automation',
promptInstructions: {
agents_prompt: 'DRIVE_FILE_ID_1',
calendar_instructions_prompt: 'DRIVE_FILE_ID_2'
},
driveFolders: [
{ name: 'Context', id: 'FOLDER_ID' }
],
workTimeBlocks: [
{ start: "09:00", end: "12:00" },
{ start: "13:00", end: "17:00" }
],
bufferMinutes: 5
});Syncs Google Tasks to Todoist and marks them as complete.
Parameters: None
Returns: void
Behavior:
- Fetches Google Tasks updated in the last 35 minutes
- Creates corresponding tasks in Todoist
- Adds labels based on task type (EMAIL tasks get 'email' label)
- Marks original Google Tasks as complete
Recommended Trigger: Time-driven, every 10 minutes
Example:
function syncTasks() {
const processor = Sterling.main({...});
processor.processGoogleTasks();
}Related Configuration:
gTaskListId- Which Google Tasks list to synclabel- Default label for synced taskstodoistProjectId- Destination project in Todoist
AI-enhances tasks with the 'enrich' label or tasks where the last comment contains '@ai'.
Parameters: None
Returns: boolean - true on success
Behavior:
- Fetches tasks updated since last sync (incremental sync)
- For each task with 'enrich' label OR last comment containing '@ai':
- Sends task to Gemini AI with full context (Drive files, previous comments)
- Creates comment with AI response (prefixed with "AI: ")
- Removes 'enrich' label if present
- Rate limits: 10-second sleep between tasks
Recommended Trigger: Time-driven, every 10 minutes
Example:
function aiEnrichment() {
const processor = Sterling.main({...});
processor.enrichTodoistTasks();
}AI Context Includes:
- System instructions from
promptInstructions.agents_prompt - All uploaded Drive files
- Task title and description
- Previous comments (maintains conversation history)
- Google Search and URL context tools
Related Configuration:
geminiApiKey- API key for GeminigeminiModel- Which model to usepromptInstructions.agents_prompt- System prompt file IDdriveFolders- Context files for AI
Analyzes today's calendar events and creates AI-generated meeting preparation tasks.
Parameters: None
Returns: array - Array of created preparation tasks
Behavior:
- Fetches today's calendar events (status: INVITED/MAYBE/YES/OWNER)
- Filters events:
- Skips all-day events
- Skips events with ≤1 attendees (solo/no-attendee events)
- Sends filtered events to AI for analysis (batches of 3)
- Creates preparation tasks for meetings requiring prep
- Smart scheduling with 3-tier strategy:
- Strict: Avoids all calendar events
- Lenient: Avoids only processed events
- Fallback: 30 min before meeting
- Rate limits: 10 seconds between AI calls, 2 seconds between task creation
Recommended Trigger: Time-driven, daily between 6-7 AM
Example:
function dailyMeetingPrep() {
const processor = Sterling.main({...});
processor.processCalendarItems();
}Preparation Task Format:
- Title: "Prepare for {event title}"
- Description: AI-generated preparation guidance
- Label: 'enrich_scheduled'
- Duration: AI-estimated or 45 minutes default
- Due: Automatically scheduled in open calendar slot
Related Configuration:
calendarId- Which calendar to processpromptInstructions.calendar_instructions_prompt- Calendar-specific instructionsworkTimeBlocks- Available work hours for schedulingbufferMinutes- Buffer time after events
Uploads Drive files to Gemini for AI context with intelligent caching.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
forceUpdate |
boolean | Optional | false |
Force upload all files regardless of cache status |
Returns: void
Behavior:
- Iterates through all folders in
driveFolders - For each file, checks if update needed:
- File has no stored metadata
- File modified since last upload
- File metadata expired (>10 minutes)
forceUpdateis true
- Uploads changed files to Gemini API
- Stores file metadata in Script Properties
- Maintains list of current files for deletion detection
Recommended Trigger: Time-driven, every 5 minutes
Example:
function refreshAIContext() {
const processor = Sterling.main({...});
processor.processContextData();
}
// Force refresh all files
function forceRefreshContext() {
const processor = Sterling.main({...});
processor.processContextData(true);
}Smart Caching:
- Only uploads changed files (checks
lastUpdatedtimestamp) - 10-minute TTL for file metadata
- Near-real-time context with minimal API costs
Related Configuration:
driveFolders- Which folders to monitor for context files
Batch enriches all tasks due today with a specific label, deleting previous comments for a fresh start.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
label |
string | ✅ | Label to filter tasks by (e.g., 'prepare_jit') |
Returns: void
Behavior:
- Fetches tasks due today with specified label
- For each task:
- Deletes all existing comments (fresh start)
- Sends to AI with Drive context
- Creates comment with AI response
- Removes the label
- Rate limits: 20-second sleep between tasks
Recommended Trigger: Time-driven, daily between 7-8 AM with label 'prepare_jit'
Example:
function jitPreparation() {
const processor = Sterling.main({...});
processor.enrichTodaysTasksForLabel('prepare_jit');
}Use Case: Just-in-time task preparation at start of day
Related Configuration:
geminiApiKey,geminiModel- AI configurationpromptInstructions.agents_prompt- System promptdriveFolders- Context files
Creates an executive summary task with today's calendar events and priority tasks.
Parameters: None
Returns: boolean - true on success, false on failure
Behavior:
- Fetches today's calendar events
- Fetches tasks: today, overdue, or priority 1
- Sends to AI for analysis
- Creates P1 task with Markdown briefing containing:
- Critical Focus: 1-2 must-do items
- Schedule Highlights: Timeline with conflicts/tight transitions
- Quick Wins: 15-minute tasks
- Prep Notes: Meetings lacking preparation/agenda
Recommended Trigger: Time-driven, daily between 6-7 AM
Example:
function morningBriefing() {
const processor = Sterling.main({...});
processor.generateDailyBriefing();
}Output Task:
- Title: "📅 Daily Briefing: {date}"
- Priority: P1 (4)
- Due: Today
- Description: AI-generated Markdown briefing
Related Configuration:
calendarId- Calendar for eventstodoistProjectId- Where to create briefing taskgeminiApiKey,geminiModel- AI configuration
Analyzes inbox tasks to identify quick 2-minute tasks and creates a summary.
Parameters: None
Returns: boolean - true on success, false if no tasks/quick wins found
Behavior:
- Fetches all tasks from #Inbox project
- Sends to AI for conservative 2-minute task analysis
- AI excludes vague tasks, research, coordination, creative work
- Creates P2 summary task scheduled at 9 AM with:
- Numbered list of quick wins
- Reason for each selection
- Motivational summary (2-3 sentences)
Recommended Trigger: Time-driven, daily between 6-7 AM
Example:
function identifyQuickWins() {
const processor = Sterling.main({...});
processor.generateQuickWinsSummary();
}Output Task:
- Title: "⚡ Quick Wins Summary: {count} tasks under 2 minutes"
- Priority: P2 (3)
- Due: Today 9:00 AM
- Duration: 15 minutes
- Description: Formatted list with rationale
Common 2-Minute Tasks Identified:
- Quick emails
- Simple yes/no decisions
- Short phone calls
- Lookups/checks
Related Configuration:
todoistProjectId- Where to create summary taskgeminiApiKey,geminiModel- AI configuration
Sterling uses the following Google services:
- Google Tasks API - For task synchronization
- Google Calendar API - For calendar event processing
- Google Drive API - For context file access
- Generative Language API (Gemini) - For AI features
- Google Apps Script API - For library deployment
Note: Apps Script will automatically request permissions for these services when you first run the script. No manual API enabling is required.
Gemini API Key:
- Go to Google AI Studio
- Click "Get API key"
- Create or select GCP project
- Copy API key
Todoist API Token:
- Go to Todoist Settings > Integrations
- Scroll to "API token"
- Copy token
Google Tasks List ID:
function getTaskListId() {
const lists = Tasks.Tasklists.list();
lists.items.forEach(list => {
Logger.log(`${list.title}: ${list.id}`);
});
}Todoist Project ID:
- Open project in Todoist web app
- URL format:
https://todoist.com/app/project/PROJECT_ID - Copy
PROJECT_IDfrom URL
Drive Folder ID:
- Open folder in Google Drive
- URL format:
https://drive.google.com/drive/folders/FOLDER_ID - Copy
FOLDER_IDfrom URL
Drive File ID (for prompts):
- Open file in Google Drive
- Click Share → Copy link
- URL format:
https://drive.google.com/file/d/FILE_ID/view - Copy
FILE_IDfrom URL
Define when tasks can be scheduled. Times must be within same day (no midnight-spanning).
Format:
workTimeBlocks: [
{ start: "HH:MM", end: "HH:MM" },
{ start: "HH:MM", end: "HH:MM" }
]Examples:
// Standard 9-5 with lunch
workTimeBlocks: [
{ start: "09:00", end: "12:00" },
{ start: "13:00", end: "17:00" }
]
// Early bird
workTimeBlocks: [
{ start: "07:00", end: "11:00" },
{ start: "12:00", end: "16:00" }
]
// Single block
workTimeBlocks: [
{ start: "09:00", end: "17:00" }
]How It Works:
- System creates "blocked periods" for times outside work blocks
- Blocked periods act as unavailable time slots
- Meeting prep tasks avoid blocked periods
- Gaps between blocks (e.g., 12:00-13:00) become break time
Add transition time after calendar events before scheduling prep tasks.
Default: 0 (no buffer)
Example Use Cases:
// No buffer - tasks can be scheduled immediately after events
bufferMinutes: 0
// 5-minute buffer - allows quick bio break/transition
bufferMinutes: 5
// 15-minute buffer - prevents back-to-back scheduling
bufferMinutes: 15Applies To:
- Calendar events when finding open slots
- Previously scheduled prep tasks
- Does NOT apply to work time block boundaries
Sync Google Tasks to Todoist every 10 minutes:
function syncTasks() {
const processor = Sterling.main({
gTaskListId: 'YOUR_GTASK_LIST_ID',
calendarId: 'primary',
geminiApiKey: 'YOUR_KEY',
geminiModel: 'gemini-3-flash-preview',
todoistApiKey: 'YOUR_TOKEN',
todoistProjectId: 'PROJECT_ID',
label: 'from-gtasks',
promptInstructions: {
agents_prompt: 'FILE_ID',
calendar_instructions_prompt: 'FILE_ID'
}
});
processor.processGoogleTasks();
}
// Trigger: Every 10 minutesFull automation with AI enrichment and context sync:
function aiWorkflow() {
const processor = Sterling.main({
gTaskListId: 'YOUR_GTASK_LIST_ID',
calendarId: 'primary',
geminiApiKey: 'YOUR_KEY',
geminiModel: 'gemini-3-flash-preview',
todoistApiKey: 'YOUR_TOKEN',
todoistProjectId: 'PROJECT_ID',
label: 'automation',
promptInstructions: {
agents_prompt: 'FILE_ID',
calendar_instructions_prompt: 'FILE_ID'
},
driveFolders: [
{ name: 'People', id: 'FOLDER_ID_1' },
{ name: 'Projects', id: 'FOLDER_ID_2' }
]
});
// Run context refresh first (every 5 min)
processor.processContextData();
// Then task operations (every 10 min)
processor.processGoogleTasks();
processor.enrichTodoistTasks();
}All features with recommended scheduling:
// Trigger: Every 5 minutes
function refreshContext() {
const processor = Sterling.main({...});
processor.processContextData();
}
// Trigger: Every 10 minutes
function taskSync() {
const processor = Sterling.main({...});
processor.processGoogleTasks();
processor.enrichTodoistTasks();
}
// Trigger: Daily, 6-7 AM
function morningRoutine() {
const processor = Sterling.main({...});
processor.generateDailyBriefing();
processor.generateQuickWinsSummary();
processor.processCalendarItems();
}
// Trigger: Daily, 7-8 AM
function dailyPreparation() {
const processor = Sterling.main({...});
processor.enrichTodaysTasksForLabel('prepare_jit');
processor.enrichTodaysTasksForLabel('enrich_scheduled');
}Configure work schedule and transition time:
function customSchedule() {
const processor = Sterling.main({
gTaskListId: 'YOUR_GTASK_LIST_ID',
calendarId: 'primary',
geminiApiKey: 'YOUR_KEY',
geminiModel: 'gemini-3-flash-preview',
todoistApiKey: 'YOUR_TOKEN',
todoistProjectId: 'PROJECT_ID',
label: 'automation',
promptInstructions: {
agents_prompt: 'FILE_ID',
calendar_instructions_prompt: 'FILE_ID'
},
// Early bird schedule
workTimeBlocks: [
{ start: "07:00", end: "11:00" },
{ start: "12:00", end: "16:00" }
],
// 10-minute buffer between events
bufferMinutes: 10
});
processor.processCalendarItems();
}All methods include comprehensive error handling:
- Try-catch blocks around major operations
- Structured logging via Telemetry module
- Retry logic for AI calls (3 retries, 30-second intervals)
- Rate limiting to prevent API throttling
- Graceful degradation when services unavailable
Example Error Log:
Processor: Failed to enrich task with error: API quota exceeded
AI: Retrying API call (attempt 2/3)| Operation | Sleep Time | Purpose |
|---|---|---|
| AI task enrichment | 10 seconds | Prevent Gemini API throttling |
| Meeting prep creation | 2 seconds | Prevent Todoist API throttling |
| JIT preparation | 20 seconds | Spread AI load |
| AI batch calls | 10 seconds | Calendar processing rate limit |
-
Context Files:
- Keep Drive files concise (< 1MB each)
- Use Markdown for better AI comprehension
- Organize by category (People, Projects, etc.)
-
Prompt Instructions:
- Store as Google Docs or Markdown files
- Version control via Drive file history
- Include clear, specific instructions
-
Work Time Blocks:
- Align with actual availability
- Include lunch breaks as gaps
- Account for recurring meetings
-
Triggers:
- Use recommended schedules (see each method)
- Spread out heavy operations
- Monitor execution logs
-
Testing:
- Start with
processContextData()alone - Add methods incrementally
- Check Script Properties for proper caching
- Start with
"Configuration validation failed"
- Check all required parameters are provided
- Ensure no placeholder values (YOUR_, FOLDER_ID)
- Verify parameter types match specification
"API quota exceeded"
- Check Gemini API quota in Google Cloud Console
- Reduce context file sizes
- Increase sleep times between operations
"No tasks found"
- Verify Todoist project ID is correct
- Check label exists in Todoist
- Ensure tasks meet filter criteria
"Failed to upload file"
- Verify Drive folder IDs are correct
- Check file permissions (must be readable)
- Ensure files aren't too large (>20MB)
Enable verbose logging:
function debug() {
const processor = Sterling.main({...});
// Check what files are being tracked
Logger.log(PropertiesService.getScriptProperties().getKeys());
// Test context upload
processor.processContextData(true); // Force refresh
// Check sync token
Logger.log(PropertiesService.getScriptProperties().getProperty('TODOIST_LAST_SYNC_TOKEN'));
}- Examples & Setup Guide - Complete setup and integration examples
- Architecture Documentation - System flows and diagrams
- Main README - Overview and features
- Issues: Report bugs and request features via GitHub Issues
- Discussions: Ask questions in GitHub Discussions
- Documentation: Check examples/ for more code samples