Skip to main content

Ethone Namespace

The ethone namespace provides core utilities for your custom scripts.
Scripts are written in JavaScript and executed by the Go client using Goja.

ethone.on_command()

Create custom commands with automatic argument parsing.

Syntax

ethone.on_command(name, description, usage, callback)

Parameters

ParameterTypeDescription
namestringCommand name without prefix
descriptionstringWhat the command does
usagestringUsage string shown in .custom (e.g., “hello [name]“)
callbackfunctionFunction called when command is used
The callback receives a ctx object with:
  • ctx.command - Command name
  • ctx.args - Array of arguments
  • ctx.message - Message object
  • ctx.guild - Guild object
  • ctx.channel - Channel object
  • ctx.author - Author object
Access IDs through context objects:
  • Use ctx.guild.id for guild ID
  • Use ctx.channel.id for channel ID
  • Use ctx.author.id for author ID

Example

ethone.on_command(
    "hello",          // name
    "Say hello",      // description
    "hello",          // usage
    function(ctx) {   // callback
        var channelId = ctx.channel.id;
        var message = "Hello, " + ctx.author.username + "!";
        discord.send_message(channelId, message);
    }
);

ethone.on_command(
    "say",                // name
    "Repeat message",     // description
    "say <message>",      // usage
    function(ctx) {       // callback
        if (ctx.args.length === 0) {
            discord.send_message(ctx.channel.id, "Usage: .say <message>");
            return;
        }
        var channelId = ctx.channel.id;
        var message = ctx.args.join(" ");
        discord.send_message(channelId, message);
    }
);
See Commands Documentation for more examples.

ethone.log()

Log a message to the console for debugging.

Syntax

ethone.log(message)

Parameters

ParameterTypeDescription
messagestringThe message to log to the console

Returns

void

Example

ethone.log("Script started!");

discord.on_message = function(ctx) {
    ethone.log("Received message from " + ctx.author.username + ": " + ctx.content);
};

ethone.sleep()

Pause execution for a specified number of milliseconds. Only use inside event handlers, never at top level.

Syntax

ethone.sleep(ms)

Parameters

ParameterTypeDescription
msnumberMilliseconds to sleep (e.g., 1000 = 1 second)

Returns

void

Example

discord.on_message = function(ctx) {
    if (ctx.content === ".delay") {
        ethone.sleep(2000); // Wait 2 seconds
        discord.send_message(ctx.channel.id, "Delayed response!");
    }
};

Common Mistakes

// Wrong - Will cause script to timeout
ethone.sleep(5000);
ethone.log("This will never run");

// Correct - Inside event handler
discord.on_message = function(ctx) {
    ethone.sleep(5000); // Ok here
};

ethone.user

Access information about the current user (selfbot user).

Properties

PropertyTypeDescription
idstringYour user ID
usernamestringYour username
discriminatorstringYour discriminator
tagstringFull username with discriminator
avatar_urlstringURL to your avatar image
banner_urlstringURL to your banner image
botbooleanWhether you are a bot account
global_namestringYour display name
accent_colornumberYour accent color as integer
tokenstringYour Discord token

Example

discord.on_message = function(ctx) {
    if (ctx.author.id === ethone.user.id) {
        ethone.log("I sent this message");
        return;
    }
    
    ethone.log(ctx.author.username + " said: " + ctx.content);
};

discord.on_message = function(ctx) {
    if (ctx.author.id === ethone.user.id) return;
    
    var count = ethone.get_value("message_count") || 0;
    count++;
    ethone.set_value("message_count", count);
    
    if (ctx.content === ".stats") {
        discord.send_message(
            ctx.channel.id,
            "Tracked " + count + " messages from other users"
        );
    }
};

discord.on_message = function(ctx) {
    if (ctx.author.id !== ethone.user.id) return;
    
    ethone.sleep(5000);
    discord.delete_message(ctx.channel.id, ctx.message.id);
    ethone.log("Deleted my message after 5 seconds");
};

ethone.log("Running as: " + ethone.user.username + " (" + ethone.user.id + ")");

ethone.stop()

Stop the Ethone client.

Syntax

ethone.stop()

Returns

void

Example

ethone.on_command("shutdown", "Stop the client", "shutdown", function(ctx) {
    if (ctx.author.id !== "YOUR_USER_ID") return;
    discord.send_message(ctx.channel.id, "Shutting down...");
    ethone.stop();
});

ethone.restart()

Restart the Ethone client.

Syntax

ethone.restart()

Returns

void

Example

ethone.on_command("restart", "Restart the client", "restart", function(ctx) {
    if (ctx.author.id !== "YOUR_USER_ID") return;
    discord.send_message(ctx.channel.id, "Restarting...");
    ethone.restart();
});

ethone.reload_scripts()

Reload all scripts without restarting the client.

Syntax

ethone.reload_scripts()

Returns

void

Example

ethone.on_command("reload", "Reload all scripts", "reload", function(ctx) {
    discord.send_message(ctx.channel.id, "Reloading scripts...");
    ethone.reload_scripts();
});

ethone.toggle_console()

Toggle console window visibility (Windows only, no-op on Unix/Linux).

Syntax

ethone.toggle_console()

Returns

void

Example

ethone.on_command("console", "Toggle console", "console", function(ctx) {
    ethone.toggle_console();
    discord.send_message(ctx.channel.id, "Console toggled!");
});

ethone.send_event()

Send a notification event to your Ethone inbox.
This is not a Discord event. Use ethone.send_event() to send notifications to your Ethone inbox.

Syntax

ethone.send_event(title, content, type, link, context)

Parameters

ParameterTypeDescription
titlestringEvent title
contentstringEvent content/description
typestringEvent type: "success", "error", "warning", or "info"
linkstring[] | undefinedOptional array of clickable link URLs (e.g., Discord message links)
contextobject | undefinedOptional context object with text (string) and icon (URL string) properties for visual context

Returns

boolean - true if successful, false otherwise

Example

ethone.send_event("Script Started", "Automation script is running", "success");

ethone.on_command("test", "Test command", "test", function(ctx) {
    try {
        var result = doSomething();
        ethone.send_event("Test Complete", "Test executed successfully", "success");
    } catch (error) {
        ethone.send_event("Test Failed", "Error: " + error, "error");
    }
});

discord.on_message = function(ctx) {
    if (ctx.content.includes("important keyword")) {
        var messageUrl = "https://discord.com/channels/" + ctx.guild.id + "/" + ctx.channel.id + "/" + ctx.message.id;
        ethone.send_event(
            "Keyword Detected",
            "User " + ctx.author.username + " mentioned keyword",
            "info",
            [messageUrl]
        );
    }
};

discord.on_message = function(ctx) {
    if (ctx.content.toLowerCase() === ".alert") {
        var messageUrl = "https://discord.com/channels/" + ctx.guild.id + "/" + ctx.channel.id + "/" + ctx.message.id;
        ethone.send_event(
            "Alert Command",
            ctx.author.username + " used alert command",
            "warning",
            [messageUrl],
            {
                text: ctx.guild.name,
                icon: ctx.guild.icon_url
            }
        );
    }
};

ethone.on_command("notify", "Send notification", "notify <message>", function(ctx) {
    if (ctx.args.length === 0) {
        discord.send_message(ctx.channel.id, "Usage: .notify <message>");
        return;
    }
    
    var message = ctx.args.join(" ");
    var messageUrl = "https://discord.com/channels/" + ctx.guild.id + "/" + ctx.channel.id + "/" + ctx.message.id;
    
    ethone.send_event(
        "Custom Notification",
        message,
        "info",
        [messageUrl],
        {
            text: ctx.guild.name + " - #" + ctx.channel.name,
            icon: ctx.author.avatar_url
        }
    );
    
    discord.send_message(ctx.channel.id, "Notification sent to inbox!");
});

Event Types

TypeDescriptionUse Case
successPositive outcomesTask completed, item found, operation succeeded
errorErrors and failuresAPI errors, exceptions, failed operations
warningWarnings and cautionsHigh usage, rate limits, potential issues
infoInformationalGeneral notifications, status updates, reminders

ethone.set_value()

Store a value in cloud storage that persists across script reloads and client restarts.

