Skip to main content

Plugin API Reference

TojuClientPluginApi is the object passed to a plugin activation context. The runtime freezes the API object before passing it to plugin code.

This page is the compact map. Use the focused API pages for concrete copy-paste examples with literal input data.

Focused API Pages

Activation Types

interface TojuPluginDisposable {
dispose: () => void;
}

interface TojuPluginActivationContext {
api: TojuClientPluginApi;
manifest: TojuPluginManifest;
pluginId: string;
subscriptions: TojuPluginDisposable[];
}

interface TojuClientPluginModule {
activate?: (context: TojuPluginActivationContext) => Promise<void> | void;
deactivate?: (context: TojuPluginActivationContext) => Promise<void> | void;
onPluginDataChanged?: (context: TojuPluginActivationContext, event: unknown) => Promise<void> | void;
onServerRequirementsChanged?: (context: TojuPluginActivationContext, snapshot: PluginRequirementsSnapshot) => Promise<void> | void;
ready?: (context: TojuPluginActivationContext) => Promise<void> | void;
}

Profiles

interface PluginApiProfileUpdate {
description?: string;
displayName: string;
}

interface PluginApiAvatarUpdate {
avatarHash: string;
avatarMime: string;
avatarUrl: string;
}
MethodCapabilityDescription
profile.getCurrent()profile.readReturns the current User or null.
profile.update(profile)profile.writeUpdates display name and optional description.
profile.updateAvatar(avatar)profile.writeUpdates avatar URL, MIME type, and hash metadata.

Users and Roles

MethodCapabilityDescription
users.getCurrent()users.readReturns current User or null.
users.list()users.readReturns known users.
users.readMembers()users.readReturns active room members.
users.setRole(userId, role)roles.manageUpdates a user's role.
users.kick(userId)users.manageKicks a user.
users.ban(userId, reason?)users.manageBans a user with optional reason.
roles.list()roles.readReturns room roles.
roles.setAssignments(assignments)roles.manageReplaces role assignments.

Server

interface PluginApiServerSettingsUpdate {
description?: string;
isPrivate?: boolean;
maxUsers?: number;
name?: string;
password?: string;
topic?: string;
}

interface PluginApiPluginUserRequest {
avatarUrl?: string;
displayName: string;
id?: string;
}
MethodCapabilityDescription
server.getCurrent()server.readReturns the current Room or null.
server.registerPluginUser(request)users.manageAdds a plugin-owned user and returns its id.
server.updatePermissions(permissions)server.manageUpdates partial room permissions.
server.updateSettings(settings)server.manageUpdates room settings.

Channels

interface PluginApiChannelRequest {
id?: string;
name: string;
position?: number;
}
MethodCapabilityDescription
channels.list()channels.readReturns current room channels.
channels.select(channelId)channels.readSelects a channel.
channels.addAudioChannel(request)channels.manageAdds a voice channel.
channels.addVideoChannel(request)channels.manageRegisters a video channel section.
channels.rename(channelId, name)channels.manageRenames a channel.
channels.remove(channelId)channels.manageRemoves a channel.

Messages

interface PluginApiMessageAsPluginUserRequest {
channelId?: string;
content: string;
pluginUserId: string;
}
MethodCapabilityDescription
messages.readCurrent()messages.readReturns current visible messages.
messages.send(content, channelId?)messages.sendSends a message and returns the created Message.
messages.sendAsPluginUser(request)messages.sendEmits a message from a registered plugin user.
messages.setTyping(isTyping, channelId?)messages.sendBroadcasts current typing state for a channel.
messages.subscribeTyping(handler)messages.readSubscribes to peer typing state.
messages.edit(messageId, content)messages.editOwnEdits a plugin message.
messages.delete(messageId)messages.deleteOwnDeletes a plugin message.
messages.moderateDelete(messageId)messages.moderatePerforms a moderation delete.
messages.sync(messages)messages.syncSyncs an array of messages into state.

Events

interface PluginApiEventSubscription {
eventName: string;
handler: (event: PluginEventEnvelope) => void;
}

interface PluginEventEnvelope<TPayload = unknown> {
emittedAt?: number;
eventId?: string;
eventName: string;
payload: TPayload;
pluginId: string;
serverId: string;
sourcePluginUserId?: string;
sourceUserId?: string;
type: 'plugin_event';
}
MethodCapabilityDescription
events.publishServer(eventName, payload)events.server.publishSends a declared plugin event through the signaling server.
events.subscribeServer(subscription)events.server.subscribeSubscribes to a declared server plugin event.
events.publishP2p(eventName, payload)events.p2p.publishSends a declared plugin event over peer paths.
events.subscribeP2p(subscription)events.p2p.subscribeRegisters a P2P event subscription.

Message Bus

