or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-commands.mdchannels.mdclient.mdcommands.mderrors.mdevents.mdguild.mdindex.mdmessages.mdpermissions.mdtasks.mdui.mdusers.mdutilities.mdvoice.mdwebhooks.md

permissions.mddocs/

0

# Nextcord Permissions and Roles

1

2

Comprehensive permission management, role operations, and access control for Discord servers with fine-grained permission handling.

3

4

## Permissions

5

6

Discord's bitfield-based permission system with comprehensive access control capabilities.

7

8

### Permissions Class { .api }

9

10

```python

11

import nextcord

12

from typing import Dict, Iterator, Tuple, Union

13

14

class Permissions:

15

"""Wraps up a Discord permission value.

16

17

The properties provided are two-way. You can set and retrieve individual permissions.

18

19

Attributes

20

----------

21

value: int

22

The raw value of the permissions.

23

"""

24

25

def __init__(self, permissions: int = 0, **kwargs):

26

"""Initialize permissions.

27

28

Parameters

29

----------

30

permissions: int

31

The raw permissions integer.

32

**kwargs

33

Individual permission flags to set.

34

"""

35

...

36

37

@classmethod

38

def none(cls) -> Permissions:

39

"""A factory method that creates a Permissions with all permissions set to False."""

40

...

41

42

@classmethod

43

def all(cls) -> Permissions:

44

"""A factory method that creates a Permissions with all permissions set to True."""

45

...

46

47

@classmethod

48

def all_channel(cls) -> Permissions:

49

"""A factory method that creates a Permissions with all channel permissions set to True."""

50

...

51

52

@classmethod

53

def general(cls) -> Permissions:

54

"""A factory method that creates a Permissions with general permissions."""

55

...

56

57

@classmethod

58

def membership(cls) -> Permissions:

59

"""A factory method that creates a Permissions with membership permissions."""

60

...

61

62

@classmethod

63

def text(cls) -> Permissions:

64

"""A factory method that creates a Permissions with text channel permissions."""

65

...

66

67

@classmethod

68

def voice(cls) -> Permissions:

69

"""A factory method that creates a Permissions with voice channel permissions."""

70

...

71

72

@classmethod

73

def stage(cls) -> Permissions:

74

"""A factory method that creates a Permissions with stage channel permissions."""

75

...

76

77

@classmethod

78

def stage_moderator(cls) -> Permissions:

79

"""A factory method that creates a Permissions with stage moderator permissions."""

80

...

81

82

@classmethod

83

def advanced(cls) -> Permissions:

84

"""A factory method that creates a Permissions with advanced permissions."""

85

...

86

87

def update(self, **kwargs) -> None:

88

"""Bulk update permissions.

89

90

Parameters

91

----------

92

**kwargs

93

Permission flags to update.

94

"""

95

...

96

97

def __iter__(self) -> Iterator[Tuple[str, bool]]:

98

"""Iterate over all permissions."""

99

...

100

101

# Permission flags (all boolean properties)

102

class Permissions:

103

# General Server Permissions

104

@property

105

def create_instant_invite(self) -> bool:

106

"""bool: Returns True if a user can create instant invites."""

107

...

108

109

@property

110

def kick_members(self) -> bool:

111

"""bool: Returns True if a user can kick members from the guild."""

112

...

113

114

@property

115

def ban_members(self) -> bool:

116

"""bool: Returns True if a user can ban members from the guild."""

117

...

118

119

@property

120

def administrator(self) -> bool:

121

"""bool: Returns True if a user is an administrator. This role overrides all other permissions."""

122

...

123

124

@property

125

def manage_channels(self) -> bool:

126

"""bool: Returns True if a user can edit, delete, or create channels."""

127

...

128

129

@property

130

def manage_guild(self) -> bool:

131

"""bool: Returns True if a user can edit guild properties."""

132

...

133

134

@property

135

def add_reactions(self) -> bool:

136

"""bool: Returns True if a user can add reactions to messages."""

137

...

138

139

@property

140

def view_audit_log(self) -> bool:

141

"""bool: Returns True if a user can view the guild's audit log."""

142

...

143

144

@property

145

def priority_speaker(self) -> bool:

146

"""bool: Returns True if a user can use priority speaker in voice channels."""

147

...

148

149

@property

150

def stream(self) -> bool:

151

"""bool: Returns True if a user can stream in voice channels."""

152

...

153

154

@property

155

def view_channel(self) -> bool:

156

"""bool: Returns True if a user can view channels."""

157

...

158

159

@property

160

def send_messages(self) -> bool:

161

"""bool: Returns True if a user can send messages."""

162

...

163

164

@property

165

def send_tts_messages(self) -> bool:

166

"""bool: Returns True if a user can send TTS messages."""

167

...

168

169

@property

170

def manage_messages(self) -> bool:

171

"""bool: Returns True if a user can manage messages (delete/pin)."""

172

...

173

174

@property

175

def embed_links(self) -> bool:

176

"""bool: Returns True if a user's messages will embed links."""

177

...

178

179

@property

180

def attach_files(self) -> bool:

181

"""bool: Returns True if a user can attach files to messages."""

182

...

183

184

@property

185

def read_message_history(self) -> bool:

186

"""bool: Returns True if a user can read message history."""

187

...

188

189

@property

190

def mention_everyone(self) -> bool:

191

"""bool: Returns True if a user can mention @everyone and @here."""

192

...

193

194

@property

195

def external_emojis(self) -> bool:

196

"""bool: Returns True if a user can use external emojis."""

197

...

198

199

@property

200

def view_guild_insights(self) -> bool:

201

"""bool: Returns True if a user can view guild insights."""

202

...

203

204

@property

205

def connect(self) -> bool:

206

"""bool: Returns True if a user can connect to voice channels."""

207

...

208

209

@property

210

def speak(self) -> bool:

211

"""bool: Returns True if a user can speak in voice channels."""

212

...

213

214

@property

215

def mute_members(self) -> bool:

216

"""bool: Returns True if a user can mute members in voice channels."""

217

...

218

219

@property

220

def deafen_members(self) -> bool:

221

"""bool: Returns True if a user can deafen members in voice channels."""

222

...

223

224

@property

225

def move_members(self) -> bool:

226

"""bool: Returns True if a user can move members between voice channels."""

227

...

228

229

@property

230

def use_voice_activation(self) -> bool:

231

"""bool: Returns True if a user can use voice activation in voice channels."""

232

...

233

234

@property

235

def change_nickname(self) -> bool:

236

"""bool: Returns True if a user can change their nickname."""

237

...

238

239

@property

240

def manage_nicknames(self) -> bool:

241

"""bool: Returns True if a user can manage other members' nicknames."""

242

...

243

244

@property

245

def manage_roles(self) -> bool:

246

"""bool: Returns True if a user can manage roles."""

247

...

248

249

@property

250

def manage_webhooks(self) -> bool:

251

"""bool: Returns True if a user can manage webhooks."""

252

...

253

254

@property

255

def manage_emojis_and_stickers(self) -> bool:

256

"""bool: Returns True if a user can manage emojis and stickers."""

257

...

258

259

@property

260

def use_application_commands(self) -> bool:

261

"""bool: Returns True if a user can use application commands."""

262

...

263

264

@property

265

def request_to_speak(self) -> bool:

266

"""bool: Returns True if a user can request to speak in stage channels."""

267

...

268

269

@property

270

def manage_events(self) -> bool:

271

"""bool: Returns True if a user can manage guild events."""

272

...

273

274

@property

275

def manage_threads(self) -> bool:

276

"""bool: Returns True if a user can manage threads."""

277

...

278

279

@property

280

def create_public_threads(self) -> bool:

281

"""bool: Returns True if a user can create public threads."""

282

...

283

284

@property

285

def create_private_threads(self) -> bool:

286

"""bool: Returns True if a user can create private threads."""

287

...

288

289

@property

290

def external_stickers(self) -> bool:

291

"""bool: Returns True if a user can use external stickers."""

292

...

293

294

@property

295

def send_messages_in_threads(self) -> bool:

296

"""bool: Returns True if a user can send messages in threads."""

297

...

298

299

@property

300

def use_embedded_activities(self) -> bool:

301

"""bool: Returns True if a user can use embedded activities in voice channels."""

302

...

303

304

@property

305

def moderate_members(self) -> bool:

306

"""bool: Returns True if a user can moderate members (timeout, etc.)."""

307

...

308

309

# Permission usage examples

310

def create_permissions_examples():

311

"""Examples of creating and working with permissions."""

312

313

# Create permissions with specific flags

314

perms = nextcord.Permissions(

315

send_messages=True,

316

read_message_history=True,

317

add_reactions=True

318

)

319

320

# Create from raw value

321

perms_raw = nextcord.Permissions(permissions=268435456)

322

323

# Factory methods

324

admin_perms = nextcord.Permissions.all()

325

text_perms = nextcord.Permissions.text()

326

voice_perms = nextcord.Permissions.voice()

327

328

# Update permissions

329

perms.update(manage_messages=True, embed_links=True)

330

331

return perms, admin_perms, text_perms, voice_perms

332

333

@bot.slash_command(description="Check permissions for a member")

334

async def checkperms(

335

interaction: nextcord.Interaction,

336

member: Optional[nextcord.Member] = nextcord.SlashOption(

337

description="Member to check permissions for",

338

default=None

339

),

340

channel: Optional[nextcord.TextChannel] = nextcord.SlashOption(

341

description="Channel to check permissions in",

342

default=None

343

)

344

):

345

"""Check a member's permissions in a specific channel or guild."""

346

target = member or interaction.user

347

check_channel = channel or interaction.channel

348

349

# Get permissions

350

if isinstance(check_channel, nextcord.abc.GuildChannel):

351

perms = target.permissions_in(check_channel)

352

context = f"in {check_channel.mention}"

353

else:

354

perms = target.guild_permissions

355

context = "in this server"

356

357

embed = nextcord.Embed(

358

title=f"Permissions for {target.display_name}",

359

description=f"Permissions {context}",

360

color=target.color or nextcord.Color.blue()

361

)

362

363

# Key permissions to display

364

key_perms = {

365

"Administrator": perms.administrator,

366

"Manage Server": perms.manage_guild,

367

"Manage Channels": perms.manage_channels,

368

"Manage Roles": perms.manage_roles,

369

"Manage Messages": perms.manage_messages,

370

"Kick Members": perms.kick_members,

371

"Ban Members": perms.ban_members,

372

"Moderate Members": perms.moderate_members,

373

"Send Messages": perms.send_messages,

374

"View Channels": perms.view_channel,

375

"Connect to Voice": perms.connect,

376

"Speak in Voice": perms.speak,

377

"Move Members": perms.move_members,

378

}

379

380

# Group permissions by category

381

dangerous_perms = []

382

moderation_perms = []

383

basic_perms = []

384

385

for perm_name, has_perm in key_perms.items():

386

emoji = "βœ…" if has_perm else "❌"

387

perm_text = f"{emoji} {perm_name}"

388

389

if perm_name in ["Administrator", "Manage Server", "Manage Roles"]:

390

dangerous_perms.append(perm_text)

391

elif perm_name in ["Kick Members", "Ban Members", "Moderate Members", "Manage Messages"]:

392

moderation_perms.append(perm_text)

393

else:

394

basic_perms.append(perm_text)

395

396

if dangerous_perms:

397

embed.add_field(name="πŸ”΄ Administrative", value="\n".join(dangerous_perms), inline=True)

398

if moderation_perms:

399

embed.add_field(name="🟑 Moderation", value="\n".join(moderation_perms), inline=True)

400

if basic_perms:

401

embed.add_field(name="🟒 Basic", value="\n".join(basic_perms), inline=True)

402

403

# Show raw permission value

404

embed.add_field(

405

name="Raw Permission Value",

406

value=f"`{perms.value}`",

407

inline=False

408

)

409

410

await interaction.response.send_message(embed=embed)

411

```

