meshcore.js
Roles and permissions

Model and built-in permissions

Permissions come from roles. The core permissions and what they unlock.

Permissions come only from roles. A Role has a priority, a list of permissions and a member source. The library never stores membership. You own it, in a .env list, a database or a config file, and hand it to setMembers().

Built-in permissions

Permissions.* are ready-made permissions named core.*. The core. prefix is reserved for them.

PermissionUnlocks
Permissions.AdministratorEvery permission
Permissions.ManageRolesGive and remove roles, limited by the hierarchy
Permissions.ManageContactsAdd, remove and edit radio contacts
Permissions.ManageChannelsCreate and delete radio channels
Permissions.ManageJobsRun, pause and resume jobs
Permissions.ManagePluginsLoad, unload and reload plugins
Permissions.ViewPermissionsSee who has which role

One role granting Permissions.Administrator is enough to unlock the built-in /plugins and /jobs commands and any command you protect with it.

roles/owner.ts
import { Client, Permissions, RoleBuilder, SerialTransport } from '@meshcorejs/client';

const client = new Client({ transport: new SerialTransport({ path: '/dev/ttyACM0' }) });

client.register(
  new RoleBuilder()
    .setName('owner')
    .setDescription('Bot owners')
    .setPriority(1000)
    .addPermissions(Permissions.Administrator)
    .setMembers((process.env.OWNER_KEYS ?? '').split(',').filter(Boolean)),
);

Your own permissions

For anything beyond the built-ins, declare a PermissionBuilder, grant it to a role, and require it on a command.

main.ts
import { CommandBuilder, PermissionBuilder } from '@meshcorejs/client';

const trainAlert = new PermissionBuilder().setName('train.alert').setDescription('Broadcast a traffic alert');

client.register([
  trainAlert,
  new RoleBuilder()
    .setName('alerts')
    .setPriority(20)
    .addPermissions(trainAlert)
    .setMembers(moderatorKeys, { cacheTtl: 60 }),
  new CommandBuilder()
    .setName('alert')
    .setDescription('Broadcast a traffic alert')
    .addStringArg((arg) => arg.setName('text').setRequired().setRest())
    .setRequiredPermissions(trainAlert)
    .setHandler(async (ctx) => {
      const channel = ctx.client.channels.get('#lyon');
      if (!channel) return ctx.reply('Channel #lyon is not on the radio');
      await channel.send(ctx.args.text);
      await ctx.reply('Broadcast sent');
    }),
]);

Reference

On this page