CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-nextcord

A Python wrapper for the Discord API forked from discord.py

Pending
Overview
Eval results
Files

users.mddocs/

Nextcord Users and Members

User representation, member management, permission handling, and voice state tracking for comprehensive user operations in Discord servers.

User Class

Basic Discord user representation with account information and direct messaging capabilities.

User Attributes and Methods { .api }

import nextcord
from nextcord.abc import Messageable, Snowflake
from datetime import datetime
from typing import Optional, Union, List

class User(Snowflake, Messageable):
    """Represents a Discord user.
    
    This is the base class for all user-like objects in Discord.
    
    Attributes
    ----------
    id: int
        The user's unique ID.
    name: str
        The user's username, not including the discriminator.
    discriminator: str
        The user's discriminator (4-digit number).
    global_name: Optional[str]
        The user's global display name, if they have one.
    avatar: Optional[Asset]
        The user's avatar asset. None if they have no avatar.
    bot: bool
        Whether the user is a bot account.
    system: bool
        Whether the user is a system user (Discord Official).
    created_at: datetime.datetime
        When the user account was created.
    default_avatar: Asset
        The default avatar for the user.
    display_avatar: Asset
        The "display" avatar for the user (avatar or default avatar).
    mention: str
        A string that allows you to mention the user.
    """
    
    @property
    def display_name(self) -> str:
        """str: The user's display name (global_name if available, otherwise username)."""
        ...
    
    def mentioned_in(self, message: nextcord.Message) -> bool:
        """bool: Whether the user is mentioned in the given message.
        
        Parameters
        ----------
        message: nextcord.Message
            The message to check for mentions.
        
        Returns
        -------
        bool
            True if the user is mentioned in the message.
        """
        ...
    
    async def create_dm(self) -> nextcord.DMChannel:
        """Create a direct message channel with this user.
        
        Returns
        -------
        nextcord.DMChannel
            The DM channel created with this user.
        """
        ...
    
    def dm_channel(self) -> Optional[nextcord.DMChannel]:
        """Optional[nextcord.DMChannel]: The DM channel associated with this user, if any."""
        ...
    
    def avatar_url_as(
        self, 
        *, 
        format: Optional[str] = None, 
        static_format: str = 'webp', 
        size: int = 1024
    ) -> str:
        """Get the user's avatar URL in a specific format.
        
        Parameters
        ----------
        format: Optional[str]
            The format to get the avatar in. If None, uses GIF for animated avatars.
        static_format: str
            The format to use for static avatars. Defaults to 'webp'.
        size: int
            The size of the avatar to get. Must be a power of 2 between 16 and 4096.
        
        Returns
        -------
        str
            The avatar URL.
        """
        ...
    
    def is_avatar_animated(self) -> bool:
        """bool: Whether the user's avatar is animated (GIF)."""
        ...

# Basic user operations
@bot.event
async def on_message(message):
    """Example of working with user objects."""
    user = message.author
    
    # Get user information
    print(f"Username: {user.name}#{user.discriminator}")
    print(f"Display name: {user.display_name}")
    print(f"User ID: {user.id}")
    print(f"Is bot: {user.bot}")
    print(f"Account created: {user.created_at}")
    
    # Send DM to user
    if not user.bot:
        try:
            await user.send("Hello! This is a direct message.")
        except nextcord.Forbidden:
            print(f"Cannot send DM to {user.display_name} - DMs disabled")

@bot.slash_command(description="Get user information")
async def userinfo(
    interaction: nextcord.Interaction,
    user: Optional[nextcord.User] = nextcord.SlashOption(
        description="The user to get information about",
        default=None
    )
):
    """Get information about a user."""
    target = user or interaction.user
    
    embed = nextcord.Embed(
        title=f"User Information: {target.display_name}",
        color=nextcord.Color.blue()
    )
    
    embed.set_thumbnail(url=target.display_avatar.url)
    
    embed.add_field(name="Username", value=f"{target.name}#{target.discriminator}", inline=True)
    embed.add_field(name="User ID", value=target.id, inline=True)
    embed.add_field(name="Bot Account", value="Yes" if target.bot else "No", inline=True)
    
    embed.add_field(
        name="Account Created",
        value=target.created_at.strftime("%B %d, %Y at %H:%M UTC"),
        inline=False
    )
    
    if target.global_name:
        embed.add_field(name="Global Display Name", value=target.global_name, inline=True)
    
    await interaction.response.send_message(embed=embed)

