HomeDocsAutomation Scripts
Kiky Notes PRO β€” Windows

Automation Script Reference

Record a processing pipeline once, then replay it on hundreds of images in one click. Edit scripts to add filters, change parameters, collect OCR results β€” no limits.

Overview

The automation system works in two stages:

  1. 1
    Record. Perform your steps in the capture overlay β€” area selection, perspective correction, OCR, save. Every action is recorded.
  2. 2
    Edit (optional). Open the generated script in the editor. Change the folder path, tweak coordinates, add conditional logic.
  3. 3
    Play. The engine iterates over every image in the folder and applies the pipeline. Fast, parallel-friendly, resumable.
How it works internally: Recording saves actions into a Vec<AutomationAction> in memory and serialises them to a human-readable .rhai script file. The overlay Play button reruns from memory (instant). The Script Editor runs from the file (fully editable). Both paths produce identical output.

Automation Toolbar

The toolbar appears on the right side of the capture overlay when PRO or Trial is active. It is completely hidden for non-PRO users.

ButtonAction
πŸ“ Set FolderOpens a folder picker. All scripts, input images and output files are stored here. Persists across sessions.
⏺ RecordToggle. Turns red when active. Stopping recording writes automation_YYYYMMDD_HHMMSS.rhai to the folder.
⏸ PausePauses / resumes recording without discarding accumulated actions.
β–Ά PlayRuns the last recorded pipeline on every image in the folder.
✏ EditOpens the Script Editor pre-populated with the last generated script.

Recording a Script

Every interaction with the overlay during recording is captured as an action:

User actionScript line generated
Confirm area selectionimg = crop_area(img, x, y, w, h);
Apply perspectiveimg = apply_perspective(img, [tl_x,tl_y, tr_x,tr_y, br_x,br_y, bl_x,bl_y]);
Apply curve / arc dewarpimg = apply_curve(img, top, side);
Draw / annotateimg = apply_drawings(img, "/path/overlay.png");
OCR (final action)text = ocr_and_copy(img); + save_ocr_to_text(text, image_path); + save_to_folder(img, batch_timestamp);
Copy to clipboardcopy_to_clipboard(img);
Save to foldersave_to_folder(img, batch_timestamp);
Auto-complete on stop: If you press ⏺ to stop without a final action (OCR/Save/Copy), the engine automatically appends CaptureArea (derived from the current selection) and SaveToFolder so every recording always produces a usable script.
OCR keeps the overlay open: While recording is active, clicking the OCR button does not close the overlay β€” this lets you immediately select the next image without re-opening the capture window.

Script Editor

Open the editor from: System tray β†’ ✏ Automation Script Editor Β· PRO, or from the overlay toolbar via the ✏ button.

Ctrl + SSave script to current file
F5Run script on the configured folder
Ctrl + dragMove the editor window
EscClose the editor

Abrir β€” open any .rhai file. Salvar β€” save current script. Executar β€” run on folder (same as F5). Fechar β€” close.

Language Syntax

Scripts use a Rhai-compatible syntax. Everything below is supported by the built-in engine.

Variables

rhai
let x = 42;          // declare
x = x + 1;          // assign
x += " world";      // compound assign (also works with strings)

Types

rhai
let n   = 42;           // integer (i64)
let f   = 3.14;         // float (f64)
let s   = "hello";      // string
let neg = -0.08;        // negative literal
let arr = [1, 2, 3];    // array

String concatenation

rhai
let greeting = "Hello, " + name + "!";
let log_line = path + "\n" + text + "\n\n";
all_text += log_line;   // append with +=

For loop

rhai
for image_path in images_in_folder(folder) {
    let img  = load_image(image_path);
    let text = "";
    // ... pipeline steps
}

If / else

rhai
if image_path.contains("_processed") {
    continue;   // skip already-processed images
}

if text.is_empty() {
    save_to_folder(img, batch_timestamp);
} else {
    save_ocr_to_text(text, image_path);
    save_to_folder(img, batch_timestamp);
}

Operators

CategoryOperators
Arithmetic+ - * /
Comparison== != < > <= >=
Logical&& || !
Unary- (negate) ! (not)
Compound+=

