Skip to content
This repository has been archived by the owner on Jun 27, 2021. It is now read-only.

Custom plugins

Joe edited this page Feb 4, 2020 · 2 revisions

How to make plugins

Let's start by showing the basic format:

const Plugin = require('../plugin');

module.exports = new Plugin({
    name: 'A Plugin', /* Human-readable plugin name. */
    author: 'Joe', /* [Optional] Put your name here to give yourself credit for making it :) */
    description: 'Does absolutely nothing, lol', /* Description of what this plugin does. */
    preload: false, /* [Optional] If true, load this before Discord has finished starting up */
    color: '#666', /* [Optional] The color that this plugin shows in logs and in the plugin settings tab. Any valid CSS color will work here. */
    disabledByDefault: false, /* [Optional] If true, disable the plugin until the user enables it in settings */

    load: function() {
        /* What your plugin does when Discord is loaded, or when the plugin is reloaded. */
    },
    unload: function() {
        /* What your plugin does when it is disabled or being reloaded. */
    }
});

Helper functions reference

The Plugin class adds the following functions to your plugin:

  • log, info, warn, error: same as console.log, console.info, etc., except it adds the name and color of your plugin to the log statement. Example: this.log('Successfully loaded!')

  • sleep(ms): Returns a Promise that resolves after ms milliseconds. Usage: await this.sleep(5000); [Make sure you make load() an async function first!]

Storing settings

The Plugin class and settings plugin offer the following helpers for plugin settings:

  • settings: Stores your plugin's settings in the config file. It is done using getters and setters, so loading and saving your plugin's settings are as easy as reading and writing this.settings. However, you most likely won't need to use it if you use the settings UI (see the next section.)

  • defaultSettings: The default settings your plugin should use when first starting up or when its data is cleared.

Settings UI (BRED)

generateSettings: a function that is called when EnhancedDiscord settings are opened. This should return one of the following types:

  • DiscordUIElement[] An array of elements for the ED's Discord UI generator to create.
  • ^ Proper docs for this coming soon™. For now, see the example plugin for a showcase of all the available element types.
  • ReactNode Any valid react element. Make sure you call call React.createElement on your component, if you return a function or a class this will not work.
  • HTMLElement The value returned by any call to document.createElement(...), you can modify this class before returning it, e.g. setting inner children by HTMLElement.appendChild
  • DOMString [DEPRECATED] A HTML string paired with a plugin.settingsListeners property. For legacy support only, please don't make new plugins using this.

Global helper functions and variables

Most of the functions you should need are in window.EDApi, which is a clone of BDApi from BetterDiscord with some modifications. The following functions have been modified to be usable in the usual way as well as like this:

  • findModule(name, silent): Looks for a module with a function called name. Using this can be trial-and-error sometimes. Example: findModule('sendMessage').sendMessage('415248292767727616', {content: 'random shit'}) would send the message 'random shit' in #shitposting in the EnhancedDiscord server. The silent argument tells whether to send a warning in console if the module is not found.

  • findModules(name): Same as above, but returns an Array of modules.

  • monkeyPatch(module, functionName, newFunction): Inside a webpack module, it replaces a function (named functionName) with a new one (newFunction).

    • It's a good idea to make a parameter for your new function if you need to use any of the following properties. For these examples I used b (i.e. newFunction = b => { /* do stuff */ })

    • To access the original arguments, use b.methodArguments. For example, in sendMessage, b.methodArguments[0] is the channel ID.

    • To access the "this" object used internally, use b.thisObject.

    • To access the original function, use b.originalMethod.

    • To run the original function, use b.callOriginalMethod(b.methodArguments).

    • To undo your patch, use the unpatch() function; for example, findModule('sendMessage').sendMessage.unpatch();. The __monkeyPatched property, located in the same place, can be used to determine if a function is already patched.

These functions have also been added to the window object for convenience.

ED.webSocket - The websocket for receiving events and shit. Shouldn't be needed by the vast majority of plugins.

ED.localStorage - Access to localStorage, might be useful for storing certain kinds of data. Shouldn't be needed by most plugins.