Member Class

Guild-specific user representation with roles, permissions, and server-specific attributes.

Member Attributes and Properties { .api }

class Member(User):
    """Represents a Discord member (user in a guild).
    
    A member is a user with additional guild-specific information like roles,
    nickname, join date, and permissions.
    
    Attributes
    ----------
    guild: Guild
        The guild this member belongs to.
    nick: Optional[str]
        The member's nickname in the guild, if any.
    joined_at: Optional[datetime.datetime]
        When the member joined the guild.
    premium_since: Optional[datetime.datetime]
        When the member started boosting the guild.
    pending: bool
        Whether the member has passed the guild's membership screening.
    timed_out_until: Optional[datetime.datetime]
        When the member's timeout expires, if they are timed out.
    roles: List[Role]
        A list of roles the member has.
    activities: List[BaseActivity]
        The member's current activities.
    status: Status
        The member's overall status.
    mobile_status: Status
        The member's mobile status.
    desktop_status: Status
        The member's desktop status.
    web_status: Status
        The member's web status.
    voice: Optional[VoiceState]
        The member's voice state, if they are in a voice channel.
    """
    
    @property
    def display_name(self) -> str:
        """str: The member's display name (nickname if available, otherwise username)."""
        ...
    
    @property
    def colour(self) -> nextcord.Colour:
        """nextcord.Colour: The member's color based on their highest role."""
        ...
    
    @property
    def color(self) -> nextcord.Colour:
        """nextcord.Colour: An alias for colour."""
        ...
    
    @property
    def top_role(self) -> Role:
        """Role: The member's highest role."""
        ...
    
    @property
    def guild_permissions(self) -> Permissions:
        """Permissions: The member's resolved permissions in the guild."""
        ...
    
    def permissions_in(self, channel: nextcord.abc.GuildChannel) -> Permissions:
        """Calculate the member's permissions in a specific channel.
        
        Parameters
        ----------
        channel: nextcord.abc.GuildChannel
            The channel to calculate permissions for.
        
        Returns
        -------
        Permissions
            The member's permissions in the channel.
        """
        ...
    
    def get_role(self, role_id: int) -> Optional[Role]:
        """Get a role the member has by its ID.
        
        Parameters
        ----------
        role_id: int
            The ID of the role to get.
        
        Returns
        -------
        Optional[Role]
            The role if found, None otherwise.
        """
        ...

