Guide discord.js
Sujets populaires

Permissions

Les Permissions sont la fonctionnalité principale de Discord, permettant aux utilisateurs de personnaliser le fonctionnement de leur serveur selon leurs préférences. Essentiellement, les Permissions et les remplacements de permission indiquent à Discord qui est autorisé à faire quoi et où. Les Permissions peuvent être très déroutantes au début, mais ce guide est là pour les expliquer et les clarifier, alors plongeons-y !

Rôles comme permissions de bot

Si vous voulez garder vos vérifications de permissions de bot simples, vous pourriez trouver suffisant de vérifier si le membre exécutant la commande a un rôle spécifique.

Si vous avez l'ID du rôle, vous pouvez vérifier si la Collection .roles sur un objet GuildMember l'inclut, en utilisant .has(). Si vous ne connaissez pas l'ID et souhaitez vérifier quelque chose comme un rôle "Mod", vous pouvez utiliser .some().

member.roles.cache.has('role-id-here');
// retourne true si le membre a le rôle

member.roles.cache.some((role) => role.name === 'Mod');
// retourne true si l'un des rôles du membre s'appelle exactement "Mod"

Si vous souhaitez améliorer légèrement ce système, vous pouvez inclure le propriétaire de la guilde en comparant l'ID du membre exécutant avec interaction.guild.ownerId.

Pour inclure des vérifications de permissions comme Administrator ou ManageGuild, continuez votre lecture car nous couvrirons les permissions Discord et toutes leurs complexités dans les sections suivantes.

Terminologie

  • Permission : La capacité d'exécuter une certaine action dans Discord
  • Overwrite : Règle sur un canal pour modifier les permissions pour un membre ou un rôle
  • BitField : Représentation binaire des permissions Discord
  • Base Permissions : Permissions pour les rôles que le membre a, définies au niveau de la guilde
  • Final Permissions : Permissions pour un membre ou un rôle, après l'application de tous les overwrites
  • Flag : Chaîne lisible par l'homme en PascalCase (par exemple, KickMembers) qui fait référence à une position dans le BitField de permission. Vous pouvez trouver une liste de tous les drapeaux valides sur la page PermissionsBitField#Flags

Vous pouvez fournir des décimales de permissions partout où nous utilisons des littéraux de drapeaux dans ce guide. Si vous être intéressé par une calculatrice de permissions pratique, vous pouvez consulter la section "Bot" du portail de développeur Discord.

Permissions de base

Définition des permissions de rôle

Les permissions de base sont définies sur les rôles, pas sur le membre de la guilde lui-même. Pour les modifier, vous accédez à un objet Role (par exemple via member.roles.cache.first() ou guild.roles.cache.random()) et utilisez la méthode .setPermissions(). Voici comment vous modifieriez les permissions de base pour le rôle @everyone, par exemple :

const { PermissionsBitField } = require('discord.js');

guild.roles.everyone.setPermissions([PermissionsBitField.Flags.SendMessages, PermissionsBitField.Flags.ViewChannel]);

Toute permission non référencée dans le tableau de drapeaux ou le champ de bit n'est pas accordée au rôle.

Notez que les noms des drapeaux sont littéraux. Bien que ViewChannel accorde l'accès pour voir plusieurs canaux, le drapeau de permission s'appelle toujours ViewChannel sous sa forme singulière.

Création d'un rôle avec des permissions

Alternativement, vous pouvez fournir les permissions en tant que propriété de RoleCreateOptions lors de la création du rôle sous la forme d'un tableau de chaînes de drapeaux ou d'un numéro de permission :

const { PermissionsBitField } = require('discord.js');

guild.roles.create({
	name: 'Mod',
	permissions: [PermissionsBitField.Flags.SendMessages, PermissionsBitField.Flags.KickMembers],
});

Vérification des permissions des membres

Pour savoir si l'un des rôles d'un membre a une permission activée, vous pouvez utiliser la méthode .has() sur GuildMember#permissions et fournir un drapeau de permission, un tableau ou un numéro à vérifier. Vous pouvez également spécifier si vous souhaitez autoriser la permission Administrator ou le statut de propriétaire de guilde à ignorer cette vérification avec les paramètres suivants.

const { PermissionsBitField } = require('discord.js');

