Guides
Write a plugin
Group commands that belong together, configure them, reload them from the radio.
A poll on the channel and a vote in DM. Both share the same state, so they live in one plugin.
export const polls = new PluginBuilder<{ channel: string }>()
.setName('polls')
.setDescription('One yes/no poll at a time')
.setBricks((client, { channel }) => {
const votes = new Map<string, 'yes' | 'no'>();
return [
new CommandBuilder()
.setName('poll')
.setDescription('Open a poll on the channel')
.addStringArg((arg) => arg.setName('question').setRequired().setRest())
.setHandler(async (ctx) => {
votes.clear();
await client.channels.get(channel)?.send(`📊 ${ctx.args.question} (/vote yes|no)`);
}),
new CommandBuilder()
.setName('vote')
.setDescription('Vote on the open poll')
.addChoiceArg((arg) => arg.setName('answer').setChoices('yes', 'no').setRequired())
.setHandler((ctx) => {
votes.set(ctx.author.name, ctx.args.answer);
return ctx.reply(`${votes.size} votes so far`);
}),
];
});export default polls.configure({ channel: '#club' });What happens
setBricks() is a factory. It runs when the plugin loads and on every reload, with the client and the
options. State kept in its closure is reset on reload.
configure() returns a copy carrying the options. The file under plugins/ exports that copy, and the
loader registers it. The same plugin can be configured twice with two names.
/plugins reload polls from a DM rebuilds the bricks. If the new version fails, the previous bricks keep
running.
Go further
- Writing one for static bricks and validation.
- Configuring and runtime for load, unload and reload.
- Shipping a package to publish it on npm.