interface PluginApiMessageBusEnvelope {
channelId?: string;
eventId: string;
messages?: Message[];
payload?: unknown;
pluginId: string;
roomId: string;
sentAt: number;
sourcePeerId?: string;
sourceUserId?: string;
topic: string;
}

interface PluginApiMessageBusLatestRequest {
channelId?: string;
includeDeleted?: boolean;
limit?: number;
sinceTimestamp?: number;
targetPeerId?: string;
topic?: string;
}

interface PluginApiMessageBusPublishRequest extends PluginApiMessageBusLatestRequest {
includeLatestMessages?: boolean;
includeSelf?: boolean;
payload?: unknown;
topic: string;
}

interface PluginApiMessageBusSubscription {
channelId?: string;
handler: (event: PluginApiMessageBusEnvelope) => void;
latestMessageLimit?: number;
replayLatest?: boolean;
topic?: string;
}
MethodCapabilityDescription
messageBus.publish(request)events.p2p.publish, optionally messages.readPublishes a plugin-bus event, optionally including latest messages.
messageBus.sendLatestMessages(request?)events.p2p.publish and messages.readSends a latest-message snapshot.
messageBus.subscribe(subscription)events.p2p.subscribe, optionally messages.readSubscribes to plugin-bus events, optionally replaying latest messages.

P2P and Media

interface PluginApiAudioClipRequest {
volume?: number;
url: string;
}

interface PluginApiCustomStreamRequest {
label?: string;
stream: MediaStream;
}
MethodCapabilityDescription
p2p.connectedPeers()p2p.dataReturns connected peer ids.
p2p.broadcastData(eventName, payload)p2p.dataBroadcasts plugin data.
p2p.sendData(peerId, eventName, payload)p2p.dataSends plugin data targeted to a peer.
media.playAudioClip(request)media.playAudioPlays an audio URL at optional volume.
media.addCustomAudioStream(request)media.addAudioStreamContributes an audio MediaStream.
media.addCustomVideoStream(request)media.addVideoStreamRegisters a video MediaStream contribution.
media.setInputVolume(volume)audio.volumeSets local input volume.
media.setOutputVolume(volume)audio.volumeSets local output volume.

Storage

MethodCapabilityDescription
clientData.read(key)storage.localReads async plugin-local data.
clientData.write(key, value)storage.localWrites async plugin-local data.
clientData.remove(key)storage.localRemoves async plugin-local data.
serverData.read(key)storage.serverData.readReads local per-user/per-server data.
serverData.write(key, value)storage.serverData.writeWrites local per-user/per-server data.
serverData.remove(key)storage.serverData.writeRemoves local per-user/per-server data.
storage.get(key)storage.localLegacy synchronous local read.
storage.set(key, value)storage.localLegacy synchronous local write.
storage.remove(key)storage.localLegacy synchronous local remove.

UI Contributions

interface PluginApiActionContribution {
icon?: string;
label: string;
run: () => Promise<void> | void;
}

interface PluginApiPageContribution {
label: string;
path: string;
render: () => HTMLElement | string;
}

interface PluginApiPanelContribution {
label: string;
order?: number;
render: () => HTMLElement | string;
}

interface PluginApiSettingsPageContribution {
label: string;
order?: number;
render: () => HTMLElement | string;
settingsKey?: string;
}

interface PluginApiChannelSectionContribution {
label: string;
order?: number;
type?: 'audio' | 'custom' | 'video';
}

interface PluginApiEmbedRendererContribution {
embedType: string;
render: (payload: unknown) => HTMLElement | string;
}

interface PluginApiDomMountRequest {
element: HTMLElement;
position?: InsertPosition;
target: Element | string;
}
MethodCapabilityDescription
ui.registerAppPage(id, contribution)ui.pagesAdds a plugin app page.
ui.registerSettingsPage(id, contribution)ui.settingsAdds a plugin settings page.
ui.registerSidePanel(id, contribution)ui.sidePanelAdds a side panel.
ui.registerChannelSection(id, contribution)ui.channelsSectionAdds a channel section.
ui.registerComposerAction(id, contribution)ui.pagesAdds a composer action.
ui.registerProfileAction(id, contribution)ui.pagesAdds a profile action.
ui.registerToolbarAction(id, contribution)ui.pagesAdds an action tile to the server side panel View plugins menu.
ui.registerEmbedRenderer(id, contribution)ui.embedsAdds an embed renderer.
ui.mountElement(id, request)ui.domMounts plugin-owned DOM into a target element or selector.

Context and Logger

MethodCapabilityDescription
context.getCurrent()NoneReads current user, server, active text channel, and active voice channel.
logger.debug(message, data?)NoneWrites a debug plugin log entry.
logger.info(message, data?)NoneWrites an info plugin log entry.
logger.warn(message, data?)NoneWrites a warning plugin log entry.
logger.error(message, data?)NoneWrites an error plugin log entry.