# Member information example
@bot.slash_command(description="Get detailed member information")
async def memberinfo(
    interaction: nextcord.Interaction,
    member: Optional[nextcord.Member] = nextcord.SlashOption(
        description="The member to get information about",
        default=None
    )
):
    """Get detailed information about a guild member."""
    target = member or interaction.user
    
    embed = nextcord.Embed(
        title=f"Member Information: {target.display_name}",
        color=target.color or nextcord.Color.blue()
    )
    
    embed.set_thumbnail(url=target.display_avatar.url)
    
    # Basic info
    embed.add_field(name="Username", value=f"{target.name}#{target.discriminator}", inline=True)
    embed.add_field(name="User ID", value=target.id, inline=True)
    embed.add_field(name="Bot", value="Yes" if target.bot else "No", inline=True)
    
    # Nickname
    if target.nick:
        embed.add_field(name="Nickname", value=target.nick, inline=True)
    
    # Join information
    if target.joined_at:
        embed.add_field(
            name="Joined Server",
            value=target.joined_at.strftime("%B %d, %Y at %H:%M UTC"),
            inline=False
        )
    
    embed.add_field(
        name="Account Created",
        value=target.created_at.strftime("%B %d, %Y at %H:%M UTC"),
        inline=False
    )
    
    # Premium information
    if target.premium_since:
        embed.add_field(
            name="Boosting Since",
            value=target.premium_since.strftime("%B %d, %Y at %H:%M UTC"),
            inline=True
        )
    
    # Timeout information
    if target.timed_out_until:
        embed.add_field(
            name="Timed Out Until",
            value=target.timed_out_until.strftime("%B %d, %Y at %H:%M UTC"),
            inline=True
        )
    
    # Roles (limit to prevent embed overflow)
    if target.roles[1:]:  # Skip @everyone
        roles = [role.mention for role in target.roles[1:][:10]]
        role_text = ", ".join(roles)
        if len(target.roles) > 11:
            role_text += f" and {len(target.roles) - 11} more..."
        embed.add_field(name="Roles", value=role_text, inline=False)
    
    # Status and activity
    status_emoji = {
        nextcord.Status.online: "🟢",
        nextcord.Status.idle: "🟡", 
        nextcord.Status.dnd: "🔴",
        nextcord.Status.offline: "⚫"
    }
    embed.add_field(
        name="Status",
        value=f"{status_emoji.get(target.status, '❓')} {target.status.name.title()}",
        inline=True
    )
    
    # Voice status
    if target.voice:
        voice_info = f"🔊 {target.voice.channel.mention}"
        if target.voice.self_mute:
            voice_info += " (Muted)"
        if target.voice.self_deaf:
            voice_info += " (Deafened)"
        embed.add_field(name="Voice Channel", value=voice_info, inline=True)
    
    await interaction.response.send_message(embed=embed)

Member Role Management { .api }

# Role management methods
class Member:
    async def add_roles(
        self, 
        *roles: Snowflake,
        reason: Optional[str] = None,
        atomic: bool = True
    ) -> None:
        """Add roles to the member.
        
        Parameters
        ----------
        *roles: Snowflake
            The roles to add to the member.
        reason: Optional[str]
            The reason for adding the roles.
        atomic: bool
            Whether to atomically add all roles or add them individually.
        """
        ...
    
    async def remove_roles(
        self,
        *roles: Snowflake,
        reason: Optional[str] = None,
        atomic: bool = True
    ) -> None:
        """Remove roles from the member.
        
        Parameters
        ----------
        *roles: Snowflake
            The roles to remove from the member.
        reason: Optional[str]
            The reason for removing the roles.
        atomic: bool
            Whether to atomically remove all roles or remove them individually.
        """
        ...
    
    async def edit(
        self,
        *,
        nick: Optional[str] = MISSING,
        roles: Optional[List[Role]] = MISSING,
        mute: Optional[bool] = MISSING,
        deafen: Optional[bool] = MISSING,
        suppress: Optional[bool] = MISSING,
        reason: Optional[str] = None,
        timed_out_until: Optional[datetime.datetime] = MISSING,
        voice_channel: Optional[nextcord.abc.Snowflake] = MISSING,
    ) -> Optional[Member]:
        """Edit the member's attributes.
        
        Parameters
        ----------
        nick: Optional[str]
            The member's new nickname. None to remove nickname.
        roles: Optional[List[Role]]
            The member's new list of roles.
        mute: Optional[bool]
            Whether to mute the member in voice channels.
        deafen: Optional[bool]
            Whether to deafen the member in voice channels.
        suppress: Optional[bool]
            Whether to suppress the member (stage channels).
        reason: Optional[str]
            The reason for editing the member.
        timed_out_until: Optional[datetime.datetime]
            When the member's timeout should expire.
        voice_channel: Optional[nextcord.abc.Snowflake]
            The voice channel to move the member to.
        """
        ...
    
    async def timeout(
        self,
        until: Optional[datetime.datetime],
        *,
        reason: Optional[str] = None
    ) -> None:
        """Timeout the member until a specific time.
        
        Parameters
        ----------
        until: Optional[datetime.datetime]
            When the timeout should expire. None to remove timeout.
        reason: Optional[str]
            The reason for the timeout.
        """
        ...

