API Reference
The whole plugin SDK surface in one page.
Plugin SDK version 2. Everything here is experimental and can change between releases.
Module Exports
@sharkord/plugin-sdk (server):
| Export | What it is |
|---|---|
PluginContext, UnloadPluginContext, UpgradePluginContext | The context types passed to each lifecycle function |
PluginModule, TUpgradeInfo | The shape of a plugin's server entry |
TPluginContract | The contract both halves share |
Permission, ChannelPermission, ChannelType | Enums used by requires, ctx.permissions and ctx.channels |
TConsumeOptions, TVoiceConsumerHandle | Voice consumer types |
PluginSlot, TPluginSlotProps | The component slots enum, and what each one passes |
FileSaveType, MessageSaveType | Payload discriminators for the hooks |
PLUGIN_SDK_VERSION | The SDK version this build targets |
ServerEvent, EventPayloads | Event names and payloads |
TCommandArg, TInvokerContext | Command argument and invoker types |
TPluginSettingDefinition, PluginSettings | Settings types |
TCreateStreamOptions, TExternalStreamHandle | Voice stream types |
| mediasoup types | Router, Producer, PlainTransport, RtpParameters, and others, re-exported |
@sharkord/plugin-sdk/client (browser):
| Export | What it is |
|---|---|
createCallAction | Typed caller for your own actions |
useCanUseAction, useCanUseCommand | Whether this user may call one, for disabling UI |
useStoreSelector | Reads a slice of Sharkord's state |
usePush | Receives what ctx.push sent |
useUserData | Per-user storage for the signed-in user |
actions | Sharkord's own client actions |
TPluginComponentsMapBySlotId, TPluginTabs, TPluginStoreState | The types your client entry exports and reads |
Plugin Lifecycle
export const onLoad = async (ctx: PluginContext) => {};
export const onUnload = async (ctx: UnloadPluginContext) => {};
export const onUpgrade = async (ctx: UpgradePluginContext, info: TUpgradeInfo) => {};onLoad is required. onUnload is optional today and warns when missing, and will be required in a future SDK version. onUpgrade runs before onLoad, only when the installed version differs from the last one that ran.
The unload context is a subset: path, dataPath, logger, voice, messages, ui, and the deprecated log aliases. Registration namespaces are absent, because unregistering is automatic. The upgrade context is smaller still: pluginId, path, dataPath and logger.
PluginContext
| Member | Notes |
|---|---|
pluginId | Your plugin's id |
path | The plugin folder. Rewritten on every update |
dataPath | Durable storage. Survives updates, removed with the plugin |
logger.log / debug / error | Writes to the plugin log shown in the interface |
log / debug / error | Deprecated aliases of the above |
events.on / off | on returns an unsubscribe. Events |
commands.register(command) | Commands |
actions.register(action) | Actions |
settings.register(definitions) | Async, returns { get, set }. Settings |
messages.send / edit / delete / get / list / pin / unpin / react / unreact | Async. Messages. send and edit take previews |
users.list / get / ban / unban / kick | Async. Data |
roles.list / get / assign / remove | Async. Data |
permissions.userCan / userCanInChannel | Async. Data |
channels.list / get / create / update / delete | Async. Data |
categories.list / get / create / update / delete | Async. Data |
userData.get / set / delete | Async, per user. Data |
push.toUser / toUsers / toAll | Server to client. Client SDK |
hooks.onBeforeMessageSave / onBeforeFileSave / onBeforeChannelCreate / onBeforeVoiceJoin / onBeforeLogin | Hooks |
http.register / get / post / patch / delete / options | HTTP routes |
voice.getRouter / getListenInfo / getState / getProducers / createStream / consume | Voice |
ui.enable(requirements?) / disable() | Whether your components are rendered |
Limits and Defaults
| Thing | Value |
|---|---|
onLoad, onUnload, onUpgrade timeout | 30 seconds |
| Command and action execution timeout | 30 seconds |
| Hook execution timeout | 30 seconds |
| Event handler timeout | 10 seconds |
| Command, action and user-data rate limit | 60 per minute per user (configurable) |
| HTTP route rate limit | 300 per minute per IP, shared by all plugin routes (configurable) |
| Commands per plugin | 100 |
| Actions per plugin | 100 |
| HTTP routes per plugin | 100 |
| Push payload | 64 KB of JSON |
| Per-user data | 64 KB of JSON |
| Hook reject reason | 200 characters |
| Capability types an admin can restrict | commands, actions, components, HTTP routes |
Messages returned by messages.list | 100 |
| Voice consumers per plugin | unlimited; closed on unload |
| Permission to run commands and actions | USE_PLUGINS |
| Permission to install and toggle plugins | MANAGE_PLUGINS |
| Permission to change capability access | MANAGE_PLUGIN_PERMISSIONS |
Manifest
{
"id": "my-plugin",
"name": "My Plugin",
"author": "Me",
"description": "Does something useful.",
"homepage": "https://example.com",
"logo": "https://example.com/logo.png",
"sdkVersion": 2,
"version": "0.0.1"
}id, name, author, description, sdkVersion, and version are required. id must be lowercase letters, numbers, and dashes, at most 64 characters, and must match the folder name. version must be semver. homepage and logo must be HTTP(S) URLs when present.
Source of Truth
When an example here and the code disagree, the code wins: