Skip to content

Plugin basics

Every plugin describes itself in plugin-info, returned by info. PhoenixCord reads it once, when the plugin is loaded.

fn info() -> PluginInfo {
PluginInfo {
tags: vec!["Chat".into(), "Utility".into()],
dependencies: vec!["OtherPlugin".into()],
settings: vec![/* see Settings and storage */],
commands: vec![/* see Commands */],
hooks: vec![Hook::ChatBarButtons, Hook::MessagePreSend],
events: vec![EventKind::ChannelSelected],
..PluginInfo::new("SilentMessageToggle", "Adds a button to toggle silent messages", &["you"])
}
}
Field Meaning
name Unique name, ASCII letters, digits, - and _
tags Categories used to filter the plugin list
dependencies Plugins started before this one, automatically
enabled-by-default Enable on first run
required Cannot be disabled
hooks Which hook functions PhoenixCord should call
events Which client events to receive
  • load: PhoenixCord compiles the component and calls info.
  • start: called when the plugin is enabled, after its dependencies started. In Rust, the plugin struct is created with Default right before start.
  • stop: called when the plugin is disabled. Timers are cancelled automatically. In Rust, the struct is dropped afterwards.

A plugin that traps (panics) or exceeds the time limit on any call is stopped and reported as failed. Enabling it again starts it from a fresh instance.

Hooks are the functions PhoenixCord calls to let a plugin change the client. A plugin implements only the hooks it lists in hooks; in Rust every hook has an empty default.

Hook Called for Guide
message-pre-send, message-pre-edit Outgoing messages and edits Messages
message-accessories, message-decorations, message-popover-buttons Every rendered message Messages
chat-bar-buttons The message input User interface
context-menu Every context menu User interface
profile-sections, user-badges User profiles User interface
member-decorations Member list and DM list rows User interface
server-list-elements The server list User interface
settings-panel The plugin’s settings page Settings and storage

Render hooks run every time Discord renders the place they extend. Keep them fast and free of side effects; compute expensive data in event handlers and keep it in the plugin’s state.

on-event receives everything that happens asynchronously. Some events need a subscription in events, the rest are always delivered to the plugin that caused them. See Events.

A plugin keeps its state in memory between calls. In Rust that is the plugin struct:

#[derive(Default)]
struct SilentMessageToggle {
enabled: bool,
}

When state that a render hook depends on changes, call host::request_render() so PhoenixCord renders the hook again. Use settings and storage for anything that must survive a restart.