9 Writing an owobot plugin
Elara edited this page 2024-04-24 00:35:07 +00:00

Writing an owobot plugin

owobot can be extended using plugins written in JavaScript. A plugin is a JavaScript file with some information about the plugin and JS code to handle the functionality. The first thing you need to do when you're writing a plugin is specify some information about your plugin. You can do that using owobot.pluginInfo, like so:

owobot.pluginInfo = {
  name: "test",
  version: "0.1.0",
  desc: "This is a test plugin",
};

Note
Throughout this page, when I refer to a session, I'm talking about the discordgo.Session object. Refer to its documentation to see what you can do with it.

Lifecycle Hooks

  • owobot.init(prev) (callback): This function is called when your plugin is first loaded. You can use it to perform initialization tasks, such as creating database tables. The prev argument contains the pluginInfo for the previous version of your plugin. You can use that to determine whether you need to perform tasks to upgrade from a previous version, such as updating something in the database.

    Here's an example of using owobot.init to create a table:

    owobot.init = (prev) => {
      sql.exec(`
        CREATE TABLE IF NOT EXISTS data (
            x INT PRIMARY KEY,
            y INT NOT NULL,
            z INT NOT NULL
        );
      `);
    
      if (vercmp.older(prev.version, "0.0.9")) {
        sql.exec('ALTER TABLE data DROP COLUMN id')
      }
    };
    
  • owobot.onDisable(guildID) (callback): This function is called when your plugin is disabled for a specific guild (server). You can use it to clean up any guild-specific data, such as removing entries from the database or deleting webhooks created by your plugin.

Event Listeners

  • owobot.on(eventType, fn) (function): Registers a listener function for a specific Discord event type (e.g., "MessageCreate"). The fn argument will be called whenever the specified event occurs. It should always accept a session and the event that caused it to be called.

    Here's an example using an event listener to reply to every message with "UwU":

    owobot.on("MessageCreate", (sess, msg) => {
      if (msg.author.bot) return;
      sess.channelMessageSendReply(msg.channelID, "UwU", msg.reference())
    });
    

Commands

  • owobot.commands ([]command): An array of objects containing your plugin's commands. Each object defines a command with its properties and subcommands (if applicable).

    Command Object:

    • name (string): The unique name of the command.
    • desc (string): A short description of the command.
    • usage: (string): A description of the command arguments (e.g. <some_argument> [optional_argument])
    • subcommands ([]command): An optional array containing all the subcommands of the command.
    • permissions ([]discord.Permission): An optional array of all the permissions that are required to execute this command.
    • onExec(session, interaction, args) (callback): The function that gets executed when someone runs the command. It accepts a discordgo.Session object, a discordgo.InteractionCreate event, and an array of string arguments.

    Example:

    owobot.commands = [
      {
        name: 'hello',
        desc: 'Say hello to the bot',
        onExec: (sess, i, args) => owobot.respondEphemeral(sess, i.interaction, "Haii! :3"),
        subcommands: [
          {
            name: 'world',
            desc: 'Say hello to the world',
            permissions: [discord.Permissions.KickMembers],
            onExec: (sess, i, args) => owobot.respondEphemeral(sess, i.interaction, 'Hello, world!!'),
          },
        ],
      },
    ]; 
    

Responding to interactions

  • owobot.respond(session, interaction, content) (function): Responds to an interaction with a public message visible to everyone.

  • owobot.respondEphemeral(session, interaction, content) (function): Sends a temporary message that only the user who triggered the interaction can see.

Utilities

  • owobot.enabled(guildID) (function): Checks if the plugin is currently enabled for the specified guild. Returns true if enabled, false otherwise.

Cache API

  • cache.channel(s, guildID, channelID) (function): Retrieves information about a channel from the cache, or from the Discord API if it doesn't exist in the cache. Returns a discordgo.Channel object.
  • cache.member(s, guildID, userID) (function): Retrieves information about a guild member from the cache, or from the Discord API if it doesn't exist in the cache. Returns a discordgo.Member object.
  • cache.role(s, guildID, roleID) (function): Retrieves information about a role from the cache, or from the Discord API if it doesn't exist in the cache. Returns a discordgo.Role object.
  • cache.roles(s, guildID) (function): Retrieves all roles for a guild from the cache, or from the Discord API if they don't exist in the cache. Returns an array of discordgo.Role objects.

SQL Database API

Note
owobot uses an SQLite database, so all queries should use SQLite syntax

  • sql.exec(query, ...args) (function): Executes an SQL query that modifies the database but doesn't return any results (e.g., INSERT, UPDATE, DELETE).
  • sql.query(query, ...args) (function): Executes an SQL query that retrieves data from the database. Returns an array of objects representing the query results.
  • sql.queryOne(query, ...args) (function): Similar to sql.query but expects only one result and only returns a single object instead of an array.

Version Comparison API

  • vercmp.compare(v1, v2) (function): : Compares two version strings and returns an integer indicating their relative order. Negative value means v1 is older, positive means v2 is older, and 0 means they're equal.
  • vercmp.newer(v1, v2) (function):: Checks if version string v1 is newer than v2. Returns true if newer, false otherwise.
  • vercmp.older(v1, v2) (function):: Checks if version string v1 is older than v2. Returns true if older, false otherwise.
  • vercmp.equal(v1, v2) (function):: Checks if two version strings are equal. Returns true if equal, false otherwise.

Ticket API

  • tickets.open(session, guildID, user, executor?) (function): Opens a new ticket for a user. The optional executor is the user that triggered the ticket to be open. If unspecified, it defaults to the owobot user.
  • tickets.close(session, guildID, user, executor?) (function): Closes an existing ticket for the given user. The optional executor is the user that triggered the ticket to be closed. If unspecified, it defaults to the owobot user.

Eventlog API

  • eventlog.log(session, guildID, entry) (function): Writes an event to the event log channel.

    Entry object

    • title (string): The title of the log entry
    • description (string): The description of the log entry
    • imageURL (string): An optional image URL for the log entry
    • author (disccordgo.User): The user that triggered the log event

Fetch

  • fetch(url, options?): Makes an HTTP request to the given URL

    Options:

    • method (string): The HTTP method for the request. Defaults to "GET" if not specified. Valid options include "GET", "POST", "PUT", etc.
    • body (string): The request body for POST or PUT requests. Should be a string containing the data to send.
    • headers (object): An object containing additional headers to send with the request. Keys are header names, and values are header values (both must be strings).
    • handleCookies (boolean): If true, owobot will automatically handle cookies for this request. Defaults to true.

    Response:

    • status (string): The HTTP status message (e.g., "200 OK", "404 Not Found").
    • statusCode (number): The HTTP status code (e.g., 200, 404).
    • headers (object): An object containing the response headers. Keys are header names, values are header values.
    • text() (function): Returns the response body as a string.
    • json() (function): Parses the response as JSON and returns the resulting value.

    Here's an example of using fetch:

    let response = fetch("https://webhook.site/00000000-0000-0000-0000-000000000000", {
      method: 'POST',
      body: JSON.stringify({'hello': 'world!'}),
      headers: {
        Authorization: 'Bearer my-token',
      },
    });
    
    print(response.status) // This prints "200 OK"