Syntax

ethone.set_value(key, value)

Parameters

ParameterTypeDescription
keystringStorage key (unique identifier)
valueanyValue to store (any JSON-serializable type)

Returns

boolean - true if successful, false otherwise

Example

// Store API key
ethone.on_command("setkey", "Set API key", "setkey <key>", function(ctx) {
    if (ctx.args.length === 0) {
        discord.send_message(ctx.channel.id, "Usage: .setkey <key>");
        return;
    }
    ethone.set_value("api_key", ctx.args[0]);
    discord.send_message(ctx.channel.id, "API key saved!");
});

// Store complex objects
ethone.set_value("preferences", {
    theme: "dark",
    notifications: true,
    auto_mod: false
});

ethone.get_value()

Retrieve a value from cloud storage.

Syntax

ethone.get_value(key)

Parameters

ParameterTypeDescription
keystringStorage key to retrieve

Returns

The stored value or null if not found

Example

// Get API key
ethone.on_command("getkey", "Get API key", "getkey", function(ctx) {
    var apiKey = ethone.get_value("api_key");
    if (apiKey) {
        discord.send_message(ctx.channel.id, "API Key: " + apiKey);
    } else {
        discord.send_message(ctx.channel.id, "No API key set");
    }
});

// Get with default value
var prefs = ethone.get_value("preferences");
if (!prefs) {
    prefs = {
        theme: "light",
        notifications: false
    };
}

ethone.get_values()

Get all stored values from cloud storage.

Syntax

ethone.get_values()

Returns

object - Object containing all key-value pairs

Example

ethone.on_command("listvalues", "List all stored values", "listvalues", function(ctx) {
    var values = ethone.get_values();
    var keys = Object.keys(values);
    
    if (keys.length === 0) {
        discord.send_message(ctx.channel.id, "No values stored");
        return;
    }
    
    var msg = "Stored values:\n";
    for (var i = 0; i < keys.length; i++) {
        msg += keys[i] + ": " + JSON.stringify(values[keys[i]]) + "\n";
    }
    discord.send_message(ctx.channel.id, msg);
});
`

---

## os.read_file()

Read the contents of a file.

### Syntax

```javascript
os.read_file(path)

Parameters

ParameterTypeDescription
pathstringPath to the file to read

Returns

string - File contents, or null if failed

Example

ethone.on_command("readfile", "Read file", "readfile <path>", function(ctx) {
    if (ctx.args.length < 1) {
        discord.send_message(ctx.channel.id, "Usage: .readfile <path>");
        return;
    }
    
    var content = os.read_file(ctx.args[0]);
    if (content) {
        discord.send_message(ctx.channel.id, "File content:\n" + content.substring(0, 1000));
    } else {
        discord.send_message(ctx.channel.id, "Failed to read file");
    }
});

os.write_file()

Write content to a file (overwrites existing file).

Syntax

os.write_file(path, content)

Parameters

ParameterTypeDescription
pathstringPath to the file to write
contentstringContent to write to the file

Returns

boolean - true if successful

Example

ethone.on_command("savelog", "Save log", "savelog <message>", function(ctx) {
    if (ctx.args.length < 1) {
        discord.send_message(ctx.channel.id, "Usage: .savelog <message>");
        return;
    }
    
    var message = ctx.args.join(" ");
    var timestamp = new Date().toISOString();
    var log = timestamp + " - " + ctx.author.tag + ": " + message + "\n";
    
    if (os.write_file("bot_log.txt", log)) {
        discord.send_message(ctx.channel.id, "Log saved!");
    } else {
        discord.send_message(ctx.channel.id, "Failed to save log");
    }
});

os.append_file()

Append content to a file (creates file if it doesn’t exist).

Syntax

os.append_file(path, content)

Parameters

ParameterTypeDescription
pathstringPath to the file
contentstringContent to append

Returns

boolean - true if successful

Example

discord.on_message = function(ctx) {
    if (ctx.author.bot) return;
    
    var log = new Date().toISOString() + " - " + ctx.author.tag + ": " + ctx.content + "\n";
    os.append_file("chat_log.txt", log);
};

os.delete_file()