# Role management examples
@bot.slash_command(description="Add a role to a member")
async def addrole(
    interaction: nextcord.Interaction,
    member: nextcord.Member = nextcord.SlashOption(description="Member to add role to"),
    role: nextcord.Role = nextcord.SlashOption(description="Role to add")
):
    """Add a role to a member."""
    try:
        # Check if user has permission to manage roles
        if not interaction.user.guild_permissions.manage_roles:
            await interaction.response.send_message(
                "❌ You don't have permission to manage roles.",
                ephemeral=True
            )
            return
        
        # Check if role is already assigned
        if role in member.roles:
            await interaction.response.send_message(
                f"❌ {member.mention} already has the {role.mention} role.",
                ephemeral=True
            )
            return
        
        # Check role hierarchy
        if role.position >= interaction.user.top_role.position:
            await interaction.response.send_message(
                f"❌ You cannot assign the {role.mention} role (higher than your top role).",
                ephemeral=True
            )
            return
        
        # Add the role
        await member.add_roles(role, reason=f"Added by {interaction.user}")
        
        await interaction.response.send_message(
            f"✅ Added {role.mention} to {member.mention}.",
            ephemeral=True
        )
        
    except nextcord.Forbidden:
        await interaction.response.send_message(
            "❌ I don't have permission to manage roles.",
            ephemeral=True
        )
    except nextcord.HTTPException as e:
        await interaction.response.send_message(
            f"❌ Failed to add role: {e}",
            ephemeral=True
        )

@bot.slash_command(description="Remove a role from a member")
async def removerole(
    interaction: nextcord.Interaction,
    member: nextcord.Member = nextcord.SlashOption(description="Member to remove role from"),
    role: nextcord.Role = nextcord.SlashOption(description="Role to remove")
):
    """Remove a role from a member."""
    try:
        if not interaction.user.guild_permissions.manage_roles:
            await interaction.response.send_message(
                "❌ You don't have permission to manage roles.",
                ephemeral=True
            )
            return
        
        if role not in member.roles:
            await interaction.response.send_message(
                f"❌ {member.mention} doesn't have the {role.mention} role.",
                ephemeral=True
            )
            return
        
        if role.position >= interaction.user.top_role.position:
            await interaction.response.send_message(
                f"❌ You cannot remove the {role.mention} role (higher than your top role).",
                ephemeral=True
            )
            return
        
        await member.remove_roles(role, reason=f"Removed by {interaction.user}")
        
        await interaction.response.send_message(
            f"✅ Removed {role.mention} from {member.mention}.",
            ephemeral=True
        )
        
    except nextcord.Forbidden:
        await interaction.response.send_message(
            "❌ I don't have permission to manage roles.",
            ephemeral=True
        )
    except nextcord.HTTPException as e:
        await interaction.response.send_message(
            f"❌ Failed to remove role: {e}",
            ephemeral=True
        )

# Bulk role management
@bot.slash_command(description="Mass assign role to members")
async def massrole(
    interaction: nextcord.Interaction,
    role: nextcord.Role = nextcord.SlashOption(description="Role to assign"),
    filter_by: str = nextcord.SlashOption(
        description="Filter criteria",
        choices=["all", "humans", "bots", "no_roles"]
    )
):
    """Mass assign a role to members based on criteria."""
    if not interaction.user.guild_permissions.manage_roles:
        await interaction.response.send_message(
            "❌ You don't have permission to manage roles.",
            ephemeral=True
        )
        return
    
    # Defer response as this might take time
    await interaction.response.defer(ephemeral=True)
    
    members_to_add = []
    
    for member in interaction.guild.members:
        # Skip if member already has the role
        if role in member.roles:
            continue
            
        # Apply filter
        if filter_by == "humans" and member.bot:
            continue
        elif filter_by == "bots" and not member.bot:
            continue
        elif filter_by == "no_roles" and len(member.roles) > 1:  # More than @everyone
            continue
        
        members_to_add.append(member)
    
    if not members_to_add:
        await interaction.followup.send("No members found matching the criteria.")
        return
    
    # Add role to members (with rate limiting consideration)
    added_count = 0
    failed_count = 0
    
    for member in members_to_add:
        try:
            await member.add_roles(role, reason=f"Mass role assignment by {interaction.user}")
            added_count += 1
        except (nextcord.Forbidden, nextcord.HTTPException):
            failed_count += 1
        
        # Simple rate limiting
        if added_count % 10 == 0:
            await asyncio.sleep(1)
    
    await interaction.followup.send(
        f"✅ Mass role assignment complete!\n"
        f"Added {role.mention} to {added_count} members.\n" +
        (f"Failed to add to {failed_count} members." if failed_count > 0 else "")
    )

