0
# Nextcord Users and Members
1
2
User representation, member management, permission handling, and voice state tracking for comprehensive user operations in Discord servers.
3
4
## User Class
5
6
Basic Discord user representation with account information and direct messaging capabilities.
7
8
### User Attributes and Methods { .api }
9
10
```python
11
import nextcord
12
from nextcord.abc import Messageable, Snowflake
13
from datetime import datetime
14
from typing import Optional, Union, List
15
16
class User(Snowflake, Messageable):
17
"""Represents a Discord user.
18
19
This is the base class for all user-like objects in Discord.
20
21
Attributes
22
----------
23
id: int
24
The user's unique ID.
25
name: str
26
The user's username, not including the discriminator.
27
discriminator: str
28
The user's discriminator (4-digit number).
29
global_name: Optional[str]
30
The user's global display name, if they have one.
31
avatar: Optional[Asset]
32
The user's avatar asset. None if they have no avatar.
33
bot: bool
34
Whether the user is a bot account.
35
system: bool
36
Whether the user is a system user (Discord Official).
37
created_at: datetime.datetime
38
When the user account was created.
39
default_avatar: Asset
40
The default avatar for the user.
41
display_avatar: Asset
42
The "display" avatar for the user (avatar or default avatar).
43
mention: str
44
A string that allows you to mention the user.
45
"""
46
47
@property
48
def display_name(self) -> str:
49
"""str: The user's display name (global_name if available, otherwise username)."""
50
...
51
52
def mentioned_in(self, message: nextcord.Message) -> bool:
53
"""bool: Whether the user is mentioned in the given message.
54
55
Parameters
56
----------
57
message: nextcord.Message
58
The message to check for mentions.
59
60
Returns
61
-------
62
bool
63
True if the user is mentioned in the message.
64
"""
65
...
66
67
async def create_dm(self) -> nextcord.DMChannel:
68
"""Create a direct message channel with this user.
69
70
Returns
71
-------
72
nextcord.DMChannel
73
The DM channel created with this user.
74
"""
75
...
76
77
def dm_channel(self) -> Optional[nextcord.DMChannel]:
78
"""Optional[nextcord.DMChannel]: The DM channel associated with this user, if any."""
79
...
80
81
def avatar_url_as(
82
self,
83
*,
84
format: Optional[str] = None,
85
static_format: str = 'webp',
86
size: int = 1024
87
) -> str:
88
"""Get the user's avatar URL in a specific format.
89
90
Parameters
91
----------
92
format: Optional[str]
93
The format to get the avatar in. If None, uses GIF for animated avatars.
94
static_format: str
95
The format to use for static avatars. Defaults to 'webp'.
96
size: int
97
The size of the avatar to get. Must be a power of 2 between 16 and 4096.
98
99
Returns
100
-------
101
str
102
The avatar URL.
103
"""
104
...
105
106
def is_avatar_animated(self) -> bool:
107
"""bool: Whether the user's avatar is animated (GIF)."""
108
...
109
110
# Basic user operations
111
@bot.event
112
async def on_message(message):
113
"""Example of working with user objects."""
114
user = message.author
115
116
# Get user information
117
print(f"Username: {user.name}#{user.discriminator}")
118
print(f"Display name: {user.display_name}")
119
print(f"User ID: {user.id}")
120
print(f"Is bot: {user.bot}")
121
print(f"Account created: {user.created_at}")
122
123
# Send DM to user
124
if not user.bot:
125
try:
126
await user.send("Hello! This is a direct message.")
127
except nextcord.Forbidden:
128
print(f"Cannot send DM to {user.display_name} - DMs disabled")
129
130
@bot.slash_command(description="Get user information")
131
async def userinfo(
132
interaction: nextcord.Interaction,
133
user: Optional[nextcord.User] = nextcord.SlashOption(
134
description="The user to get information about",
135
default=None
136
)
137
):
138
"""Get information about a user."""
139
target = user or interaction.user
140
141
embed = nextcord.Embed(
142
title=f"User Information: {target.display_name}",
143
color=nextcord.Color.blue()
144
)
145
146
embed.set_thumbnail(url=target.display_avatar.url)
147
148
embed.add_field(name="Username", value=f"{target.name}#{target.discriminator}", inline=True)
149
embed.add_field(name="User ID", value=target.id, inline=True)
150
embed.add_field(name="Bot Account", value="Yes" if target.bot else "No", inline=True)
151
152
embed.add_field(
153
name="Account Created",
154
value=target.created_at.strftime("%B %d, %Y at %H:%M UTC"),
155
inline=False
156
)
157
158
if target.global_name:
159
embed.add_field(name="Global Display Name", value=target.global_name, inline=True)
160
161
await interaction.response.send_message(embed=embed)
162
```
163
164
## Member Class
165
166
Guild-specific user representation with roles, permissions, and server-specific attributes.
167
168
### Member Attributes and Properties { .api }
169
170
```python
171
class Member(User):
172
"""Represents a Discord member (user in a guild).
173
174
A member is a user with additional guild-specific information like roles,
175
nickname, join date, and permissions.
176
177
Attributes
178
----------
179
guild: Guild
180
The guild this member belongs to.
181
nick: Optional[str]
182
The member's nickname in the guild, if any.
183
joined_at: Optional[datetime.datetime]
184
When the member joined the guild.
185
premium_since: Optional[datetime.datetime]
186
When the member started boosting the guild.
187
pending: bool
188
Whether the member has passed the guild's membership screening.
189
timed_out_until: Optional[datetime.datetime]
190
When the member's timeout expires, if they are timed out.
191
roles: List[Role]
192
A list of roles the member has.
193
activities: List[BaseActivity]
194
The member's current activities.
195
status: Status
196
The member's overall status.
197
mobile_status: Status
198
The member's mobile status.
199
desktop_status: Status
200
The member's desktop status.
201
web_status: Status
202
The member's web status.
203
voice: Optional[VoiceState]
204
The member's voice state, if they are in a voice channel.
205
"""
206
207
@property
208
def display_name(self) -> str:
209
"""str: The member's display name (nickname if available, otherwise username)."""
210
...
211
212
@property
213
def colour(self) -> nextcord.Colour:
214
"""nextcord.Colour: The member's color based on their highest role."""
215
...
216
217
@property
218
def color(self) -> nextcord.Colour:
219
"""nextcord.Colour: An alias for colour."""
220
...
221
222
@property
223
def top_role(self) -> Role:
224
"""Role: The member's highest role."""
225
...
226
227
@property
228
def guild_permissions(self) -> Permissions:
229
"""Permissions: The member's resolved permissions in the guild."""
230
...
231
232
def permissions_in(self, channel: nextcord.abc.GuildChannel) -> Permissions:
233
"""Calculate the member's permissions in a specific channel.
234
235
Parameters
236
----------
237
channel: nextcord.abc.GuildChannel
238
The channel to calculate permissions for.
239
240
Returns
241
-------
242
Permissions
243
The member's permissions in the channel.
244
"""
245
...
246
247
def get_role(self, role_id: int) -> Optional[Role]:
248
"""Get a role the member has by its ID.
249
250
Parameters
251
----------
252
role_id: int
253
The ID of the role to get.
254
255
Returns
256
-------
257
Optional[Role]
258
The role if found, None otherwise.
259
"""
260
...
261
262
# Member information example
263
@bot.slash_command(description="Get detailed member information")
264
async def memberinfo(
265
interaction: nextcord.Interaction,
266
member: Optional[nextcord.Member] = nextcord.SlashOption(
267
description="The member to get information about",
268
default=None
269
)
270
):
271
"""Get detailed information about a guild member."""
272
target = member or interaction.user
273
274
embed = nextcord.Embed(
275
title=f"Member Information: {target.display_name}",
276
color=target.color or nextcord.Color.blue()
277
)
278
279
embed.set_thumbnail(url=target.display_avatar.url)
280
281
# Basic info
282
embed.add_field(name="Username", value=f"{target.name}#{target.discriminator}", inline=True)
283
embed.add_field(name="User ID", value=target.id, inline=True)
284
embed.add_field(name="Bot", value="Yes" if target.bot else "No", inline=True)
285
286
# Nickname
287
if target.nick:
288
embed.add_field(name="Nickname", value=target.nick, inline=True)
289
290
# Join information
291
if target.joined_at:
292
embed.add_field(
293
name="Joined Server",
294
value=target.joined_at.strftime("%B %d, %Y at %H:%M UTC"),
295
inline=False
296
)
297
298
embed.add_field(
299
name="Account Created",
300
value=target.created_at.strftime("%B %d, %Y at %H:%M UTC"),
301
inline=False
302
)
303
304
# Premium information
305
if target.premium_since:
306
embed.add_field(
307
name="Boosting Since",
308
value=target.premium_since.strftime("%B %d, %Y at %H:%M UTC"),
309
inline=True
310
)
311
312
# Timeout information
313
if target.timed_out_until:
314
embed.add_field(
315
name="Timed Out Until",
316
value=target.timed_out_until.strftime("%B %d, %Y at %H:%M UTC"),
317
inline=True
318
)
319
320
# Roles (limit to prevent embed overflow)
321
if target.roles[1:]: # Skip @everyone
322
roles = [role.mention for role in target.roles[1:][:10]]
323
role_text = ", ".join(roles)
324
if len(target.roles) > 11:
325
role_text += f" and {len(target.roles) - 11} more..."
326
embed.add_field(name="Roles", value=role_text, inline=False)
327
328
# Status and activity
329
status_emoji = {
330
nextcord.Status.online: "π’",
331
nextcord.Status.idle: "π‘",
332
nextcord.Status.dnd: "π΄",
333
nextcord.Status.offline: "β«"
334
}
335
embed.add_field(
336
name="Status",
337
value=f"{status_emoji.get(target.status, 'β')} {target.status.name.title()}",
338
inline=True
339
)
340
341
# Voice status
342
if target.voice:
343
voice_info = f"π {target.voice.channel.mention}"
344
if target.voice.self_mute:
345
voice_info += " (Muted)"
346
if target.voice.self_deaf:
347
voice_info += " (Deafened)"
348
embed.add_field(name="Voice Channel", value=voice_info, inline=True)
349
350
await interaction.response.send_message(embed=embed)
351
```
352
353
### Member Role Management { .api }
354
355
```python
356
# Role management methods
357
class Member:
358
async def add_roles(
359
self,
360
*roles: Snowflake,
361
reason: Optional[str] = None,
362
atomic: bool = True
363
) -> None:
364
"""Add roles to the member.
365
366
Parameters
367
----------
368
*roles: Snowflake
369
The roles to add to the member.
370
reason: Optional[str]
371
The reason for adding the roles.
372
atomic: bool
373
Whether to atomically add all roles or add them individually.
374
"""
375
...
376
377
async def remove_roles(
378
self,
379
*roles: Snowflake,
380
reason: Optional[str] = None,
381
atomic: bool = True
382
) -> None:
383
"""Remove roles from the member.
384
385
Parameters
386
----------
387
*roles: Snowflake
388
The roles to remove from the member.
389
reason: Optional[str]
390
The reason for removing the roles.
391
atomic: bool
392
Whether to atomically remove all roles or remove them individually.
393
"""
394
...
395
396
async def edit(
397
self,
398
*,
399
nick: Optional[str] = MISSING,
400
roles: Optional[List[Role]] = MISSING,
401
mute: Optional[bool] = MISSING,
402
deafen: Optional[bool] = MISSING,
403
suppress: Optional[bool] = MISSING,
404
reason: Optional[str] = None,
405
timed_out_until: Optional[datetime.datetime] = MISSING,
406
voice_channel: Optional[nextcord.abc.Snowflake] = MISSING,
407
) -> Optional[Member]:
408
"""Edit the member's attributes.
409
410
Parameters
411
----------
412
nick: Optional[str]
413
The member's new nickname. None to remove nickname.
414
roles: Optional[List[Role]]
415
The member's new list of roles.
416
mute: Optional[bool]
417
Whether to mute the member in voice channels.
418
deafen: Optional[bool]
419
Whether to deafen the member in voice channels.
420
suppress: Optional[bool]
421
Whether to suppress the member (stage channels).
422
reason: Optional[str]
423
The reason for editing the member.
424
timed_out_until: Optional[datetime.datetime]
425
When the member's timeout should expire.
426
voice_channel: Optional[nextcord.abc.Snowflake]
427
The voice channel to move the member to.
428
"""
429
...
430
431
async def timeout(
432
self,
433
until: Optional[datetime.datetime],
434
*,
435
reason: Optional[str] = None
436
) -> None:
437
"""Timeout the member until a specific time.
438
439
Parameters
440
----------
441
until: Optional[datetime.datetime]
442
When the timeout should expire. None to remove timeout.
443
reason: Optional[str]
444
The reason for the timeout.
445
"""
446
...
447
448
# Role management examples
449
@bot.slash_command(description="Add a role to a member")
450
async def addrole(
451
interaction: nextcord.Interaction,
452
member: nextcord.Member = nextcord.SlashOption(description="Member to add role to"),
453
role: nextcord.Role = nextcord.SlashOption(description="Role to add")
454
):
455
"""Add a role to a member."""
456
try:
457
# Check if user has permission to manage roles
458
if not interaction.user.guild_permissions.manage_roles:
459
await interaction.response.send_message(
460
"β You don't have permission to manage roles.",
461
ephemeral=True
462
)
463
return
464
465
# Check if role is already assigned
466
if role in member.roles:
467
await interaction.response.send_message(
468
f"β {member.mention} already has the {role.mention} role.",
469
ephemeral=True
470
)
471
return
472
473
# Check role hierarchy
474
if role.position >= interaction.user.top_role.position:
475
await interaction.response.send_message(
476
f"β You cannot assign the {role.mention} role (higher than your top role).",
477
ephemeral=True
478
)
479
return
480
481
# Add the role
482
await member.add_roles(role, reason=f"Added by {interaction.user}")
483
484
await interaction.response.send_message(
485
f"β Added {role.mention} to {member.mention}.",
486
ephemeral=True
487
)
488
489
except nextcord.Forbidden:
490
await interaction.response.send_message(
491
"β I don't have permission to manage roles.",
492
ephemeral=True
493
)
494
except nextcord.HTTPException as e:
495
await interaction.response.send_message(
496
f"β Failed to add role: {e}",
497
ephemeral=True
498
)
499
500
@bot.slash_command(description="Remove a role from a member")
501
async def removerole(
502
interaction: nextcord.Interaction,
503
member: nextcord.Member = nextcord.SlashOption(description="Member to remove role from"),
504
role: nextcord.Role = nextcord.SlashOption(description="Role to remove")
505
):
506
"""Remove a role from a member."""
507
try:
508
if not interaction.user.guild_permissions.manage_roles:
509
await interaction.response.send_message(
510
"β You don't have permission to manage roles.",
511
ephemeral=True
512
)
513
return
514
515
if role not in member.roles:
516
await interaction.response.send_message(
517
f"β {member.mention} doesn't have the {role.mention} role.",
518
ephemeral=True
519
)
520
return
521
522
if role.position >= interaction.user.top_role.position:
523
await interaction.response.send_message(
524
f"β You cannot remove the {role.mention} role (higher than your top role).",
525
ephemeral=True
526
)
527
return
528
529
await member.remove_roles(role, reason=f"Removed by {interaction.user}")
530
531
await interaction.response.send_message(
532
f"β Removed {role.mention} from {member.mention}.",
533
ephemeral=True
534
)
535
536
except nextcord.Forbidden:
537
await interaction.response.send_message(
538
"β I don't have permission to manage roles.",
539
ephemeral=True
540
)
541
except nextcord.HTTPException as e:
542
await interaction.response.send_message(
543
f"β Failed to remove role: {e}",
544
ephemeral=True
545
)
546
547
# Bulk role management
548
@bot.slash_command(description="Mass assign role to members")
549
async def massrole(
550
interaction: nextcord.Interaction,
551
role: nextcord.Role = nextcord.SlashOption(description="Role to assign"),
552
filter_by: str = nextcord.SlashOption(
553
description="Filter criteria",
554
choices=["all", "humans", "bots", "no_roles"]
555
)
556
):
557
"""Mass assign a role to members based on criteria."""
558
if not interaction.user.guild_permissions.manage_roles:
559
await interaction.response.send_message(
560
"β You don't have permission to manage roles.",
561
ephemeral=True
562
)
563
return
564
565
# Defer response as this might take time
566
await interaction.response.defer(ephemeral=True)
567
568
members_to_add = []
569
570
for member in interaction.guild.members:
571
# Skip if member already has the role
572
if role in member.roles:
573
continue
574
575
# Apply filter
576
if filter_by == "humans" and member.bot:
577
continue
578
elif filter_by == "bots" and not member.bot:
579
continue
580
elif filter_by == "no_roles" and len(member.roles) > 1: # More than @everyone
581
continue
582
583
members_to_add.append(member)
584
585
if not members_to_add:
586
await interaction.followup.send("No members found matching the criteria.")
587
return
588
589
# Add role to members (with rate limiting consideration)
590
added_count = 0
591
failed_count = 0
592
593
for member in members_to_add:
594
try:
595
await member.add_roles(role, reason=f"Mass role assignment by {interaction.user}")
596
added_count += 1
597
except (nextcord.Forbidden, nextcord.HTTPException):
598
failed_count += 1
599
600
# Simple rate limiting
601
if added_count % 10 == 0:
602
await asyncio.sleep(1)
603
604
await interaction.followup.send(
605
f"β Mass role assignment complete!\n"
606
f"Added {role.mention} to {added_count} members.\n" +
607
(f"Failed to add to {failed_count} members." if failed_count > 0 else "")
608
)
609
```
610
611
### Member Moderation { .api }
612
613
```python
614
# Moderation methods
615
class Member:
616
async def ban(
617
self,
618
*,
619
delete_message_days: int = 1,
620
reason: Optional[str] = None
621
) -> None:
622
"""Ban the member from the guild.
623
624
Parameters
625
----------
626
delete_message_days: int
627
Number of days worth of messages to delete (0-7).
628
reason: Optional[str]
629
The reason for the ban.
630
"""
631
...
632
633
async def unban(
634
self,
635
*,
636
reason: Optional[str] = None
637
) -> None:
638
"""Unban the member from the guild.
639
640
Parameters
641
----------
642
reason: Optional[str]
643
The reason for the unban.
644
"""
645
...
646
647
async def kick(self, *, reason: Optional[str] = None) -> None:
648
"""Kick the member from the guild.
649
650
Parameters
651
----------
652
reason: Optional[str]
653
The reason for the kick.
654
"""
655
...
656
657
async def move_to(
658
self,
659
channel: Optional[nextcord.abc.Snowflake],
660
*,
661
reason: Optional[str] = None
662
) -> None:
663
"""Move the member to a different voice channel.
664
665
Parameters
666
----------
667
channel: Optional[nextcord.abc.Snowflake]
668
The channel to move to. None to disconnect from voice.
669
reason: Optional[str]
670
The reason for moving the member.
671
"""
672
...
673
674
# Moderation command examples
675
@bot.slash_command(description="Timeout a member")
676
async def timeout(
677
interaction: nextcord.Interaction,
678
member: nextcord.Member = nextcord.SlashOption(description="Member to timeout"),
679
duration: int = nextcord.SlashOption(
680
description="Duration in minutes",
681
min_value=1,
682
max_value=40320 # 4 weeks max
683
),
684
reason: Optional[str] = nextcord.SlashOption(description="Reason for timeout", default=None)
685
):
686
"""Timeout a member for a specified duration."""
687
# Permission check
688
if not interaction.user.guild_permissions.moderate_members:
689
await interaction.response.send_message(
690
"β You don't have permission to timeout members.",
691
ephemeral=True
692
)
693
return
694
695
# Hierarchy check
696
if member.top_role.position >= interaction.user.top_role.position and interaction.user != interaction.guild.owner:
697
await interaction.response.send_message(
698
"β You cannot timeout this member (same or higher role).",
699
ephemeral=True
700
)
701
return
702
703
# Calculate timeout end time
704
from datetime import datetime, timedelta
705
until = datetime.utcnow() + timedelta(minutes=duration)
706
707
try:
708
await member.timeout(until=until, reason=reason or f"Timed out by {interaction.user}")
709
710
embed = nextcord.Embed(
711
title="Member Timed Out",
712
description=f"{member.mention} has been timed out for {duration} minutes.",
713
color=nextcord.Color.orange()
714
)
715
716
embed.add_field(name="Duration", value=f"{duration} minutes", inline=True)
717
embed.add_field(name="Until", value=until.strftime("%Y-%m-%d %H:%M UTC"), inline=True)
718
719
if reason:
720
embed.add_field(name="Reason", value=reason, inline=False)
721
722
embed.set_footer(text=f"Actioned by {interaction.user}", icon_url=interaction.user.display_avatar.url)
723
724
await interaction.response.send_message(embed=embed)
725
726
except nextcord.Forbidden:
727
await interaction.response.send_message(
728
"β I don't have permission to timeout this member.",
729
ephemeral=True
730
)
731
except nextcord.HTTPException as e:
732
await interaction.response.send_message(
733
f"β Failed to timeout member: {e}",
734
ephemeral=True
735
)
736
737
@bot.slash_command(description="Remove timeout from a member")
738
async def untimeout(
739
interaction: nextcord.Interaction,
740
member: nextcord.Member = nextcord.SlashOption(description="Member to remove timeout from"),
741
reason: Optional[str] = nextcord.SlashOption(description="Reason", default=None)
742
):
743
"""Remove timeout from a member."""
744
if not interaction.user.guild_permissions.moderate_members:
745
await interaction.response.send_message(
746
"β You don't have permission to manage timeouts.",
747
ephemeral=True
748
)
749
return
750
751
if not member.timed_out_until:
752
await interaction.response.send_message(
753
f"β {member.mention} is not currently timed out.",
754
ephemeral=True
755
)
756
return
757
758
try:
759
await member.timeout(until=None, reason=reason or f"Timeout removed by {interaction.user}")
760
761
embed = nextcord.Embed(
762
title="Timeout Removed",
763
description=f"Timeout has been removed from {member.mention}.",
764
color=nextcord.Color.green()
765
)
766
767
if reason:
768
embed.add_field(name="Reason", value=reason, inline=False)
769
770
embed.set_footer(text=f"Actioned by {interaction.user}", icon_url=interaction.user.display_avatar.url)
771
772
await interaction.response.send_message(embed=embed)
773
774
except nextcord.Forbidden:
775
await interaction.response.send_message(
776
"β I don't have permission to remove timeout from this member.",
777
ephemeral=True
778
)
779
except nextcord.HTTPException as e:
780
await interaction.response.send_message(
781
f"β Failed to remove timeout: {e}",
782
ephemeral=True
783
)
784
785
@bot.slash_command(description="Kick a member from the server")
786
async def kick(
787
interaction: nextcord.Interaction,
788
member: nextcord.Member = nextcord.SlashOption(description="Member to kick"),
789
reason: Optional[str] = nextcord.SlashOption(description="Reason for kick", default=None)
790
):
791
"""Kick a member from the server."""
792
if not interaction.user.guild_permissions.kick_members:
793
await interaction.response.send_message(
794
"β You don't have permission to kick members.",
795
ephemeral=True
796
)
797
return
798
799
if member.top_role.position >= interaction.user.top_role.position and interaction.user != interaction.guild.owner:
800
await interaction.response.send_message(
801
"β You cannot kick this member (same or higher role).",
802
ephemeral=True
803
)
804
return
805
806
# Try to send DM before kicking
807
try:
808
dm_embed = nextcord.Embed(
809
title=f"Kicked from {interaction.guild.name}",
810
description=f"You have been kicked from {interaction.guild.name}.",
811
color=nextcord.Color.red()
812
)
813
if reason:
814
dm_embed.add_field(name="Reason", value=reason, inline=False)
815
816
await member.send(embed=dm_embed)
817
except nextcord.Forbidden:
818
pass # User has DMs disabled
819
820
try:
821
await member.kick(reason=reason or f"Kicked by {interaction.user}")
822
823
embed = nextcord.Embed(
824
title="Member Kicked",
825
description=f"{member} has been kicked from the server.",
826
color=nextcord.Color.red()
827
)
828
829
if reason:
830
embed.add_field(name="Reason", value=reason, inline=False)
831
832
embed.set_footer(text=f"Actioned by {interaction.user}", icon_url=interaction.user.display_avatar.url)
833
834
await interaction.response.send_message(embed=embed)
835
836
except nextcord.Forbidden:
837
await interaction.response.send_message(
838
"β I don't have permission to kick this member.",
839
ephemeral=True
840
)
841
except nextcord.HTTPException as e:
842
await interaction.response.send_message(
843
f"β Failed to kick member: {e}",
844
ephemeral=True
845
)
846
```
847
848
## Voice State
849
850
Voice channel state tracking for members in voice channels.
851
852
### VoiceState Class { .api }
853
854
```python
855
class VoiceState:
856
"""Represents a member's voice state in a guild.
857
858
Attributes
859
----------
860
deaf: bool
861
Whether the member is server deafened.
862
mute: bool
863
Whether the member is server muted.
864
self_deaf: bool
865
Whether the member is self-deafened.
866
self_mute: bool
867
Whether the member is self-muted.
868
self_stream: bool
869
Whether the member is streaming using "Go Live".
870
self_video: bool
871
Whether the member has their camera enabled.
872
suppress: bool
873
Whether the member is suppressed (stage channels).
874
afk: bool
875
Whether the member is AFK.
876
channel: Optional[VoiceChannel]
877
The voice channel the member is connected to.
878
requested_to_speak_at: Optional[datetime.datetime]
879
When the member requested to speak (stage channels).
880
"""
881
882
@property
883
def member(self) -> Optional[Member]:
884
"""Optional[Member]: The member this voice state belongs to."""
885
...
886
887
# Voice state event handling
888
@bot.event
889
async def on_voice_state_update(member: nextcord.Member, before: nextcord.VoiceState, after: nextcord.VoiceState):
890
"""Handle voice state updates."""
891
892
# Member joined a voice channel
893
if before.channel is None and after.channel is not None:
894
print(f"{member.display_name} joined {after.channel.name}")
895
896
# Log to a specific channel
897
log_channel = nextcord.utils.get(member.guild.channels, name="voice-logs")
898
if log_channel:
899
embed = nextcord.Embed(
900
title="Voice Channel Joined",
901
description=f"{member.mention} joined {after.channel.mention}",
902
color=nextcord.Color.green()
903
)
904
await log_channel.send(embed=embed)
905
906
# Member left a voice channel
907
elif before.channel is not None and after.channel is None:
908
print(f"{member.display_name} left {before.channel.name}")
909
910
log_channel = nextcord.utils.get(member.guild.channels, name="voice-logs")
911
if log_channel:
912
embed = nextcord.Embed(
913
title="Voice Channel Left",
914
description=f"{member.mention} left {before.channel.mention}",
915
color=nextcord.Color.red()
916
)
917
await log_channel.send(embed=embed)
918
919
# Member switched voice channels
920
elif before.channel != after.channel:
921
print(f"{member.display_name} moved from {before.channel.name} to {after.channel.name}")
922
923
log_channel = nextcord.utils.get(member.guild.channels, name="voice-logs")
924
if log_channel:
925
embed = nextcord.Embed(
926
title="Voice Channel Switched",
927
description=f"{member.mention} moved from {before.channel.mention} to {after.channel.mention}",
928
color=nextcord.Color.blue()
929
)
930
await log_channel.send(embed=embed)
931
932
# Member mute status changed
933
if before.self_mute != after.self_mute:
934
status = "muted" if after.self_mute else "unmuted"
935
print(f"{member.display_name} {status} themselves")
936
937
# Member deaf status changed
938
if before.self_deaf != after.self_deaf:
939
status = "deafened" if after.self_deaf else "undeafened"
940
print(f"{member.display_name} {status} themselves")
941
942
# Voice moderation commands
943
@bot.slash_command(description="Move a member to a different voice channel")
944
async def movemember(
945
interaction: nextcord.Interaction,
946
member: nextcord.Member = nextcord.SlashOption(description="Member to move"),
947
channel: nextcord.VoiceChannel = nextcord.SlashOption(description="Channel to move to")
948
):
949
"""Move a member to a different voice channel."""
950
if not interaction.user.guild_permissions.move_members:
951
await interaction.response.send_message(
952
"β You don't have permission to move members.",
953
ephemeral=True
954
)
955
return
956
957
if not member.voice or not member.voice.channel:
958
await interaction.response.send_message(
959
f"β {member.mention} is not in a voice channel.",
960
ephemeral=True
961
)
962
return
963
964
try:
965
await member.move_to(channel, reason=f"Moved by {interaction.user}")
966
await interaction.response.send_message(
967
f"β Moved {member.mention} to {channel.mention}.",
968
ephemeral=True
969
)
970
except nextcord.Forbidden:
971
await interaction.response.send_message(
972
"β I don't have permission to move this member.",
973
ephemeral=True
974
)
975
except nextcord.HTTPException as e:
976
await interaction.response.send_message(
977
f"β Failed to move member: {e}",
978
ephemeral=True
979
)
980
981
@bot.slash_command(description="Disconnect a member from voice")
982
async def disconnect(
983
interaction: nextcord.Interaction,
984
member: nextcord.Member = nextcord.SlashOption(description="Member to disconnect")
985
):
986
"""Disconnect a member from their voice channel."""
987
if not interaction.user.guild_permissions.move_members:
988
await interaction.response.send_message(
989
"β You don't have permission to disconnect members.",
990
ephemeral=True
991
)
992
return
993
994
if not member.voice or not member.voice.channel:
995
await interaction.response.send_message(
996
f"β {member.mention} is not in a voice channel.",
997
ephemeral=True
998
)
999
return
1000
1001
try:
1002
await member.move_to(None, reason=f"Disconnected by {interaction.user}")
1003
await interaction.response.send_message(
1004
f"β Disconnected {member.mention} from voice.",
1005
ephemeral=True
1006
)
1007
except nextcord.Forbidden:
1008
await interaction.response.send_message(
1009
"β I don't have permission to disconnect this member.",
1010
ephemeral=True
1011
)
1012
except nextcord.HTTPException as e:
1013
await interaction.response.send_message(
1014
f"β Failed to disconnect member: {e}",
1015
ephemeral=True
1016
)
1017
```
1018
1019
## Client User
1020
1021
The bot's own user representation with additional capabilities.
1022
1023
### ClientUser Class { .api }
1024
1025
```python
1026
class ClientUser(User):
1027
"""Represents the client user (the bot itself).
1028
1029
This is a special subclass of User that represents the bot's
1030
own account with additional methods for managing the bot's presence.
1031
1032
Attributes
1033
----------
1034
email: Optional[str]
1035
The bot's email (None for bot accounts).
1036
locale: Optional[str]
1037
The bot's locale.
1038
mfa_enabled: bool
1039
Whether the bot has MFA enabled.
1040
verified: bool
1041
Whether the bot's email is verified.
1042
"""
1043
1044
async def edit(
1045
self,
1046
*,
1047
username: str = MISSING,
1048
avatar: Optional[bytes] = MISSING
1049
) -> ClientUser:
1050
"""Edit the client user's profile.
1051
1052
Parameters
1053
----------
1054
username: str
1055
The new username for the bot.
1056
avatar: Optional[bytes]
1057
The new avatar as bytes. None to remove avatar.
1058
1059
Returns
1060
-------
1061
ClientUser
1062
The updated client user.
1063
"""
1064
...
1065
1066
# Bot profile management
1067
@bot.slash_command(description="Change bot avatar")
1068
async def change_avatar(interaction: nextcord.Interaction):
1069
"""Change the bot's avatar (owner only)."""
1070
if interaction.user.id != bot.owner_id:
1071
await interaction.response.send_message(
1072
"β Only the bot owner can use this command.",
1073
ephemeral=True
1074
)
1075
return
1076
1077
# This would typically involve uploading a file
1078
# For this example, we'll just show the concept
1079
await interaction.response.send_message(
1080
"To change the bot avatar, use the `edit()` method with avatar bytes.",
1081
ephemeral=True
1082
)
1083
1084
# Example of changing bot presence
1085
@bot.event
1086
async def on_ready():
1087
"""Set initial bot presence when ready."""
1088
activity = nextcord.Activity(
1089
type=nextcord.ActivityType.watching,
1090
name=f"{len(bot.guilds)} servers"
1091
)
1092
await bot.change_presence(status=nextcord.Status.online, activity=activity)
1093
print(f'{bot.user} is ready!')
1094
1095
@bot.slash_command(description="Change bot status")
1096
async def setstatus(
1097
interaction: nextcord.Interaction,
1098
activity_type: str = nextcord.SlashOption(
1099
description="Type of activity",
1100
choices=["playing", "watching", "listening", "competing"]
1101
),
1102
message: str = nextcord.SlashOption(description="Status message")
1103
):
1104
"""Change the bot's status (owner only)."""
1105
if interaction.user.id != bot.owner_id:
1106
await interaction.response.send_message(
1107
"β Only the bot owner can use this command.",
1108
ephemeral=True
1109
)
1110
return
1111
1112
activity_types = {
1113
"playing": nextcord.ActivityType.playing,
1114
"watching": nextcord.ActivityType.watching,
1115
"listening": nextcord.ActivityType.listening,
1116
"competing": nextcord.ActivityType.competing
1117
}
1118
1119
activity = nextcord.Activity(
1120
type=activity_types[activity_type],
1121
name=message
1122
)
1123
1124
await bot.change_presence(activity=activity)
1125
1126
await interaction.response.send_message(
1127
f"β Changed status to **{activity_type.title()}** {message}",
1128
ephemeral=True
1129
)
1130
```
1131
1132
This comprehensive documentation covers all aspects of nextcord's user and member management system, providing developers with the tools needed to effectively work with Discord users in their bots.