Method call syntax

Method calls are desugared to function calls β€” a.method(b) is identical to method(a, b).

rhai
// These are equivalent:
if image_path.contains("_processed") { continue; }
if contains(image_path, "_processed") { continue; }

let lower = text.to_lower();
let lower = to_lower(text);

Comments

rhai
// This is a line comment β€” everything after // is ignored
let folder = "C:/scans/invoices";  // inline comment

Built-in Functions

Image processing

SignatureReturnsDescription
load_image(path)ImageLoad an image from an absolute path.
crop_area(img, x, y, w, h)ImageCrop to the rectangle (x, y, width, height). Values are clamped to image bounds.
apply_perspective(img, corners)Image4-point perspective correction. corners is an 8-element array [tl_x, tl_y, tr_x, tr_y, br_x, br_y, bl_x, bl_y].
apply_curve(img, top, side)ImageArc/curve de-warp. top and side are floats in roughly -1.0 .. 1.0.
apply_drawings(img, overlay_path)ImageAlpha-blend a saved drawing overlay PNG on top of the image. Pass empty string to skip.

Output

SignatureReturnsDescription
ocr_and_copy(img)StringRun OCR on the image. Copies extracted text to the Windows clipboard. Returns the text.
save_ocr_to_text(text, image_path)()Write text to output/{stem}.txt. Must be called after ocr_and_copy().
copy_to_clipboard(img)()Copy the processed image (not text) to the Windows clipboard.
save_to_folder(img, batch_timestamp)()Save the processed image as output/{stem}_{timestamp}_processed.png.

Iteration & utility

SignatureReturnsDescription
images_in_folder(folder)ArrayReturn sorted array of absolute image paths (.png .jpg .jpeg .bmp .tif .tiff .webp) in folder. Excludes automation_* files.
current_timestamp()StringReturn the current time as YYYYMMDD_HHMMSS. Used for batch_timestamp so each run gets a unique name.
wait_ms(ms)()Pause execution for ms milliseconds.
print(value)()Log a value to the application trace log.

String helpers

All string helpers can be called as method(str, ...) or as str.method(...).

SignatureReturnsDescription
contains(s, pattern)boolTrue if s contains pattern.
starts_with(s, prefix)boolTrue if s starts with prefix.
ends_with(s, suffix)boolTrue if s ends with suffix.
is_empty(s)boolTrue if s is an empty string or empty array.
len(s)intCharacter count (string) or element count (array).
to_lower(s)StringLowercase copy.
to_upper(s)StringUppercase copy.
trim(s)StringStrip leading/trailing whitespace.

Variables & Scope

The engine pre-seeds the script scope with two variables before execution:

VariableTypeDescription
batch_timestampStringTimestamp of when Play / Executar was pressed. Format: YYYYMMDD_HHMMSS. Embedded in all output filenames.
folderStringAbsolute path to the configured working folder.

Scripts typically override batch_timestamp with let batch_timestamp = current_timestamp(); so each run uses a fresh timestamp. The variable set by the engine is a useful fallback for scripts without this line.

Inside a for loop, image_path and img are the per-iteration variables. text is conventionally declared as let text = ""; and populated by ocr_and_copy.

Example Scripts

1. Crop + OCR + save image and text file

The template generated after a typical recording session.

rhai
// ─────────────────────────────────────────────────────────
//  Kiky Notes PRO β€” Automation Script
//  Actions : crop, ocr, save-text, save-image
// ─────────────────────────────────────────────────────────

let batch_timestamp = current_timestamp();
let folder = "C:/Users/you/Documents/invoices";

for image_path in images_in_folder(folder) {
    let img  = load_image(image_path);
    let text = "";
    img  = crop_area(img, 120, 80, 1400, 900);
    text = ocr_and_copy(img);
    save_ocr_to_text(text, image_path);
    save_to_folder(img, batch_timestamp);
}

2. Perspective correction + save

Scanned documents photographed at an angle.

rhai
let batch_timestamp = current_timestamp();
let folder = "C:/scans/books";

for image_path in images_in_folder(folder) {
    let img = load_image(image_path);
    img = apply_perspective(img, [45,30, 1390,25, 1410,950, 30,960]);
    save_to_folder(img, batch_timestamp);
}