Member Moderation { .api }

# Moderation methods
class Member:
    async def ban(
        self,
        *,
        delete_message_days: int = 1,
        reason: Optional[str] = None
    ) -> None:
        """Ban the member from the guild.
        
        Parameters
        ----------
        delete_message_days: int
            Number of days worth of messages to delete (0-7).
        reason: Optional[str]
            The reason for the ban.
        """
        ...
    
    async def unban(
        self,
        *,
        reason: Optional[str] = None
    ) -> None:
        """Unban the member from the guild.
        
        Parameters
        ----------
        reason: Optional[str]
            The reason for the unban.
        """
        ...
    
    async def kick(self, *, reason: Optional[str] = None) -> None:
        """Kick the member from the guild.
        
        Parameters
        ----------
        reason: Optional[str]
            The reason for the kick.
        """
        ...
    
    async def move_to(
        self,
        channel: Optional[nextcord.abc.Snowflake],
        *,
        reason: Optional[str] = None
    ) -> None:
        """Move the member to a different voice channel.
        
        Parameters
        ----------
        channel: Optional[nextcord.abc.Snowflake]
            The channel to move to. None to disconnect from voice.
        reason: Optional[str]
            The reason for moving the member.
        """
        ...

# Moderation command examples
@bot.slash_command(description="Timeout a member")
async def timeout(
    interaction: nextcord.Interaction,
    member: nextcord.Member = nextcord.SlashOption(description="Member to timeout"),
    duration: int = nextcord.SlashOption(
        description="Duration in minutes",
        min_value=1,
        max_value=40320  # 4 weeks max
    ),
    reason: Optional[str] = nextcord.SlashOption(description="Reason for timeout", default=None)
):
    """Timeout a member for a specified duration."""
    # Permission check
    if not interaction.user.guild_permissions.moderate_members:
        await interaction.response.send_message(
            "❌ You don't have permission to timeout members.",
            ephemeral=True
        )
        return
    
    # Hierarchy check
    if member.top_role.position >= interaction.user.top_role.position and interaction.user != interaction.guild.owner:
        await interaction.response.send_message(
            "❌ You cannot timeout this member (same or higher role).",
            ephemeral=True
        )
        return
    
    # Calculate timeout end time
    from datetime import datetime, timedelta
    until = datetime.utcnow() + timedelta(minutes=duration)
    
    try:
        await member.timeout(until=until, reason=reason or f"Timed out by {interaction.user}")
        
        embed = nextcord.Embed(
            title="Member Timed Out",
            description=f"{member.mention} has been timed out for {duration} minutes.",
            color=nextcord.Color.orange()
        )
        
        embed.add_field(name="Duration", value=f"{duration} minutes", inline=True)
        embed.add_field(name="Until", value=until.strftime("%Y-%m-%d %H:%M UTC"), inline=True)
        
        if reason:
            embed.add_field(name="Reason", value=reason, inline=False)
        
        embed.set_footer(text=f"Actioned by {interaction.user}", icon_url=interaction.user.display_avatar.url)
        
        await interaction.response.send_message(embed=embed)
        
    except nextcord.Forbidden:
        await interaction.response.send_message(
            "❌ I don't have permission to timeout this member.",
            ephemeral=True
        )
    except nextcord.HTTPException as e:
        await interaction.response.send_message(
            f"❌ Failed to timeout member: {e}",
            ephemeral=True
        )

