Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ON CHANGE

Monitors folders for file changes and triggers a script when files are created, modified, or deleted.

Syntax

' Using account:// syntax (recommended)
ON CHANGE "account://email@domain.com/path/to/folder"

' Direct provider syntax
ON CHANGE "gdrive:///path/to/folder"
ON CHANGE "onedrive:///path/to/folder"
ON CHANGE "dropbox:///path/to/folder"

' Local filesystem
ON CHANGE "/local/path/to/folder"

' With event type filter
ON CHANGE "account://email@domain.com/folder" EVENTS "create, modify"

Description

The ON CHANGE keyword registers a folder monitor that triggers a script whenever files change in the specified folder. This works with cloud storage providers (Google Drive, OneDrive, Dropbox) and local filesystem.

Uses the same account:// syntax as COPY, MOVE, and other file operations for consistency.

Parameters

ParameterTypeRequiredDescription
pathStringYesFolder path using account:// or provider:// syntax
EVENTSStringNoComma-separated list of event types to monitor

Path Syntax

FormatDescriptionExample
account://email/pathUses connected account (auto-detects provider)account://user@gmail.com/Documents
gdrive:///pathGoogle Drive directgdrive:///shared/reports
onedrive:///pathOneDrive directonedrive:///business/docs
dropbox:///pathDropbox directdropbox:///team/assets
/pathLocal filesystem/var/uploads/incoming

Provider Auto-Detection

When using account:// syntax, the provider is auto-detected from the email:

Email DomainProvider
@gmail.com, @google.comGoogle Drive
@outlook.com, @hotmail.com, @live.comOneDrive
OtherDefaults to Google Drive

Event Types

EventAliasesDescription
createcreated, newNew file created
modifymodified, change, changedFile content changed
deletedeleted, remove, removedFile deleted
renamerenamedFile renamed
movemovedFile moved to different folder

Default events (if not specified): create, modify, delete

Examples

Basic Folder Monitoring

' Monitor Google Drive folder via connected account
ON CHANGE "account://user@gmail.com/Documents/invoices"
    event = GET LAST "folder_change_events"
    TALK "File changed: " + event.file_name + " (" + event.event_type + ")"
END ON

Process New Uploads

ON CHANGE "account://user@gmail.com/Uploads" EVENTS "create"
    event = GET LAST "folder_change_events"
    
    ' Only process PDF files
    IF event.mime_type = "application/pdf" THEN
        ' Extract data from invoice
        data = SAVE FROM UNSTRUCTURED event.file_path, "invoices"
        TALK "Processed invoice: " + data.invoice_number
        
        ' Move to processed folder
        MOVE event.file_path TO "account://user@gmail.com/Processed/"
    END IF
END ON

Sync Between Providers

' When file is added to Google Drive, copy to OneDrive
ON CHANGE "account://user@gmail.com/Shared/Reports" EVENTS "create"
    event = GET LAST "folder_change_events"
    
    ' Copy to OneDrive backup
    COPY event.file_path TO "account://user@outlook.com/Backup/Reports/"
    
    TALK "Synced " + event.file_name + " to OneDrive"
END ON

Monitor for Deletions

ON CHANGE "gdrive:///archive" EVENTS "delete"
    event = GET LAST "folder_change_events"
    
    ' Log deletion to audit table
    INSERT INTO "audit_log", {
        "action": "file_deleted",
        "file_path": event.file_path,
        "file_name": event.file_name,
        "deleted_at": NOW()
    }
    
    ' Send notification
    SEND MAIL "admin@company.com", "File Deleted", "
        File was deleted from archive:
        Name: " + event.file_name + "
        Path: " + event.file_path + "
    "
END ON

Watch for Modifications

ON CHANGE "account://user@gmail.com/Config" EVENTS "modify"
    event = GET LAST "folder_change_events"
    
    ' Reload configuration when config files change
    IF event.file_name = "settings.json" THEN
        config = READ event.file_path
        SET BOT MEMORY "config", config
        TALK "Configuration reloaded"
    END IF
END ON

Process Images

