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

EXTRACT

The EXTRACT keyword unpacks ZIP archives to a specified destination in the bot’s storage, enabling bots to process uploaded archives and access their contents.


Syntax

EXTRACT "archive.zip" TO "destination/"
result = EXTRACT "archive.zip" TO "destination/"

Parameters

ParameterTypeDescription
archiveStringPath to the ZIP archive to extract
TOClauseDestination folder for extracted contents

Description

EXTRACT unpacks a ZIP archive and places its contents in the specified destination folder. The folder is created automatically if it doesn’t exist. Directory structure within the archive is preserved.

Use cases include:

  • Processing user-uploaded archives
  • Unpacking data imports
  • Restoring backups
  • Accessing bundled resources
  • Handling bulk file uploads

Examples

Basic Extraction

' Extract archive to a folder
EXTRACT "uploads/documents.zip" TO "extracted/"

TALK "Archive extracted successfully"

Extract with Result

' Get extraction details
result = EXTRACT "backup.zip" TO "restored/"

TALK "Extracted " + result.file_count + " files"
TALK "Total size: " + FORMAT(result.total_size / 1024, "#,##0") + " KB"

Extract User Upload

' Handle uploaded archive from user
TALK "Please upload a ZIP file with your documents."
HEAR uploaded_file

IF uploaded_file.type = "application/zip" THEN
    upload_result = UPLOAD uploaded_file TO "temp"
    
    ' Extract to user's folder
    user_folder = "users/" + user.id + "/imports/" + FORMAT(NOW(), "YYYYMMDD") + "/"
    result = EXTRACT upload_result.path TO user_folder
    
    TALK "Extracted " + result.file_count + " files from your archive!"
    
    ' List extracted files
    files = LIST user_folder
    FOR EACH file IN files
        TALK "- " + file.name
    NEXT
ELSE
    TALK "Please upload a ZIP file."
END IF

Extract and Process

' Extract data files and process them
result = EXTRACT "imports/data-batch.zip" TO "temp/batch/"

csv_files = LIST "temp/batch/" FILTER "*.csv"

FOR EACH csv_file IN csv_files
    data = READ "temp/batch/" + csv_file.name AS TABLE
    
    ' Process each row
    FOR EACH row IN data
        INSERT INTO "imports" WITH
            source_file = csv_file.name,
            data = row,
            imported_at = NOW()
    NEXT
    
    TALK "Processed: " + csv_file.name
NEXT

' Clean up temp files
DELETE FILE "temp/batch/"

TALK "Import complete: processed " + LEN(csv_files) + " files"

Restore Backup

' Restore from backup archive
TALK "Enter the backup filename to restore (e.g., backup-20250115.zip)"
HEAR backup_name

backup_path = "backups/" + backup_name

files = LIST "backups/"
found = false
FOR EACH file IN files
    IF file.name = backup_name THEN
        found = true
        EXIT FOR
    END IF
NEXT

IF found THEN
    result = EXTRACT backup_path TO "restored/"
    TALK "Backup restored: " + result.file_count + " files"
ELSE
    TALK "Backup file not found. Available backups:"
    FOR EACH file IN files
        TALK "- " + file.name
    NEXT
END IF

Common Use Cases

Bulk Document Upload

' Handle bulk document upload
TALK "Upload a ZIP file containing your documents."
HEAR archive

upload = UPLOAD archive TO "temp"
result = EXTRACT upload.path TO "documents/bulk-" + FORMAT(NOW(), "YYYYMMDDHHmmss") + "/"

TALK "Successfully uploaded " + result.file_count + " documents!"

' Clean up temp file
DELETE FILE upload.path

Process Image Pack

' Extract and catalog images
result = EXTRACT "uploads/images.zip" TO "temp/images/"

images = LIST "temp/images/" FILTER "*.jpg,*.png,*.gif"

FOR EACH image IN images
    ' Move to permanent storage with organized path
    MOVE "temp/images/" + image.name TO "media/images/" + image.name
    
    ' Record in database
    INSERT INTO "media" WITH
        filename = image.name,
        path = "media/images/" + image.name,
        size = image.size,
        uploaded_at = NOW()
NEXT

TALK "Cataloged " + LEN(images) + " images"

Template Installation

' Install a template pack
result = EXTRACT "templates/new-theme.zip" TO "themes/custom/"

TALK "Template installed with " + result.file_count + " files"

' Verify required files
required = ["style.css", "config.json", "templates/"]
missing = []

FOR EACH req IN required
    files = LIST "themes/custom/" FILTER req
    IF LEN(files) = 0 THEN
        missing = APPEND(missing, req)
    END IF
NEXT

IF LEN(missing) > 0 THEN
    TALK "Warning: Missing required files: " + JOIN(missing, ", ")
ELSE
    TALK "Template is complete and ready to use!"
END IF

Return Value

Returns an object with extraction details:

PropertyDescription
result.destinationDestination folder path
result.file_countNumber of files extracted
result.folder_countNumber of folders created
result.total_sizeTotal size of extracted files
result.filesArray of extracted file paths
result.extracted_atExtraction timestamp

Error Handling

ON ERROR RESUME NEXT

result = EXTRACT "uploads/data.zip" TO "extracted/"

IF ERROR THEN
    PRINT "Extraction failed: " + ERROR_MESSAGE
    
    IF INSTR(ERROR_MESSAGE, "corrupt") > 0 THEN
        TALK "The archive appears to be corrupted. Please upload again."
    ELSE IF INSTR(ERROR_MESSAGE, "not found") > 0 THEN
        TALK "Archive file not found."
    ELSE IF INSTR(ERROR_MESSAGE, "storage") > 0 THEN
        TALK "Not enough storage space to extract the archive."
    ELSE
        TALK "Sorry, I couldn't extract the archive. Please try again."
    END IF
ELSE
    TALK "Extraction complete!"
END IF

Common Errors

ErrorCauseSolution
FILE_NOT_FOUNDArchive doesn’t existVerify archive path
INVALID_ARCHIVENot a valid ZIP fileCheck file format
CORRUPT_ARCHIVEArchive is damagedRequest new upload
STORAGE_FULLInsufficient spaceClean up storage
PERMISSION_DENIEDAccess blockedCheck permissions

Security Considerations

  • Path validation: Extracted paths are validated to prevent directory traversal attacks
  • Size limits: Maximum extracted size is enforced to prevent storage exhaustion
  • File type filtering: Executable files can be blocked if configured
  • Malware scanning: Uploaded archives can be scanned before extraction

Size Limits

LimitDefaultNotes
Max archive size100 MBFor uploaded archives
Max extracted size500 MBTotal after extraction
Max files10,000Files in archive
Max path depth10Nested folder depth

Configuration

No specific configuration required. Uses bot’s standard drive settings from config.csv:

name,value
drive-provider,seaweedfs
drive-url,http://localhost:8333
drive-bucket,my-bot

Implementation Notes

  • Implemented in Rust under src/file/archive.rs
  • Supports standard ZIP format
  • Preserves directory structure
  • Handles nested folders
  • Progress tracking for large archives
  • Atomic extraction (temp folder, then move)
  • Cleans up on failure

  • COMPRESS — Create ZIP archives
  • UPLOAD — Upload archives from users
  • LIST — List extracted files
  • MOVE — Organize extracted files
  • DELETE FILE — Clean up after extraction

Summary

EXTRACT unpacks ZIP archives to a destination folder. Use it to process uploaded archives, restore backups, handle bulk imports, and access bundled resources. The archive’s directory structure is preserved, and the destination folder is created automatically. Combine with UPLOAD to accept user archives and LIST to discover extracted contents.