Delete a file.

Syntax

os.delete_file(path)

Parameters

ParameterTypeDescription
pathstringPath to the file to delete

Returns

boolean - true if successful

Example

ethone.on_command("deletefile", "Delete file", "deletefile <path>", function(ctx) {
    if (ctx.args.length < 1) {
        discord.send_message(ctx.channel.id, "Usage: .deletefile <path>");
        return;
    }
    
    if (os.delete_file(ctx.args[0])) {
        discord.send_message(ctx.channel.id, "File deleted!");
    } else {
        discord.send_message(ctx.channel.id, "Failed to delete file");
    }
});

os.exists()

Check if a file or directory exists.

Syntax

os.exists(path)

Parameters

ParameterTypeDescription
pathstringPath to check

Returns

boolean - true if exists

Example

ethone.on_command("checkfile", "Check if file exists", "checkfile <path>", function(ctx) {
    if (ctx.args.length < 1) {
        discord.send_message(ctx.channel.id, "Usage: .checkfile <path>");
        return;
    }
    
    var exists = os.exists(ctx.args[0]);
    discord.send_message(ctx.channel.id, "File exists: " + exists);
});

os.list_dir()

List contents of a directory.

Syntax

os.list_dir(path)

Parameters

ParameterTypeDescription
pathstringDirectory path

Returns

Array of file/directory objects with properties:
  • name (string) - File/directory name
  • is_dir (boolean) - Whether it’s a directory
  • size (number) - File size in bytes
  • mod_time (number) - Last modified time (Unix timestamp)

Example

ethone.on_command("listdir", "List directory", "listdir [path]", function(ctx) {
    var path = ctx.args.length > 0 ? ctx.args[0] : ".";
    var files = os.list_dir(path);
    
    if (files.length === 0) {
        discord.send_message(ctx.channel.id, "Directory is empty or doesn't exist");
        return;
    }
    
    var msg = "Files in " + path + ":\n";
    for (var i = 0; i < Math.min(files.length, 10); i++) {
        var file = files[i];
        var type = file.is_dir ? "[Dir]" : "[File]";
        msg += type + " " + file.name + " (" + file.size + " bytes)\n";
    }
    
    discord.send_message(ctx.channel.id, msg);
});

os.create_dir()

Create a directory (including parent directories if needed).

Syntax

os.create_dir(path)

Parameters

ParameterTypeDescription
pathstringDirectory path to create

Returns

boolean - true if successful

Example

ethone.on_command("mkdir", "Create directory", "mkdir <path>", function(ctx) {
    if (ctx.args.length < 1) {
        discord.send_message(ctx.channel.id, "Usage: .mkdir <path>");
        return;
    }
    
    if (os.create_dir(ctx.args[0])) {
        discord.send_message(ctx.channel.id, "Directory created!");
    } else {
        discord.send_message(ctx.channel.id, "Failed to create directory");
    }
});

os.remove_dir()

Remove a directory and all its contents recursively.

Syntax

os.remove_dir(path)

Parameters

ParameterTypeDescription
pathstringDirectory path to remove

Returns

boolean - true if successful

Warning

This operation is irreversible and removes all subdirectories and files!

os.get_cwd()

Get the current working directory.

Syntax

os.get_cwd()

Returns

string - Current working directory path

Example

ethone.on_command("cwd", "Show current directory", "cwd", function(ctx) {
    var cwd = os.get_cwd();
    discord.send_message(ctx.channel.id, "Current directory: " + cwd);
});

os.join_path()

Join path components into a single path.

Syntax

os.join_path(...paths)

Parameters

ParameterTypeDescription
...pathsstringPath components to join

Returns

string - Joined path

Example

var dataDir = os.join_path(os.get_cwd(), "data");
var logFile = os.join_path(dataDir, "logs", "app.log");

ethone.log("Log file path: " + logFile);

os.basename()

Get the filename from a path.

Syntax

os.basename(path)

Parameters

ParameterTypeDescription
pathstringFile path

Returns

string - Filename (last element of path)

Example

var path = "/home/user/documents/file.txt";
var filename = os.basename(path); // "file.txt"

os.dirname()