ON CHANGE "account://user@gmail.com/Photos/Raw" EVENTS "create"
    event = GET LAST "folder_change_events"
    
    ' Check if it's an image
    IF INSTR(event.mime_type, "image/") > 0 THEN
        ' Generate thumbnail using LLM vision
        description = IMAGE event.file_path
        
        ' Save metadata
        INSERT INTO "photos", {
            "file_path": event.file_path,
            "description": description,
            "size": event.file_size,
            "uploaded_at": NOW()
        }
        
        TALK "Processed image: " + event.file_name
    END IF
END ON

Multi-Folder Monitoring

' Monitor multiple folders with different handlers

ON CHANGE "account://user@gmail.com/Invoices"
    event = GET LAST "folder_change_events"
    ' Process invoices
    CREATE TASK "Process invoice: " + event.file_name, event.file_path, "normal"
END ON

ON CHANGE "account://user@gmail.com/Contracts"
    event = GET LAST "folder_change_events"
    ' Process contracts
    SEND MAIL "legal@company.com", "New Contract", "Please review: " + event.file_name
END ON

ON CHANGE "account://user@outlook.com/Reports" EVENTS "create, modify"
    event = GET LAST "folder_change_events"
    ' Sync reports
    COPY event.file_path TO "gdrive:///Shared/Reports/"
END ON

Local Filesystem Monitoring

' Monitor local upload directory
ON CHANGE "/var/www/uploads/incoming"
    event = GET LAST "folder_change_events"
    
    ' Scan for viruses
    result = RUN BASH "clamscan " + event.file_path
    
    IF INSTR(result, "FOUND") > 0 THEN
        ' Quarantine infected file
        MOVE event.file_path TO "/var/quarantine/"
        SEND MAIL "security@company.com", "Virus Detected", event.file_name
    ELSE
        ' Move to processed
        MOVE event.file_path TO "/var/www/uploads/processed/"
    END IF
END ON

Change Event Properties

When a file change is detected, the event object contains:

PropertyTypeDescription
idUUIDUnique event identifier
monitor_idUUIDID of the monitor that triggered
event_typeStringType of change (create, modify, delete, rename, move)
file_pathStringFull path to the file
file_idStringProvider-specific file ID
file_nameStringFile name without path
file_sizeIntegerSize in bytes
mime_typeStringMIME type of the file
old_pathStringPrevious path (for rename/move events)

Database Tables

folder_monitors

Stores the monitor configuration:

ColumnTypeDescription
idUUIDMonitor ID
bot_idUUIDBot that owns this monitor
providerVARCHARProvider (gdrive, onedrive, dropbox, local)
account_emailVARCHAREmail from account:// path
folder_pathVARCHARPath being monitored
folder_idVARCHARProvider-specific folder ID
script_pathVARCHARScript to execute
is_activeBOOLEANWhether monitor is active
watch_subfoldersBOOLEANInclude subfolders
event_types_jsonTEXTJSON array of event types
last_change_tokenVARCHARProvider change token

folder_change_events

Logs detected changes:

ColumnTypeDescription
idUUIDEvent ID
monitor_idUUIDMonitor that triggered
event_typeVARCHARType of change
file_pathVARCHARFile path
file_nameVARCHARFile name
file_sizeBIGINTSize in bytes
mime_typeVARCHARMIME type
processedBOOLEANWhether event was processed

Best Practices

  1. Use account:// syntax - Consistent with other file operations
  2. Filter events - Only monitor events you need to reduce load
  3. Handle all event types - Check event_type before processing
  4. Avoid circular triggers - Moving files can trigger other monitors
  5. Process idempotently - Events may be delivered more than once
  6. Clean up processed events - Archive old events periodically

Comparison with Other Event Keywords

KeywordTrigger SourceUse Case
ON CHANGEFile system changesSync files, process uploads
ON EMAILIncoming emailsProcess messages, auto-reply
ON INSERTDatabase insertsReact to new data
SET SCHEDULETime-basedPeriodic tasks
WEBHOOKHTTP requestsExternal integrations
  • ON EMAIL - Email monitoring
  • ON - Database trigger events
  • SET SCHEDULE - Time-based scheduling
  • COPY - Copy files with account:// syntax
  • MOVE - Move files with account:// syntax
  • USE ACCOUNT - Connect cloud accounts

TriggerKind: FolderChange = 6