Guides
Read the arguments
Declare what a command takes and get it typed in the handler.
/heard 6 repeater lists the repeaters heard in the last six hours. Both values are optional and have a
default.
export default new CommandBuilder()
.setName('heard')
.setDescription('Nodes heard recently')
.addIntegerArg((arg) => arg.setName('hours').setDescription('How far back').setMin(1).setMax(48).setDefault(1))
.addChoiceArg((arg) =>
arg.setName('kind').setDescription('Node kind').setChoices('chat', 'repeater').setDefault('chat'),
)
.setHandler((ctx) => {
// ctx.args is { hours: number; kind: 'chat' | 'repeater' }
const since = Date.now() - ctx.args.hours * 3_600_000;
const heard = ctx.client.contacts.cache.filter(
(contact) => contact.type === ctx.args.kind && contact.lastSeen.getTime() > since,
);
return ctx.reply(`${heard.size} ${ctx.args.kind} nodes in the last ${ctx.args.hours}h`);
});What happens
Each add*Arg call declares one argument. ctx.args is typed from these calls, so hours is a
number and kind is 'chat' | 'repeater' without a cast.
A value outside the range, or a kind that is not in the list, never reaches the handler. The bot answers with the usage line instead.
Values are split on spaces. Double quotes keep a value with spaces together. A string argument with
setRest() takes the rest of the line.
Go further
- Arguments for the eight argument types and their rules.
- Context and pipeline for what runs before the handler.
- ArgBuilder in the reference.