@bot.slash_command(description="Remove timeout from a member")
async def untimeout(
    interaction: nextcord.Interaction,
    member: nextcord.Member = nextcord.SlashOption(description="Member to remove timeout from"),
    reason: Optional[str] = nextcord.SlashOption(description="Reason", default=None)
):
    """Remove timeout from a member."""
    if not interaction.user.guild_permissions.moderate_members:
        await interaction.response.send_message(
            "❌ You don't have permission to manage timeouts.",
            ephemeral=True
        )
        return
    
    if not member.timed_out_until:
        await interaction.response.send_message(
            f"❌ {member.mention} is not currently timed out.",
            ephemeral=True
        )
        return
    
    try:
        await member.timeout(until=None, reason=reason or f"Timeout removed by {interaction.user}")
        
        embed = nextcord.Embed(
            title="Timeout Removed",
            description=f"Timeout has been removed from {member.mention}.",
            color=nextcord.Color.green()
        )
        
        if reason:
            embed.add_field(name="Reason", value=reason, inline=False)
        
        embed.set_footer(text=f"Actioned by {interaction.user}", icon_url=interaction.user.display_avatar.url)
        
        await interaction.response.send_message(embed=embed)
        
    except nextcord.Forbidden:
        await interaction.response.send_message(
            "❌ I don't have permission to remove timeout from this member.",
            ephemeral=True
        )
    except nextcord.HTTPException as e:
        await interaction.response.send_message(
            f"❌ Failed to remove timeout: {e}",
            ephemeral=True
        )

@bot.slash_command(description="Kick a member from the server")
async def kick(
    interaction: nextcord.Interaction,
    member: nextcord.Member = nextcord.SlashOption(description="Member to kick"),
    reason: Optional[str] = nextcord.SlashOption(description="Reason for kick", default=None)
):
    """Kick a member from the server."""
    if not interaction.user.guild_permissions.kick_members:
        await interaction.response.send_message(
            "❌ You don't have permission to kick members.",
            ephemeral=True
        )
        return
    
    if member.top_role.position >= interaction.user.top_role.position and interaction.user != interaction.guild.owner:
        await interaction.response.send_message(
            "❌ You cannot kick this member (same or higher role).",
            ephemeral=True
        )
        return
    
    # Try to send DM before kicking
    try:
        dm_embed = nextcord.Embed(
            title=f"Kicked from {interaction.guild.name}",
            description=f"You have been kicked from {interaction.guild.name}.",
            color=nextcord.Color.red()
        )
        if reason:
            dm_embed.add_field(name="Reason", value=reason, inline=False)
        
        await member.send(embed=dm_embed)
    except nextcord.Forbidden:
        pass  # User has DMs disabled
    
    try:
        await member.kick(reason=reason or f"Kicked by {interaction.user}")
        
        embed = nextcord.Embed(
            title="Member Kicked",
            description=f"{member} has been kicked from the server.",
            color=nextcord.Color.red()
        )
        
        if reason:
            embed.add_field(name="Reason", value=reason, inline=False)
        
        embed.set_footer(text=f"Actioned by {interaction.user}", icon_url=interaction.user.display_avatar.url)
        
        await interaction.response.send_message(embed=embed)
        
    except nextcord.Forbidden:
        await interaction.response.send_message(
            "❌ I don't have permission to kick this member.",
            ephemeral=True
        )
    except nextcord.HTTPException as e:
        await interaction.response.send_message(
            f"❌ Failed to kick member: {e}",
            ephemeral=True
        )

Voice State

Voice channel state tracking for members in voice channels.

VoiceState Class { .api }