if (member.permissions.has(PermissionsBitField.Flags.KickMembers)) {
	console.log('Ce membre peut expulser');
}

if (member.permissions.has([PermissionsBitField.Flags.KickMembers, PermissionsBitField.Flags.BanMembers])) {
	console.log('Ce membre peut bannir et expulser');
}

if (member.permissions.has(PermissionsBitField.Flags.KickMembers, false)) {
	console.log('Ce membre peut expulser sans permettre à l\'administrateur de passer outre');
}

Si vous fournissez plusieurs permissions à la méthode, elle retournera seulement true si toutes les permissions spécifiées sont accordées.

Vous pouvez en savoir plus sur la méthode .has() ici.

Overwrites de canaux

Les overwrites de permission contrôlent les capacités des membres pour ce canal spécifique ou un ensemble de canaux s'ils sont appliqués à une catégorie avec des canaux enfants synchronisés.

Comme vous l'avez probablement déjà vu dans votre client de bureau, les overwrites de canaux ont trois états :

  • Autorisation explicite (true, vert ✓)
  • Refus explicite (false, rouge X)
  • Par défaut (null, gris /)

Ajout d'overwrites

Pour ajouter un overwrite de permission pour un rôle ou un membre de la guilde, vous accédez aux TextChannel#permissionOverwrites du canal et utilisez la méthode .create(). Le premier paramètre est la cible de l'overwrite, soit un objet Role soit un objet User (ou leur resolvable respectif), et le second est un objet PermissionOverwriteOptions.

Ajoutons un overwrite pour verrouiller tout le monde hors du canal. L'ID de guilde double en tant qu'ID de rôle pour le rôle par défaut @everyone comme démontré ci-dessous :

channel.permissionOverwrites.create(channel.guild.roles.everyone, { ViewChannel: false });

Toute permission non spécifiée n'obtient ni une autorisation explicite ni un overwrite de refus et utilisera la permission de base à moins qu'un autre rôle n'ait un overwrite explicite défini.

Vous pouvez également fournir un tableau d'overwrites lors de la création du canal, comme montré ci-dessous :

const { ChannelType, PermissionsBitField } = require('discord.js');

guild.channels.create({
	name: 'new-channel',
	type: ChannelType.GuildText,
	permissionOverwrites: [
		{
			id: interaction.guild.id,
			deny: [PermissionsBitField.Flags.ViewChannel],
		},
		{
			id: interaction.user.id,
			allow: [PermissionsBitField.Flags.ViewChannel],
		},
	],
});

Édition des overwrites

Pour éditer les overwrites de permission sur le canal avec un ensemble fourni de nouveaux overwrites, vous pouvez utiliser la méthode .edit().

// édite les overwrites pour interdire à tout le monde de voir le canal
channel.permissionOverwrites.edit(guild.id, { ViewChannel: false });

// édite les overwrites pour permettre à un utilisateur de voir le canal
channel.permissionOverwrites.edit(user.id, { ViewChannel: true });

Remplacement des overwrites

Pour remplacer tous les overwrites de permission sur le canal avec un ensemble fourni de nouveaux overwrites, vous pouvez utiliser la méthode .set(). Ceci est extrêmement pratique si vous voulez copier l'ensemble complet des overwrites d'un canal à un autre, car cette méthode permet également de transmettre un tableau ou une Collection de PermissionOverwrites.

const { PermissionsBitField } = require('discord.js');
// copie les overwrites d'un autre canal
channel.permissionOverwrites.set(otherChannel.permissionOverwrites.cache);

// remplace les overwrites avec PermissionOverwriteOptions
channel.permissionOverwrites.set([
	{
		id: guild.id,
		deny: [PermissionsBitField.Flags.ViewChannel],
	},
	{
		id: user.id,
		allow: [PermissionsBitField.Flags.ViewChannel],
	},
]);

Suppression des overwrites

Pour supprimer l'overwrite pour un membre ou un rôle spécifique, vous pouvez utiliser la méthode .delete().

// supprime l'overwrite du canal pour l'utilisateur qui a interagi
channel.permissionOverwrites.delete(interaction.user.id);

Synchronisation avec une catégorie

Si les overwrites de permission sur un canal sous une catégorie correspondent au parent (catégorie), il est considéré comme synchronisé. Cela signifie que tout changement dans les overwrites des catégories changera également les overwrites des canaux. Le changement des overwrites des canaux enfants n'affectera pas le parent.

C'est vraiment tout ce qu'une "sync" dans les catégories Discord signifie ! Les utilisateurs et les développeurs miscomprennent souvent cela et s'attendent à un état de "sync" approprié qui s'applique dans les deux sens.

Pour synchroniser facilement les permissions avec le canal parent, vous pouvez appeler la méthode .lockPermissions() sur le canal enfant respectif.

if (!channel.parent) {
	return console.log('Ce canal n\'est pas listé sous une catégorie');
}

channel
	.lockPermissions()
	.then(() => console.log('Permissions synchronisées avec succès avec le canal parent'))
	.catch(console.error);

Permissions après les overwrites

Il y a deux méthodes utilitaires pour déterminer facilement les permissions finales pour un membre ou un rôle de la guilde dans un canal spécifique : GuildChannel#permissionsFor et GuildMember#permissionsIn - Role#permissionsIn. Tous retournent un objet PermissionsBitField.

Pour vérifier les permissions de votre bot dans le canal où la commande a été utilisée, vous pourriez utiliser quelque chose comme ceci :

// permissions finales pour un membre de la guilde utilisant permissionsFor
const botPermissionsFor = channel.permissionsFor(guild.members.me);

// permissions finales pour un membre de la guilde utilisant permissionsIn
const botPermissionsIn = guild.members.me.permissionsIn(channel);

// permissions finales pour un rôle
const rolePermissions = channel.permissionsFor(role);

Les méthodes .permissionsFor() et .permissionsIn() retournent un objet Permissions avec toutes les permissions définies si le membre ou le rôle a la permission globale Administrator et ne prend pas en compte les overwrites dans ce cas. L'utilisation du deuxième paramètre de la méthode .has() tel que décrit plus loin dans le guide ne vous permettra pas de vérifier sans prendre Administrator en compte ici !

Si vous voulez savoir comment travailler avec les objets Permissions retournés, continuez votre lecture car ce sera notre prochain sujet.

L'objet Permissions

L'objet PermissionsBitField est une classe discord.js contenant un champ de bit de permissions et un ensemble de méthodes utilitaires pour le manipuler facilement. N'oubliez pas que l'utilisation de ces méthodes ne manipulera pas les permissions, mais créera plutôt une nouvelle instance représentant le champ de bit modifié.

Affichage des drapeaux de permission

discord.js fournit une méthode toArray(), qui peut être utilisée pour convertir un objet Permissions en un tableau contenant les drapeaux de permission. Ceci est utile si vous voulez les afficher/lister et cela vous permet d'utiliser d'autres méthodes de manipulation de tableau. Par exemple :

const memberPermissions = member.permissions.toArray();
const rolePermissions = role.permissions.toArray();
// résultat : ['SendMessages', 'AddReactions', 'ChangeNickname', ...]

La valeur de retour de toArray() représente toujours les drapeaux de permission présents dans l'instance Permissions sur laquelle la méthode a été appelée. Cela signifie que si vous appelez la méthode sur, par exemple : PermissionOverwrites#deny, vous recevrrez un tableau de toutes les permissions refusées dans cet overwrite.

De plus, vous pouvez sérialiser le champ de bit sous-jacent de l'objet Permissions en appelant .serialize(). Cela retourne un objet qui mappe les noms de permission à une valeur booléenne, indiquant si le "bit" pertinent est disponible dans l'instance Permissions.

const memberPermissions = member.permissions.serialize();
const rolePermissions = role.permissions.serialize();
// résultat : {
//	SendMessages: true,
//	AddReactions: true,
//	BanMembers: false,
//	...
// }

Conversion des numéros de permission

Certaines méthodes et propriétés dans discord.js retournent des décimales de permissions plutôt qu'un objet Permissions, ce qui rend difficile de les manipuler ou de les lire si vous ne voulez pas utiliser d'opérations bitwise. Cependant, vous pouvez transmettre ces décimales au constructeur Permissions pour les convertir, comme montré ci-dessous.

const { PermissionsBitField } = require('discord.js');

const permissions = new PermissionsBitField(268_550_160n);

