Prism/developer documentation/Hooks

Hooks

Change how Prism behaves from a module without touching the framework.

The framework never checks for a specific module. When a module needs to change core behavior, it registers a hook on this.prism.hooks. Remove the module and its hooks go with it.

modules/example/main.js
async onStartup() {
    this.prism.hooks.register("restrict", this.restrict);
}

async onShutdown() {
    this.prism.hooks.unregister("restrict", this.restrict);
}

Register in onStartup() and unregister in onShutdown() with the same function, so turning the module off removes it.

Registry

MethodWhat it does
register(name, handle)Adds a handle under name.
unregister(name, handle)Removes it.
has(name)Whether any handle is registered.
get(name, ...args)Calls each handle in order and returns the first result that is not undefined.
value(name, ...args)The same as get, without waiting. Handles must return plain values.
run(name, ...args)Calls every handle and ignores the results.
restricted(action, context)Asks the restrict hooks about action. Returns the reason as a string, or "" when allowed.
assert(action, context)Throws the reason when action is restricted.

Hooks Prism Calls

HookCallArgumentsReturn
setupvalue()Setup needs, such as [] to skip the setup wizard.
ownervalue()The owner { discordId, name } in place of the stored one.
sessionget(request)A user for visitors with no session. Prism marks it guest: true.
permissionsget(user)Fields merged over the signed-in session: permissions, role, points.
restrictrestricted(action, context)A reason string to block the action, or undefined to allow it.
modeget({ session }){ badge, hint, link, server }. Shows a badge next to the brand. badge and hint are lang keys, link and server are { label, href } or null.

Restrictions

Each action below is passed to restricted() before it runs.

ActionCovers
action:<name>A dashboard action, such as action:saveSettings.
writeEvery dashboard write through the API proxy. Context: { session, discordId, module }.
page:<module>:<name>Hides a module page from the sidebar.
licenseThe online license check at boot.
loginThe login page.
logsThe Logs page and its API.
ownerOwner-only settings.
modules, tokens, export, settingsLocks those dashboard sections.
cssCustom CSS on the site and the dashboard.
accountAccount and theme pages.
updateThe auto update timer.
restartScheduled auto restarts.

The shell receives restricted, the subset of logs, owner, modules, tokens, export and settings that is blocked, so the dashboard can hide those controls.

Demo Module

Every product ships its demo as the demo module on the demo/module branch. Customer releases leave it out. The demo build adds it and sets DEMO=true.

The demo module:

  • Sets hidden: true in its manifest so it never shows on the Modules page.
  • Registers its hooks in onBoot() only when process.env.DEMO === "true", and unregisters them in onShutdown(). Its setup, owner and license hooks let a demo instance start without a license or the setup wizard.
  • Lists blocked actions in actions and blocked restrictions in denied. Anything not listed is allowed.
  • Returns its messages.locked phrase as the reason, and keeps its badge text in resources/lang/<code>/common.json.
modules/demo/src/handlers/policy.js
restrict(action) {
    if (this.denied.includes(action)) return this.prism.modules.lang.phrase("demo", "messages", "locked");
    if (action.startsWith("action:") && this.actions.includes(action.slice(7))) return this.prism.modules.lang.phrase("demo", "messages", "locked");
    return undefined;
}