class VoiceState:
    """Represents a member's voice state in a guild.
    
    Attributes
    ----------
    deaf: bool
        Whether the member is server deafened.
    mute: bool
        Whether the member is server muted.
    self_deaf: bool
        Whether the member is self-deafened.
    self_mute: bool
        Whether the member is self-muted.
    self_stream: bool
        Whether the member is streaming using "Go Live".
    self_video: bool
        Whether the member has their camera enabled.
    suppress: bool
        Whether the member is suppressed (stage channels).
    afk: bool
        Whether the member is AFK.
    channel: Optional[VoiceChannel]
        The voice channel the member is connected to.
    requested_to_speak_at: Optional[datetime.datetime]
        When the member requested to speak (stage channels).
    """
    
    @property
    def member(self) -> Optional[Member]:
        """Optional[Member]: The member this voice state belongs to."""
        ...

# Voice state event handling
@bot.event
async def on_voice_state_update(member: nextcord.Member, before: nextcord.VoiceState, after: nextcord.VoiceState):
    """Handle voice state updates."""
    
    # Member joined a voice channel
    if before.channel is None and after.channel is not None:
        print(f"{member.display_name} joined {after.channel.name}")
        
        # Log to a specific channel
        log_channel = nextcord.utils.get(member.guild.channels, name="voice-logs")
        if log_channel:
            embed = nextcord.Embed(
                title="Voice Channel Joined",
                description=f"{member.mention} joined {after.channel.mention}",
                color=nextcord.Color.green()
            )
            await log_channel.send(embed=embed)
    
    # Member left a voice channel
    elif before.channel is not None and after.channel is None:
        print(f"{member.display_name} left {before.channel.name}")
        
        log_channel = nextcord.utils.get(member.guild.channels, name="voice-logs")
        if log_channel:
            embed = nextcord.Embed(
                title="Voice Channel Left",
                description=f"{member.mention} left {before.channel.mention}",
                color=nextcord.Color.red()
            )
            await log_channel.send(embed=embed)
    
    # Member switched voice channels
    elif before.channel != after.channel:
        print(f"{member.display_name} moved from {before.channel.name} to {after.channel.name}")
        
        log_channel = nextcord.utils.get(member.guild.channels, name="voice-logs")
        if log_channel:
            embed = nextcord.Embed(
                title="Voice Channel Switched",
                description=f"{member.mention} moved from {before.channel.mention} to {after.channel.mention}",
                color=nextcord.Color.blue()
            )
            await log_channel.send(embed=embed)
    
    # Member mute status changed
    if before.self_mute != after.self_mute:
        status = "muted" if after.self_mute else "unmuted"
        print(f"{member.display_name} {status} themselves")
    
    # Member deaf status changed
    if before.self_deaf != after.self_deaf:
        status = "deafened" if after.self_deaf else "undeafened"
        print(f"{member.display_name} {status} themselves")

# Voice moderation commands
@bot.slash_command(description="Move a member to a different voice channel")
async def movemember(
    interaction: nextcord.Interaction,
    member: nextcord.Member = nextcord.SlashOption(description="Member to move"),
    channel: nextcord.VoiceChannel = nextcord.SlashOption(description="Channel to move to")
):
    """Move a member to a different voice channel."""
    if not interaction.user.guild_permissions.move_members:
        await interaction.response.send_message(
            "❌ You don't have permission to move members.",
            ephemeral=True
        )
        return
    
    if not member.voice or not member.voice.channel:
        await interaction.response.send_message(
            f"❌ {member.mention} is not in a voice channel.",
            ephemeral=True
        )
        return
    
    try:
        await member.move_to(channel, reason=f"Moved by {interaction.user}")
        await interaction.response.send_message(
            f"✅ Moved {member.mention} to {channel.mention}.",
            ephemeral=True
        )
    except nextcord.Forbidden:
        await interaction.response.send_message(
            "❌ I don't have permission to move this member.",
            ephemeral=True
        )
    except nextcord.HTTPException as e:
        await interaction.response.send_message(
            f"❌ Failed to move member: {e}",
            ephemeral=True
        )