Vous pouvez également utiliser cette approche pour d'autres PermissionResolvable comme les tableaux de drapeaux ou les drapeaux.

const { PermissionsBitField } = require('discord.js');

const flags = [
	PermissionsBitField.Flags.ViewChannel,
	PermissionsBitField.Flags.EmbedLinks,
	PermissionsBitField.Flags.AttachFiles,
	PermissionsBitField.Flags.ReadMessageHistory,
	PermissionsBitField.Flags.ManageRoles,
];

const permissions = new PermissionsBitField(flags);

Vérification des permissions

L'objet Permissions propose la méthode .has(), permettant un moyen facile de vérifier les drapeaux dans un champ de bit Permissions. La méthode .has() prend deux paramètres : le premier étant soit un numéro de permission, un seul drapeau, soit un tableau de numéros de permission et de drapeaux, le second étant un booléen, indiquant si vous voulez permettre à la permission Administrator de passer outre (par défaut true).

Supposons que vous voulez savoir si la représentation du champ de bit décimal 268_550_160 a ManageChannels référencé :

const { PermissionsBitField } = require('discord.js');

const bitPermissions = new PermissionsBitField(268_550_160n);

console.log(bitPermissions.has(PermissionsBitField.Flags.ManageChannels));
// résultat : true

console.log(bitPermissions.has([PermissionsBitField.Flags.ManageChannels, PermissionsBitField.Flags.EmbedLinks]));
// résultat : true

console.log(bitPermissions.has([PermissionsBitField.Flags.ManageChannels, PermissionsBitField.Flags.KickMembers]));
// résultat : false

const flagsPermissions = new PermissionsBitField([
	PermissionsBitField.Flags.ManageChannels,
	PermissionsBitField.Flags.EmbedLinks,
	PermissionsBitField.Flags.AttachFiles,
	PermissionsBitField.Flags.ReadMessageHistory,
	PermissionsBitField.Flags.ManageRoles,
]);

console.log(flagsPermissions.has(PermissionsBitField.Flags.ManageChannels));
// résultat : true

console.log(flagsPermissions.has([PermissionsBitField.Flags.ManageChannels, PermissionsBitField.Flags.EmbedLinks]));
// résultat : true

console.log(flagsPermissions.has([PermissionsBitField.Flags.ManageChannels, PermissionsBitField.Flags.KickMembers]));
// résultat : false

const adminPermissions = new PermissionsBitField(PermissionsBitField.Flags.Administrator);

console.log(adminPermissions.has(PermissionsBitField.Flags.ManageChannels));
// résultat : true

console.log(adminPermissions.has(PermissionsBitField.Flags.ManageChannels, true));
// résultat : true

console.log(adminPermissions.has(PermissionsBitField.Flags.ManageChannels, false));
// résultat : false

Manipulation des permissions

L'objet Permissions vous permet d'ajouter ou de supprimer facilement des permissions individuelles d'un champ de bit existant sans vous soucier des opérations bitwise. add() et .remove() peuvent tous deux prendre un seul drapeau ou numéro de permission, un tableau de drapeaux ou de numéros de permission, ou plusieurs drapeaux ou numéros de permission en tant que paramètres multiples.

const { PermissionsBitField } = require('discord.js');

const permissions = new PermissionsBitField([
	PermissionsBitField.Flags.ViewChannel,
	PermissionsBitField.Flags.EmbedLinks,
	PermissionsBitField.Flags.AttachFiles,
	PermissionsBitField.Flags.ReadMessageHistory,
	PermissionsBitField.Flags.ManageRoles,
]);

console.log(permissions.has(PermissionsBitField.Flags.KickMembers));
// résultat : false

permissions.add(PermissionsBitField.Flags.KickMembers);
console.log(permissions.has(PermissionsBitField.Flags.KickMembers));
// résultat : true

permissions.remove(PermissionsBitField.Flags.KickMembers);
console.log(permissions.has(PermissionsBitField.Flags.KickMembers));
// résultat : false

Vous pouvez utiliser ces méthodes pour adapter les permissions ou les overwrites sans toucher aux autres drapeaux. Pour y parvenir, vous pouvez obtenir les permissions existantes pour un rôle, manipuler le champ de bit comme décrit ci-dessus et transmettre le champ de bit modifié à role.setPermissions().