3. Full pipeline β€” perspective + curve + OCR

rhai
let batch_timestamp = current_timestamp();
let folder = "C:/scans/curved_pages";

for image_path in images_in_folder(folder) {
    let img  = load_image(image_path);
    let text = "";
    img  = apply_perspective(img, [50,40, 1380,35, 1400,960, 40,970]);
    img  = apply_curve(img, 0.08, 0.05);
    text = ocr_and_copy(img);
    save_ocr_to_text(text, image_path);
    save_to_folder(img, batch_timestamp);
}

4. Run a single image (no loop)

Useful when pasting a path directly and running via the editor.

rhai
let batch_timestamp = current_timestamp();
let image_path = "C:/Desktop/receipt.png";

let img  = load_image(image_path);
let text = "";
img  = crop_area(img, 0, 0, 800, 1200);
text = ocr_and_copy(img);
save_ocr_to_text(text, image_path);
save_to_folder(img, batch_timestamp);

Power-User Techniques

Skip already-processed files

rhai
for image_path in images_in_folder(folder) {
    if image_path.contains("_processed") { continue; }

    let img = load_image(image_path);
    // ... pipeline
}

Collect all OCR results into one file

rhai
let batch_timestamp = current_timestamp();
let folder = "C:/invoices";
let all_text = "";

for image_path in images_in_folder(folder) {
    let img  = load_image(image_path);
    img = crop_area(img, 0, 100, 1600, 2000);
    let text = ocr_and_copy(img);
    all_text += image_path + "\n" + text + "\n\n";
    save_to_folder(img, batch_timestamp);
}

// Write the combined file using the folder path as a placeholder image_path
save_ocr_to_text(all_text, folder + "/combined_ocr.txt");

Keyword filter β€” only save if OCR finds a word

rhai
let batch_timestamp = current_timestamp();
let folder = "C:/mail";
let keywords = ["invoice", "amount due", "total"];

for image_path in images_in_folder(folder) {
    let img  = load_image(image_path);
    let text = ocr_and_copy(img);

    let matched = false;
    for kw in keywords {
        if text.to_lower().contains(kw) {
            matched = true;
        }
    }

    if matched {
        save_to_folder(img, batch_timestamp);
        save_ocr_to_text(text, image_path);
    }
}

Change working folder without re-recording

Just edit the folder variable at the top of the script and press F5.

rhai
// Change only this line to switch to a different batch:
let folder = "D:/new_batch/march_invoices";

for image_path in images_in_folder(folder) {
    let img = load_image(image_path);
    img = crop_area(img, 120, 80, 1400, 900);
    // ... same pipeline, different folder
    save_to_folder(img, batch_timestamp);
}

Conditional crop based on filename

rhai
for image_path in images_in_folder(folder) {
    let img = load_image(image_path);

    // Use a tighter crop for files named "receipt_*"
    if image_path.contains("receipt_") {
        img = crop_area(img, 50, 50, 900, 1200);
    } else {
        img = crop_area(img, 120, 80, 1400, 900);
    }

    save_to_folder(img, batch_timestamp);
}

Output Files

All output files are written to {working_folder}/output/.

FileName patternWritten by
Processed image{stem}_{timestamp}_processed.pngsave_to_folder()
OCR text file{stem}.txtsave_ocr_to_text()
Combined OCRany name via save_ocr_to_text()manual in script
Error logerrors.txtengine β€” on failure

Folder layout

working_folder/ β”œβ”€β”€ invoice1.jpg ← input images β”œβ”€β”€ invoice2.png β”œβ”€β”€ automation_20260322_153000.rhai ← generated scripts └── output/ β”œβ”€β”€ invoice1_20260322_153000_processed.png β”œβ”€β”€ invoice1.txt β”œβ”€β”€ invoice2_20260322_153000_processed.png β”œβ”€β”€ invoice2.txt └── errors.txt ← only when errors occur

Files whose stems start with automation_ are automatically excluded from images_in_folder() results β€” they are script files, not image inputs.

Automation Script Reference β€” Kiky Notes PRO | Kiky Apps