@bot.slash_command(description="Disconnect a member from voice")
async def disconnect(
    interaction: nextcord.Interaction,
    member: nextcord.Member = nextcord.SlashOption(description="Member to disconnect")
):
    """Disconnect a member from their voice channel."""
    if not interaction.user.guild_permissions.move_members:
        await interaction.response.send_message(
            "❌ You don't have permission to disconnect members.",
            ephemeral=True
        )
        return
    
    if not member.voice or not member.voice.channel:
        await interaction.response.send_message(
            f"❌ {member.mention} is not in a voice channel.",
            ephemeral=True
        )
        return
    
    try:
        await member.move_to(None, reason=f"Disconnected by {interaction.user}")
        await interaction.response.send_message(
            f"✅ Disconnected {member.mention} from voice.",
            ephemeral=True
        )
    except nextcord.Forbidden:
        await interaction.response.send_message(
            "❌ I don't have permission to disconnect this member.",
            ephemeral=True
        )
    except nextcord.HTTPException as e:
        await interaction.response.send_message(
            f"❌ Failed to disconnect member: {e}",
            ephemeral=True
        )

Client User

The bot's own user representation with additional capabilities.

ClientUser Class { .api }

class ClientUser(User):
    """Represents the client user (the bot itself).
    
    This is a special subclass of User that represents the bot's
    own account with additional methods for managing the bot's presence.
    
    Attributes
    ----------
    email: Optional[str]
        The bot's email (None for bot accounts).
    locale: Optional[str]
        The bot's locale.
    mfa_enabled: bool
        Whether the bot has MFA enabled.
    verified: bool
        Whether the bot's email is verified.
    """
    
    async def edit(
        self,
        *,
        username: str = MISSING,
        avatar: Optional[bytes] = MISSING
    ) -> ClientUser:
        """Edit the client user's profile.
        
        Parameters
        ----------
        username: str
            The new username for the bot.
        avatar: Optional[bytes]
            The new avatar as bytes. None to remove avatar.
        
        Returns
        -------
        ClientUser
            The updated client user.
        """
        ...

# Bot profile management
@bot.slash_command(description="Change bot avatar")
async def change_avatar(interaction: nextcord.Interaction):
    """Change the bot's avatar (owner only)."""
    if interaction.user.id != bot.owner_id:
        await interaction.response.send_message(
            "❌ Only the bot owner can use this command.",
            ephemeral=True
        )
        return
    
    # This would typically involve uploading a file
    # For this example, we'll just show the concept
    await interaction.response.send_message(
        "To change the bot avatar, use the `edit()` method with avatar bytes.",
        ephemeral=True
    )

# Example of changing bot presence
@bot.event
async def on_ready():
    """Set initial bot presence when ready."""
    activity = nextcord.Activity(
        type=nextcord.ActivityType.watching,
        name=f"{len(bot.guilds)} servers"
    )
    await bot.change_presence(status=nextcord.Status.online, activity=activity)
    print(f'{bot.user} is ready!')

@bot.slash_command(description="Change bot status")
async def setstatus(
    interaction: nextcord.Interaction,
    activity_type: str = nextcord.SlashOption(
        description="Type of activity",
        choices=["playing", "watching", "listening", "competing"]
    ),
    message: str = nextcord.SlashOption(description="Status message")
):
    """Change the bot's status (owner only)."""
    if interaction.user.id != bot.owner_id:
        await interaction.response.send_message(
            "❌ Only the bot owner can use this command.",
            ephemeral=True
        )
        return
    
    activity_types = {
        "playing": nextcord.ActivityType.playing,
        "watching": nextcord.ActivityType.watching,
        "listening": nextcord.ActivityType.listening,
        "competing": nextcord.ActivityType.competing
    }
    
    activity = nextcord.Activity(
        type=activity_types[activity_type],
        name=message
    )
    
    await bot.change_presence(activity=activity)
    
    await interaction.response.send_message(
        f"✅ Changed status to **{activity_type.title()}** {message}",
        ephemeral=True
    )

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.

Install with Tessl CLI

npx tessl i tessl/pypi-nextcord

docs

application-commands.md

channels.md

client.md

commands.md

errors.md

events.md

guild.md

index.md

messages.md

permissions.md

tasks.md

ui.md

users.md

utilities.md

voice.md

webhooks.md

tile.json