412

413

## Permission Overwrites

414

415

Channel-specific permission overrides for users and roles.

416

417

### PermissionOverwrite Class { .api }

418

419

```python

420

class PermissionOverwrite:

421

"""A permission overwrite for a channel.

422

423

Permission overwrites allow you to set specific permissions for roles or members

424

in individual channels, overriding their guild-level permissions.

425

426

Attributes

427

----------

428

allow: Permissions

429

Permissions that are explicitly allowed.

430

deny: Permissions

431

Permissions that are explicitly denied.

432

"""

433

434

def __init__(self, **permissions):

435

"""Create a permission overwrite.

436

437

Parameters

438

----------

439

**permissions

440

Permission flags. Use None for neutral (inherit), True for allow, False for deny.

441

"""

442

...

443

444

@classmethod

445

def from_pair(cls, allow: Permissions, deny: Permissions) -> PermissionOverwrite:

446

"""Create a PermissionOverwrite from an allow/deny pair.

447

448

Parameters

449

----------

450

allow: Permissions

451

Permissions to explicitly allow.

452

deny: Permissions

453

Permissions to explicitly deny.

454

455

Returns

456

-------

457

PermissionOverwrite

458

The created permission overwrite.

459

"""

460

...

461

462

def update(self, **permissions) -> None:

463

"""Update the permission overwrite.

464

465

Parameters

466

----------

467

**permissions

468

Permission flags to update.

469

"""

470

...

471

472

def is_empty(self) -> bool:

473

"""bool: Whether the overwrite is empty (no explicit allows or denies)."""

474

...

475

476

# Permission overwrite examples

477

@bot.slash_command(description="Set channel permissions for a role")

478

async def setperms(

479

interaction: nextcord.Interaction,

480

channel: nextcord.TextChannel = nextcord.SlashOption(description="Channel to modify"),

481

role: nextcord.Role = nextcord.SlashOption(description="Role to set permissions for"),

482

permission: str = nextcord.SlashOption(

483

description="Permission to modify",

484

choices=[

485

"send_messages", "view_channel", "manage_messages",

486

"add_reactions", "attach_files", "read_message_history"

487

]

488

),

489

value: str = nextcord.SlashOption(

490

description="Permission value",

491

choices=["allow", "deny", "neutral"]

492

)

493

):

494

"""Set specific channel permissions for a role."""

495

if not interaction.user.guild_permissions.manage_roles:

496

await interaction.response.send_message(

497

"❌ You don't have permission to manage roles.",

498

ephemeral=True

499

)

500

return

501

502

# Get current overwrite or create new one

503

overwrite = channel.overwrites_for(role)

504

505

# Set the permission

506

perm_value = None if value == "neutral" else (value == "allow")

507

setattr(overwrite, permission, perm_value)

508

509

try:

510

await channel.set_permissions(

511

role,

512

overwrite=overwrite,

513

reason=f"Permission modified by {interaction.user}"

514

)

515

516

emoji = {"allow": "βœ…", "deny": "❌", "neutral": "βž–"}[value]

517

await interaction.response.send_message(

518

f"{emoji} Set `{permission}` to `{value}` for {role.mention} in {channel.mention}.",

519

ephemeral=True

520

)

521

522

except nextcord.Forbidden:

523

await interaction.response.send_message(

524

"❌ I don't have permission to modify channel permissions.",

525

ephemeral=True

526

)

527

except nextcord.HTTPException as e:

528

await interaction.response.send_message(

529

f"❌ Failed to set permissions: {e}",

530

ephemeral=True

531

)

532

533

@bot.slash_command(description="Lock a channel")

534

async def lockdown(

535

interaction: nextcord.Interaction,

536

channel: Optional[nextcord.TextChannel] = nextcord.SlashOption(

537

description="Channel to lock (defaults to current)",

538

default=None

539

),

540

reason: Optional[str] = nextcord.SlashOption(description="Reason for lockdown", default=None)

541

):

542

"""Lock a channel to prevent members from sending messages."""

543

if not interaction.user.guild_permissions.manage_channels:

544

await interaction.response.send_message(

545

"❌ You don't have permission to manage channels.",

546

ephemeral=True

547

)

548

return

549

550

target_channel = channel or interaction.channel

551

552

# Get @everyone role

553

everyone_role = interaction.guild.default_role

554

555

# Create overwrite that denies sending messages

556

overwrite = nextcord.PermissionOverwrite(send_messages=False)

557

558

try:

559

await target_channel.set_permissions(

560

everyone_role,

561

overwrite=overwrite,

562

reason=reason or f"Channel locked by {interaction.user}"

563

)

564

565

embed = nextcord.Embed(

566

title="πŸ”’ Channel Locked",

567

description=f"{target_channel.mention} has been locked.",

568

color=nextcord.Color.red()

569

)

570

571

if reason:

572

embed.add_field(name="Reason", value=reason, inline=False)

573

574

embed.set_footer(text=f"Locked by {interaction.user}", icon_url=interaction.user.display_avatar.url)

575

576

await interaction.response.send_message(embed=embed)

577

578

except nextcord.Forbidden:

579

await interaction.response.send_message(

580

"❌ I don't have permission to modify this channel.",

581

ephemeral=True

582

)

583

except nextcord.HTTPException as e:

584

await interaction.response.send_message(

585

f"❌ Failed to lock channel: {e}",

586

ephemeral=True

587

)

588

589

@bot.slash_command(description="Unlock a channel")

590

async def unlock(

591

interaction: nextcord.Interaction,

592

channel: Optional[nextcord.TextChannel] = nextcord.SlashOption(

593

description="Channel to unlock (defaults to current)",

594

default=None

595

),

596

reason: Optional[str] = nextcord.SlashOption(description="Reason for unlock", default=None)

597

):

598

"""Unlock a channel to allow members to send messages again."""

599

if not interaction.user.guild_permissions.manage_channels:

600

await interaction.response.send_message(

601

"❌ You don't have permission to manage channels.",

602

ephemeral=True

603

)

604

return

605

606

target_channel = channel or interaction.channel

607

everyone_role = interaction.guild.default_role

608

609

try:

610

# Remove the send_messages override (set to neutral)

611

overwrite = target_channel.overwrites_for(everyone_role)

612

overwrite.send_messages = None

613

614

if overwrite.is_empty():

615

# If overwrite is empty, delete it entirely

616

await target_channel.set_permissions(

617

everyone_role,

618

overwrite=None,

619

reason=reason or f"Channel unlocked by {interaction.user}"

620

)

621

else:

622

# Keep other overwrites but remove send_messages restriction

623

await target_channel.set_permissions(

624

everyone_role,

625

overwrite=overwrite,

626

reason=reason or f"Channel unlocked by {interaction.user}"

627

)

628

629

embed = nextcord.Embed(

630

title="πŸ”“ Channel Unlocked",

631

description=f"{target_channel.mention} has been unlocked.",

632

color=nextcord.Color.green()

633

)

634

635

if reason:

636

embed.add_field(name="Reason", value=reason, inline=False)

637

638

embed.set_footer(text=f"Unlocked by {interaction.user}", icon_url=interaction.user.display_avatar.url)

639

640

await interaction.response.send_message(embed=embed)

641

642

except nextcord.Forbidden:

643

await interaction.response.send_message(

644

"❌ I don't have permission to modify this channel.",

645

ephemeral=True

646

)

647

except nextcord.HTTPException as e:

648

await interaction.response.send_message(

649

f"❌ Failed to unlock channel: {e}",

650

ephemeral=True

651

)

652

```

653

654

## Roles

655

656

Guild roles with hierarchy, permissions, and member management.

657

658

### Role Class { .api }

659

660

```python

661

class Role(nextcord.abc.Snowflake):

662

"""Represents a Discord role.

663

664

Attributes

665

----------

666

id: int

667

The role ID.

668

name: str

669

The role name.

670

guild: Guild

671

The guild this role belongs to.

672

hoist: bool

673

Whether the role is displayed separately in the member list.

674

position: int

675

The role's position in the hierarchy. Higher is more important.

676

managed: bool

677

Whether the role is managed by an integration (bot, booster, etc.).

678

mentionable: bool

679

Whether the role can be mentioned by members.

680

permissions: Permissions

681

The permissions this role grants.

682

colour: Colour

683

The role's color.

684

created_at: datetime.datetime

685

When the role was created.

686

mention: str

687

A string that mentions this role.

688

members: List[Member]

689

A list of members who have this role.

690

"""

691

692

@property

693

def color(self) -> nextcord.Colour:

694

"""nextcord.Colour: An alias for colour."""

695

...

696

697

def is_default(self) -> bool:

698

"""bool: Whether this is the @everyone role."""

699

...

700

701

def is_bot_managed(self) -> bool:

702

"""bool: Whether this role is managed by a bot."""

703

...

704

705

def is_premium_subscriber(self) -> bool:

706

"""bool: Whether this role is the premium subscriber (booster) role."""

707

...

708

709

def is_integration(self) -> bool:

710

"""bool: Whether this role is managed by an integration."""

711

...

712

713

async def edit(

714

self,

715

*,

716

name: str = MISSING,

717

permissions: Permissions = MISSING,

718

colour: Union[nextcord.Colour, int] = MISSING,

719

color: Union[nextcord.Colour, int] = MISSING,

720

hoist: bool = MISSING,

721

mentionable: bool = MISSING,

722

position: int = MISSING,

723

reason: Optional[str] = None,

724

icon: Optional[bytes] = MISSING,

725

unicode_emoji: Optional[str] = MISSING,

726

) -> Role:

727

"""Edit the role.

728

729

Parameters

730

----------

731

name: str

732

The role's new name.

733

permissions: Permissions

734

The role's new permissions.

735

colour: Union[nextcord.Colour, int]

736

The role's new colour.

737

color: Union[nextcord.Colour, int]

738

Alias for colour.

739

hoist: bool

740

Whether the role should be hoisted.

741

mentionable: bool

742

Whether the role should be mentionable.

743

position: int

744

The role's new position.

745

reason: Optional[str]

746

The reason for editing this role.

747

icon: Optional[bytes]

748

The role's new icon (for premium guilds).

749

unicode_emoji: Optional[str]

750

The role's new unicode emoji (for premium guilds).

751

752

Returns

753

-------

754

Role

755

The newly edited role.

756

"""

757

...

758

759

async def delete(self, *, reason: Optional[str] = None) -> None:

760

"""Delete the role.

761

762

Parameters

763

----------

764

reason: Optional[str]

765

The reason for deleting this role.

766

"""

767

...

768

769

# Role management examples

770

@bot.slash_command(description="Create a new role")

771

async def createrole(

772

interaction: nextcord.Interaction,

773

name: str = nextcord.SlashOption(description="Role name"),

774

color: Optional[str] = nextcord.SlashOption(

775

description="Role color (hex code, e.g., #FF0000)",

776

default=None

777

),

778

hoist: bool = nextcord.SlashOption(description="Display separately in member list", default=False),

779

mentionable: bool = nextcord.SlashOption(description="Allow anyone to mention", default=False)

780

):

781

"""Create a new role with specified properties."""

782

if not interaction.user.guild_permissions.manage_roles:

783

await interaction.response.send_message(

784

"❌ You don't have permission to manage roles.",

785

ephemeral=True

786

)

787

return

788

789

# Parse color if provided

790

role_color = nextcord.Color.default()

791

if color:

792

try:

793

# Remove # if present

794

color_hex = color.lstrip('#')

795

role_color = nextcord.Color(int(color_hex, 16))

796

except ValueError:

797

await interaction.response.send_message(

798

"❌ Invalid color format. Use hex format like `#FF0000`.",

799

ephemeral=True

800

)

801

return

802

803

try:

804

role = await interaction.guild.create_role(

805

name=name,

806

color=role_color,

807

hoist=hoist,

808

mentionable=mentionable,

809

reason=f"Role created by {interaction.user}"

810

)

811

812

embed = nextcord.Embed(

813

title="Role Created",

814

description=f"Successfully created role {role.mention}",

815

color=role.color

816

)

817

818

embed.add_field(name="Name", value=role.name, inline=True)

819

embed.add_field(name="ID", value=role.id, inline=True)

820

embed.add_field(name="Position", value=role.position, inline=True)

821

embed.add_field(name="Color", value=str(role.color), inline=True)

822

embed.add_field(name="Hoisted", value="Yes" if role.hoist else "No", inline=True)

823

embed.add_field(name="Mentionable", value="Yes" if role.mentionable else "No", inline=True)

824

825

await interaction.response.send_message(embed=embed)

826

827

except nextcord.Forbidden:

828

await interaction.response.send_message(

829

"❌ I don't have permission to create roles.",

830

ephemeral=True

831

)

832

except nextcord.HTTPException as e:

833

await interaction.response.send_message(

834

f"❌ Failed to create role: {e}",

835

ephemeral=True

836

)

837

838

@bot.slash_command(description="Delete a role")

839

async def deleterole(

840

interaction: nextcord.Interaction,

841

role: nextcord.Role = nextcord.SlashOption(description="Role to delete"),

842

reason: Optional[str] = nextcord.SlashOption(description="Reason for deletion", default=None)

843

):

844

"""Delete a role from the server."""

845

if not interaction.user.guild_permissions.manage_roles:

846

await interaction.response.send_message(

847

"❌ You don't have permission to manage roles.",

848

ephemeral=True

849

)

850

return

851

852

# Check if it's the @everyone role

853

if role.is_default():

854

await interaction.response.send_message(

855

"❌ Cannot delete the @everyone role.",

856

ephemeral=True

857

)

858

return

859

860

# Check hierarchy

861

if role.position >= interaction.user.top_role.position and interaction.user != interaction.guild.owner:

862

await interaction.response.send_message(

863

"❌ Cannot delete this role (same or higher position than your top role).",

864

ephemeral=True

865

)

866

return

867

868

# Check if role is managed

869

if role.managed:

870

await interaction.response.send_message(

871

"❌ Cannot delete managed roles (bot roles, booster roles, etc.).",

872

ephemeral=True

873

)

874

return

875

876

role_name = role.name

877

member_count = len(role.members)

878

879

try:

880

await role.delete(reason=reason or f"Role deleted by {interaction.user}")

881

882

embed = nextcord.Embed(

883

title="Role Deleted",

884

description=f"Successfully deleted role **{role_name}**",

885

color=nextcord.Color.red()

886

)

887

888

embed.add_field(name="Members Affected", value=member_count, inline=True)

889

890

if reason:

891

embed.add_field(name="Reason", value=reason, inline=False)

892

893

embed.set_footer(text=f"Deleted by {interaction.user}", icon_url=interaction.user.display_avatar.url)

894

895

await interaction.response.send_message(embed=embed)

896

897

except nextcord.Forbidden:

898

await interaction.response.send_message(

899

"❌ I don't have permission to delete this role.",

900

ephemeral=True

901

)

902

except nextcord.HTTPException as e:

903

await interaction.response.send_message(

904

f"❌ Failed to delete role: {e}",

905

ephemeral=True

906

)

907

908

@bot.slash_command(description="Edit role permissions")

909

async def editroleperms(

910

interaction: nextcord.Interaction,

911

role: nextcord.Role = nextcord.SlashOption(description="Role to edit"),

912

permission: str = nextcord.SlashOption(

913

description="Permission to toggle",

914

choices=[

915

"manage_channels", "manage_guild", "kick_members", "ban_members",

916

"manage_messages", "send_messages", "add_reactions", "view_channel",

917

"connect", "speak", "mute_members", "deafen_members", "move_members",

918

"manage_nicknames", "manage_roles", "administrator"

919

]

920

),

921

value: bool = nextcord.SlashOption(description="Enable or disable the permission")

922

):

923

"""Edit permissions for a role."""

924

if not interaction.user.guild_permissions.manage_roles:

925

await interaction.response.send_message(

926

"❌ You don't have permission to manage roles.",

927

ephemeral=True

928

)

929

return

930

931

if role.position >= interaction.user.top_role.position and interaction.user != interaction.guild.owner:

932

await interaction.response.send_message(

933

"❌ Cannot edit this role (same or higher position than your top role).",

934

ephemeral=True

935

)

936

return

937

938

if role.managed:

939

await interaction.response.send_message(

940

"❌ Cannot edit managed roles.",

941

ephemeral=True

942

)

943

return

944

945

# Get current permissions and update

946

new_permissions = role.permissions

947

setattr(new_permissions, permission, value)

948

949

try:

950

await role.edit(

951

permissions=new_permissions,

952

reason=f"Permission {permission} {'enabled' if value else 'disabled'} by {interaction.user}"

953

)

954

955

status = "enabled" if value else "disabled"

956

emoji = "βœ…" if value else "❌"

957

958

await interaction.response.send_message(

959

f"{emoji} {permission.replace('_', ' ').title()} {status} for {role.mention}.",

960

ephemeral=True

961

)

962

963

except nextcord.Forbidden:

964

await interaction.response.send_message(

965

"❌ I don't have permission to edit this role.",

966

ephemeral=True

967

)

968

except nextcord.HTTPException as e:

969

await interaction.response.send_message(

970

f"❌ Failed to edit role: {e}",

971

ephemeral=True

972

)

973

974

@bot.slash_command(description="List all roles in the server")

975

async def listroles(interaction: nextcord.Interaction):

976

"""List all roles in the server with their information."""

977

roles = sorted(interaction.guild.roles[1:], key=lambda r: r.position, reverse=True) # Skip @everyone

978

979

if not roles:

980

await interaction.response.send_message("This server has no custom roles.")

981

return

982

983

embed = nextcord.Embed(

984

title=f"Roles in {interaction.guild.name}",

985

description=f"Total roles: {len(roles)}",

986

color=nextcord.Color.blue()

987

)

988

989

role_list = []

990

for i, role in enumerate(roles[:20]): # Limit to first 20 roles

991

member_count = len(role.members)

992

managed_indicator = " πŸ€–" if role.managed else ""

993

hoisted_indicator = " πŸ“Œ" if role.hoist else ""

994

995

role_info = (

996

f"{i+1}. {role.mention} "

997

f"({member_count} member{'s' if member_count != 1 else ''})"

998

f"{managed_indicator}{hoisted_indicator}"

999

)

1000

role_list.append(role_info)

1001

1002

embed.add_field(

1003

name="Roles (by hierarchy)",

1004

value="\n".join(role_list) + (f"\n... and {len(roles) - 20} more" if len(roles) > 20 else ""),

1005

inline=False

1006

)

1007

1008

embed.set_footer(text="πŸ€– = Managed | πŸ“Œ = Hoisted")

1009

1010

await interaction.response.send_message(embed=embed)

1011

```

1012

1013

## Permission Utilities

1014

1015

Utility functions and helpers for working with permissions and roles.

1016

1017

### Permission Helpers { .api }

1018

1019

```python

1020

# Permission checking utilities

1021

def has_any_permission(member: nextcord.Member, *permissions: str) -> bool:

1022

"""Check if a member has any of the specified permissions.

1023

1024

Parameters

1025

----------

1026

member: nextcord.Member

1027

The member to check permissions for.

1028

*permissions: str

1029

Permission names to check for.

1030

1031

Returns

1032

-------

1033

bool

1034

True if the member has any of the permissions.

1035

"""

1036

member_perms = member.guild_permissions

1037

return any(getattr(member_perms, perm, False) for perm in permissions)

1038

1039

def has_all_permissions(member: nextcord.Member, *permissions: str) -> bool:

1040

"""Check if a member has all of the specified permissions.

1041

1042

Parameters

1043

----------

1044

member: nextcord.Member

1045

The member to check permissions for.

1046

*permissions: str

1047

Permission names to check for.

1048

1049

Returns

1050

-------

1051

bool

1052

True if the member has all of the permissions.

1053

"""

1054

member_perms = member.guild_permissions

1055

return all(getattr(member_perms, perm, False) for perm in permissions)

1056

1057

def get_dangerous_permissions(permissions: nextcord.Permissions) -> List[str]:

1058

"""Get a list of dangerous permissions that a user has.

1059

1060

Parameters

1061

----------

1062

permissions: nextcord.Permissions

1063

The permissions to check.

1064

1065

Returns

1066

-------

1067

List[str]

1068

List of dangerous permission names the user has.

1069

"""

1070

dangerous = [

1071

'administrator', 'manage_guild', 'manage_roles', 'manage_channels',

1072

'kick_members', 'ban_members', 'manage_webhooks', 'manage_emojis_and_stickers'

1073

]

1074

1075

return [perm for perm in dangerous if getattr(permissions, perm, False)]

1076

1077

# Permission audit command

1078

@bot.slash_command(description="Audit dangerous permissions in the server")

1079

async def auditperms(interaction: nextcord.Interaction):

1080

"""Audit members with dangerous permissions."""

1081

if not interaction.user.guild_permissions.administrator:

1082

await interaction.response.send_message(

1083

"❌ You need Administrator permission to use this command.",

1084

ephemeral=True

1085

)

1086

return

1087

1088

await interaction.response.defer() # This might take a moment

1089

1090

dangerous_members = []

1091

1092

for member in interaction.guild.members:

1093

if member.bot:

1094

continue

1095

1096

dangerous_perms = get_dangerous_permissions(member.guild_permissions)

1097

if dangerous_perms:

1098

dangerous_members.append((member, dangerous_perms))

1099

1100

if not dangerous_members:

1101

await interaction.followup.send("βœ… No members found with dangerous permissions.")

1102

return

1103

1104

embed = nextcord.Embed(

1105

title="πŸ” Permission Audit Results",

1106

description=f"Found {len(dangerous_members)} members with dangerous permissions",

1107

color=nextcord.Color.orange()

1108

)

1109

1110

# Sort by number of dangerous permissions (most dangerous first)

1111

dangerous_members.sort(key=lambda x: len(x[1]), reverse=True)

1112

1113

member_list = []

1114

for member, perms in dangerous_members[:10]: # Show top 10

1115

perm_text = ", ".join(p.replace('_', ' ').title() for p in perms)

1116

member_list.append(f"**{member.display_name}** ({len(perms)}): {perm_text}")

1117

1118

embed.add_field(

1119

name="Members with Dangerous Permissions",

1120

value="\n".join(member_list) + (f"\n... and {len(dangerous_members) - 10} more" if len(dangerous_members) > 10 else ""),

1121

inline=False

1122

)

1123

1124

embed.set_footer(text="Consider reviewing these permissions for security")

1125

1126

await interaction.followup.send(embed=embed)

1127

1128

# Role hierarchy utilities

1129

@bot.slash_command(description="Show role hierarchy")

1130

async def hierarchy(interaction: nextcord.Interaction):

1131

"""Display the server's role hierarchy."""

1132

roles = sorted(interaction.guild.roles, key=lambda r: r.position, reverse=True)

1133

1134

embed = nextcord.Embed(

1135

title=f"Role Hierarchy in {interaction.guild.name}",

1136

description="Roles listed from highest to lowest position",

1137

color=nextcord.Color.blue()

1138

)

1139

1140

hierarchy_text = []

1141

for i, role in enumerate(roles[:15]): # Show top 15 roles

1142

indent = " " * min(i // 3, 3) # Add visual indentation

1143

member_count = len(role.members)

1144

1145

if role.is_default():

1146

role_name = "@everyone"

1147

else:

1148

role_name = role.name

1149

1150

hierarchy_text.append(

1151

f"{indent}{i+1}. **{role_name}** "

1152

f"({member_count} member{'s' if member_count != 1 else ''})"

1153

)

1154

1155

embed.add_field(

1156

name="Hierarchy",

1157

value="\n".join(hierarchy_text) + (f"\n... and {len(roles) - 15} more" if len(roles) > 15 else ""),

1158

inline=False

1159

)

1160

1161

embed.set_footer(text="Higher positions have priority over lower ones")

1162

1163

await interaction.response.send_message(embed=embed)

1164

1165

# Permission comparison utility

1166

@bot.slash_command(description="Compare permissions between two members")

1167

async def compareperms(

1168

interaction: nextcord.Interaction,

1169

member1: nextcord.Member = nextcord.SlashOption(description="First member"),

1170

member2: nextcord.Member = nextcord.SlashOption(description="Second member")

1171

):

1172

"""Compare permissions between two members."""

1173

perms1 = member1.guild_permissions

1174

perms2 = member2.guild_permissions

1175

1176

embed = nextcord.Embed(

1177

title="Permission Comparison",

1178

description=f"Comparing {member1.display_name} vs {member2.display_name}",

1179

color=nextcord.Color.blue()

1180

)

1181

1182

# Get all permission attributes

1183

all_perms = [attr for attr in dir(perms1) if not attr.startswith('_') and isinstance(getattr(perms1, attr), bool)]

1184

1185

# Categorize differences

1186

member1_only = []

1187

member2_only = []

1188

both_have = []

1189

neither_have = []

1190

1191

for perm in all_perms:

1192

has_perm1 = getattr(perms1, perm, False)

1193

has_perm2 = getattr(perms2, perm, False)

1194

1195

perm_display = perm.replace('_', ' ').title()

1196

1197

if has_perm1 and not has_perm2:

1198

member1_only.append(perm_display)

1199

elif has_perm2 and not has_perm1:

1200

member2_only.append(perm_display)

1201

elif has_perm1 and has_perm2:

1202

both_have.append(perm_display)

1203

else:

1204

neither_have.append(perm_display)

1205

1206

if member1_only:

1207

embed.add_field(

1208

name=f"βœ… Only {member1.display_name} has",

1209

value=", ".join(member1_only[:10]) + ("..." if len(member1_only) > 10 else ""),

1210

inline=False

1211

)

1212

1213

if member2_only:

1214

embed.add_field(

1215

name=f"βœ… Only {member2.display_name} has",

1216

value=", ".join(member2_only[:10]) + ("..." if len(member2_only) > 10 else ""),

1217

inline=False

1218

)

1219

1220

if both_have:

1221

embed.add_field(

1222

name="🀝 Both have",

1223

value=", ".join(both_have[:10]) + ("..." if len(both_have) > 10 else ""),

1224

inline=False

1225

)

1226

1227

await interaction.response.send_message(embed=embed)

1228

```

1229

1230

This comprehensive documentation covers all aspects of nextcord's permission and role system, providing developers with the tools needed to implement sophisticated access control in their Discord bots.