Get the directory from a path.

Syntax

os.dirname(path)

Parameters

ParameterTypeDescription
pathstringFile path

Returns

string - Directory path

Example

var path = "/home/user/documents/file.txt";
var dir = os.dirname(path); // "/home/user/documents"

os.file_info()

Get detailed information about a file or directory.

Syntax

os.file_info(path)

Parameters

ParameterTypeDescription
pathstringFile/directory path

Returns

Object with properties:
  • name (string) - Name
  • size (number) - Size in bytes
  • is_dir (boolean) - Whether it’s a directory
  • mod_time (number) - Last modified time (Unix timestamp)
  • mode (string) - File permissions (e.g., “-rw-r—r—”)
Returns null if file doesn’t exist.

Example

ethone.on_command("fileinfo", "Get file info", "fileinfo <path>", function(ctx) {
    if (ctx.args.length < 1) {
        discord.send_message(ctx.channel.id, "Usage: .fileinfo <path>");
        return;
    }
    
    var info = os.file_info(ctx.args[0]);
    if (info) {
        var msg = "File: " + info.name + "\n";
        msg += "Size: " + info.size + " bytes\n";
        msg += "Type: " + (info.is_dir ? "Directory" : "File") + "\n";
        msg += "Modified: " + new Date(info.mod_time * 1000).toISOString() + "\n";
        msg += "Permissions: " + info.mode;
        discord.send_message(ctx.channel.id, msg);
    } else {
        discord.send_message(ctx.channel.id, "File not found");
    }
});

os.abs_path()

Get the absolute path from a relative path.

Syntax

os.abs_path(path)

Parameters

ParameterTypeDescription
pathstringRelative or absolute path

Returns

string - Absolute path

Example

var relPath = "./data/file.txt";
var absPath = os.abs_path(relPath);
ethone.log("Absolute path: " + absPath);

os.rename()

Rename or move a file/directory.

Syntax

os.rename(oldPath, newPath)

Parameters

ParameterTypeDescription
oldPathstringCurrent path
newPathstringNew path

Returns

boolean - true if successful

Example

ethone.on_command("rename", "Rename file", "rename <old> <new>", function(ctx) {
    if (ctx.args.length < 2) {
        discord.send_message(ctx.channel.id, "Usage: .rename <old> <new>");
        return;
    }
    
    if (os.rename(ctx.args[0], ctx.args[1])) {
        discord.send_message(ctx.channel.id, "File renamed!");
    } else {
        discord.send_message(ctx.channel.id, "Failed to rename file");
    }
});

Complete Example: Data Logger

// Initialize data directory
var dataDir = os.join_path(os.get_cwd(), "bot_data");
if (!os.exists(dataDir)) {
    os.create_dir(dataDir);
    ethone.log("Created data directory: " + dataDir);
}

// Log messages to file
discord.on_message = function(ctx) {
    if (ctx.author.bot) return;
    
    var logFile = os.join_path(dataDir, ctx.guild.id + ".log");
    var entry = new Date().toISOString() + " | " + 
                ctx.author.tag + " | " + 
                ctx.channel.name + " | " + 
                ctx.content + "\n";
    
    os.append_file(logFile, entry);
};

// View logs command
ethone.on_command("viewlogs", "View server logs", "viewlogs", function(ctx) {
    var logFile = os.join_path(dataDir, ctx.guild.id + ".log");
    
    if (!os.exists(logFile)) {
        discord.send_message(ctx.channel.id, "No logs found for this server");
        return;
    }
    
    var content = os.read_file(logFile);
    var lines = content.split("\n");
    var recent = lines.slice(-10).join("\n");
    
    discord.send_message(ctx.channel.id, "Recent logs:\n```\n" + recent + "\n```");
});

// Clear logs command
ethone.on_command("clearlogs", "Clear server logs", "clearlogs", function(ctx) {
    var logFile = os.join_path(dataDir, ctx.guild.id + ".log");
    
    if (os.delete_file(logFile)) {
        discord.send_message(ctx.channel.id, "Logs cleared!");
    } else {
        discord.send_message(ctx.channel.id, "Failed to clear logs");
    }
});