CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-discord-py

A modern, feature-rich, and async-ready API wrapper for Discord written in Python

Pending
Overview
Eval results
Files

event-handling.mddocs/

Event Handling

Comprehensive event system for responding to Discord activities including messages, reactions, member changes, guild updates, and voice state changes. Discord.py provides both high-level events and raw gateway events for detailed control over bot behavior.

Capabilities

Core Events

Essential events for bot functionality and user interactions.

@client.event
async def on_ready():
    """
    Called when the client has successfully connected to Discord.
    Bot is fully ready to process events and commands.
    """
    pass

@client.event  
async def on_resumed():
    """
    Called when the client has resumed a session.
    """
    pass

@client.event
async def on_connect():
    """
    Called when the client has connected to Discord's gateway.
    This may be called multiple times during reconnections.
    """
    pass

@client.event
async def on_disconnect():
    """
    Called when the client has disconnected from Discord's gateway.
    """
    pass

@client.event
async def on_shard_connect(shard_id: int):
    """
    Called when a shard connects to Discord.
    
    Parameters:
    - shard_id: ID of the connected shard
    """
    pass

@client.event
async def on_shard_disconnect(shard_id: int):
    """
    Called when a shard disconnects from Discord.
    
    Parameters:
    - shard_id: ID of the disconnected shard
    """
    pass

@client.event
async def on_shard_ready(shard_id: int):
    """
    Called when a shard becomes ready.
    
    Parameters:
    - shard_id: ID of the ready shard
    """
    pass

@client.event
async def on_shard_resumed(shard_id: int):
    """
    Called when a shard resumes a session.
    
    Parameters:
    - shard_id: ID of the resumed shard
    """
    pass

Message Events

Events for message creation, editing, deletion, and reactions.

@client.event
async def on_message(message: Message):
    """
    Called when a message is created.
    
    Parameters:
    - message: The message that was created
    """
    pass

@client.event
async def on_message_edit(before: Message, after: Message):
    """
    Called when a message is edited.
    
    Parameters:
    - before: Message before editing
    - after: Message after editing
    """
    pass

@client.event
async def on_message_delete(message: Message):
    """
    Called when a message is deleted.
    
    Parameters:
    - message: The deleted message (may be partial)
    """
    pass

@client.event
async def on_bulk_message_delete(messages: List[Message]):
    """
    Called when multiple messages are deleted at once.
    
    Parameters:
    - messages: List of deleted messages
    """
    pass

@client.event
async def on_reaction_add(reaction: Reaction, user: Union[User, Member]):
    """
    Called when a reaction is added to a message.
    
    Parameters:
    - reaction: The reaction that was added
    - user: User who added the reaction
    """
    pass

@client.event
async def on_reaction_remove(reaction: Reaction, user: Union[User, Member]):
    """
    Called when a reaction is removed from a message.
    
    Parameters:
    - reaction: The reaction that was removed
    - user: User who removed the reaction
    """
    pass

@client.event
async def on_reaction_clear(message: Message, reactions: List[Reaction]):
    """
    Called when all reactions are cleared from a message.
    
    Parameters:
    - message: Message that had reactions cleared
    - reactions: List of reactions that were cleared
    """
    pass

@client.event
async def on_reaction_clear_emoji(reaction: Reaction):
    """
    Called when all reactions of a specific emoji are cleared.
    
    Parameters:
    - reaction: The reaction that was cleared
    """
    pass

@client.event
async def on_typing(channel: Messageable, user: Union[User, Member], when: datetime):
    """
    Called when someone starts typing.
    
    Parameters:
    - channel: Channel where typing started
    - user: User who started typing
    - when: When typing started
    """
    pass

Guild Events

Events for guild (server) management and changes.

@client.event
async def on_guild_join(guild: Guild):
    """
    Called when the bot joins a guild.
    
    Parameters:
    - guild: Guild that was joined
    """
    pass

@client.event
async def on_guild_remove(guild: Guild):
    """
    Called when the bot is removed from a guild.
    
    Parameters:
    - guild: Guild that was left
    """
    pass

@client.event
async def on_guild_update(before: Guild, after: Guild):
    """
    Called when a guild is updated.
    
    Parameters:
    - before: Guild before update
    - after: Guild after update
    """
    pass

@client.event
async def on_guild_available(guild: Guild):
    """
    Called when a guild becomes available.
    
    Parameters:
    - guild: Guild that became available
    """
    pass

@client.event
async def on_guild_unavailable(guild: Guild):
    """
    Called when a guild becomes unavailable.
    
    Parameters:
    - guild: Guild that became unavailable
    """
    pass

@client.event
async def on_guild_channel_create(channel: GuildChannel):
    """
    Called when a guild channel is created.
    
    Parameters:
    - channel: Channel that was created
    """
    pass

@client.event
async def on_guild_channel_delete(channel: GuildChannel):
    """
    Called when a guild channel is deleted.
    
    Parameters:
    - channel: Channel that was deleted
    """
    pass

@client.event
async def on_guild_channel_update(before: GuildChannel, after: GuildChannel):
    """
    Called when a guild channel is updated.
    
    Parameters:
    - before: Channel before update
    - after: Channel after update
    """
    pass

@client.event
async def on_guild_channel_pins_update(channel: Union[TextChannel, DMChannel, GroupChannel], last_pin: Optional[datetime]):
    """
    Called when channel pins are updated.
    
    Parameters:
    - channel: Channel with pin update
    - last_pin: Timestamp of most recent pin
    """
    pass

@client.event
async def on_guild_integrations_update(guild: Guild):
    """
    Called when guild integrations are updated.
    
    Parameters:
    - guild: Guild with integration update
    """
    pass

@client.event
async def on_webhooks_update(channel: TextChannel):
    """
    Called when channel webhooks are updated.
    
    Parameters:
    - channel: Channel with webhook update
    """
    pass

@client.event
async def on_guild_role_create(role: Role):
    """
    Called when a guild role is created.
    
    Parameters:
    - role: Role that was created
    """
    pass

@client.event
async def on_guild_role_delete(role: Role):
    """
    Called when a guild role is deleted.
    
    Parameters:
    - role: Role that was deleted
    """
    pass

@client.event
async def on_guild_role_update(before: Role, after: Role):
    """
    Called when a guild role is updated.
    
    Parameters:
    - before: Role before update
    - after: Role after update
    """
    pass

@client.event
async def on_guild_emojis_update(guild: Guild, before: List[Emoji], after: List[Emoji]):
    """
    Called when guild emojis are updated.
    
    Parameters:
    - guild: Guild with emoji update
    - before: Emojis before update
    - after: Emojis after update
    """
    pass

@client.event
async def on_guild_stickers_update(guild: Guild, before: List[GuildSticker], after: List[GuildSticker]):
    """
    Called when guild stickers are updated.
    
    Parameters:
    - guild: Guild with sticker update
    - before: Stickers before update
    - after: Stickers after update
    """
    pass

Member Events

Events for member management, joins, leaves, and updates.

@client.event
async def on_member_join(member: Member):
    """
    Called when a member joins a guild.
    
    Parameters:
    - member: Member who joined
    """
    pass

@client.event
async def on_member_remove(member: Member):
    """
    Called when a member leaves a guild.
    
    Parameters:
    - member: Member who left
    """
    pass

@client.event
async def on_member_update(before: Member, after: Member):
    """
    Called when a member is updated.
    
    Parameters:
    - before: Member before update
    - after: Member after update
    """
    pass

@client.event
async def on_user_update(before: User, after: User):
    """
    Called when a user updates their profile.
    
    Parameters:
    - before: User before update
    - after: User after update
    """
    pass

@client.event
async def on_member_ban(guild: Guild, user: Union[User, Member]):
    """
    Called when a member is banned from a guild.
    
    Parameters:
    - guild: Guild where ban occurred
    - user: User who was banned
    """
    pass

@client.event
async def on_member_unban(guild: Guild, user: User):
    """
    Called when a member is unbanned from a guild.
    
    Parameters:
    - guild: Guild where unban occurred
    - user: User who was unbanned
    """
    pass

@client.event
async def on_presence_update(before: Member, after: Member):
    """
    Called when a member's presence is updated.
    Requires PRESENCE_UPDATE intent.
    
    Parameters:
    - before: Member before presence update
    - after: Member after presence update
    """
    pass

Voice Events

Events for voice channel activity and state changes.

@client.event
async def on_voice_state_update(member: Member, before: VoiceState, after: VoiceState):
    """
    Called when a member's voice state changes.
    
    Parameters:
    - member: Member whose voice state changed
    - before: Voice state before change
    - after: Voice state after change
    """
    pass

@client.event
async def on_stage_instance_create(stage_instance: StageInstance):
    """
    Called when a stage instance is created.
    
    Parameters:
    - stage_instance: Stage instance that was created
    """
    pass

@client.event
async def on_stage_instance_delete(stage_instance: StageInstance):
    """
    Called when a stage instance is deleted.
    
    Parameters:
    - stage_instance: Stage instance that was deleted
    """
    pass

@client.event
async def on_stage_instance_update(before: StageInstance, after: StageInstance):
    """
    Called when a stage instance is updated.
    
    Parameters:
    - before: Stage instance before update
    - after: Stage instance after update
    """
    pass

Interaction Events

Events for slash commands, buttons, select menus, and other interactions.

@client.event
async def on_interaction(interaction: Interaction):
    """
    Called when an interaction is received.
    
    Parameters:
    - interaction: The interaction that was received
    """
    pass

@client.event
async def on_application_command_error(interaction: Interaction, error: AppCommandError):
    """
    Called when an application command raises an error.
    
    Parameters:
    - interaction: Interaction that caused the error
    - error: Error that was raised
    """
    pass

@client.event
async def on_app_command_completion(interaction: Interaction, command: Union[Command, ContextMenu]):
    """
    Called when an application command completes successfully.
    
    Parameters:
    - interaction: Interaction that completed
    - command: Command that was executed
    """
    pass

Thread Events

Events for thread creation, deletion, and management.

@client.event
async def on_thread_create(thread: Thread):
    """
    Called when a thread is created.
    
    Parameters:
    - thread: Thread that was created
    """
    pass

@client.event
async def on_thread_delete(thread: Thread):
    """
    Called when a thread is deleted.
    
    Parameters:
    - thread: Thread that was deleted
    """
    pass

@client.event
async def on_thread_update(before: Thread, after: Thread):
    """
    Called when a thread is updated.
    
    Parameters:
    - before: Thread before update
    - after: Thread after update
    """
    pass

@client.event
async def on_thread_member_join(member: ThreadMember):
    """
    Called when a member joins a thread.
    
    Parameters:
    - member: Thread member who joined
    """
    pass

@client.event
async def on_thread_member_remove(member: ThreadMember):
    """
    Called when a member leaves a thread.
    
    Parameters:
    - member: Thread member who left
    """
    pass

@client.event
async def on_thread_join(thread: Thread):
    """
    Called when the bot joins a thread.
    
    Parameters:
    - thread: Thread that was joined
    """
    pass

@client.event
async def on_thread_remove(thread: Thread):
    """
    Called when the bot is removed from a thread.
    
    Parameters:
    - thread: Thread that was left
    """
    pass

Scheduled Event Events

Events for guild scheduled events.

@client.event
async def on_scheduled_event_create(event: ScheduledEvent):
    """
    Called when a scheduled event is created.
    
    Parameters:
    - event: Scheduled event that was created
    """
    pass

@client.event
async def on_scheduled_event_delete(event: ScheduledEvent):
    """
    Called when a scheduled event is deleted.
    
    Parameters:
    - event: Scheduled event that was deleted
    """
    pass

@client.event
async def on_scheduled_event_update(before: ScheduledEvent, after: ScheduledEvent):
    """
    Called when a scheduled event is updated.
    
    Parameters:
    - before: Event before update
    - after: Event after update
    """
    pass

@client.event
async def on_scheduled_event_user_add(event: ScheduledEvent, user: User):
    """
    Called when a user subscribes to a scheduled event.
    
    Parameters:
    - event: Scheduled event
    - user: User who subscribed
    """
    pass

@client.event
async def on_scheduled_event_user_remove(event: ScheduledEvent, user: User):
    """
    Called when a user unsubscribes from a scheduled event.
    
    Parameters:
    - event: Scheduled event
    - user: User who unsubscribed
    """
    pass

Auto Moderation Events

Events for Discord's auto-moderation system.

@client.event
async def on_automod_rule_create(rule: AutoModRule):
    """
    Called when an auto-moderation rule is created.
    
    Parameters:
    - rule: Auto-moderation rule that was created
    """
    pass

@client.event
async def on_automod_rule_delete(rule: AutoModRule):
    """
    Called when an auto-moderation rule is deleted.
    
    Parameters:
    - rule: Auto-moderation rule that was deleted
    """
    pass

@client.event
async def on_automod_rule_update(before: AutoModRule, after: AutoModRule):
    """
    Called when an auto-moderation rule is updated.
    
    Parameters:
    - before: Rule before update
    - after: Rule after update
    """
    pass

@client.event
async def on_automod_action(execution: AutoModAction):
    """
    Called when an auto-moderation action is executed.
    
    Parameters:
    - execution: Auto-moderation action execution
    """
    pass

Raw Events

Low-level events providing raw Discord gateway data.

@client.event
async def on_raw_message_edit(payload: RawMessageUpdateEvent):
    """
    Called when a message is edited (raw event).
    
    Parameters:
    - payload: Raw message update data
    """
    pass

@client.event
async def on_raw_message_delete(payload: RawMessageDeleteEvent):
    """
    Called when a message is deleted (raw event).
    
    Parameters:
    - payload: Raw message delete data
    """
    pass

@client.event
async def on_raw_bulk_message_delete(payload: RawBulkMessageDeleteEvent):
    """
    Called when messages are bulk deleted (raw event).
    
    Parameters:
    - payload: Raw bulk delete data
    """
    pass

@client.event
async def on_raw_reaction_add(payload: RawReactionActionEvent):
    """
    Called when a reaction is added (raw event).
    
    Parameters:
    - payload: Raw reaction data
    """
    pass

@client.event
async def on_raw_reaction_remove(payload: RawReactionActionEvent):
    """
    Called when a reaction is removed (raw event).
    
    Parameters:
    - payload: Raw reaction data
    """
    pass

@client.event
async def on_raw_reaction_clear(payload: RawReactionClearEvent):
    """
    Called when reactions are cleared (raw event).
    
    Parameters:
    - payload: Raw reaction clear data
    """
    pass

@client.event
async def on_raw_reaction_clear_emoji(payload: RawReactionClearEmojiEvent):
    """
    Called when emoji reactions are cleared (raw event).
    
    Parameters:
    - payload: Raw emoji clear data
    """
    pass

@client.event
async def on_raw_typing(payload: RawTypingEvent):
    """
    Called when typing starts (raw event).
    
    Parameters:
    - payload: Raw typing data
    """
    pass

@client.event
async def on_raw_member_remove(payload: RawMemberRemoveEvent):
    """
    Called when a member leaves (raw event).
    
    Parameters:
    - payload: Raw member remove data
    """
    pass

@client.event
async def on_raw_thread_update(payload: RawThreadUpdateEvent):
    """
    Called when a thread is updated (raw event).
    
    Parameters:
    - payload: Raw thread update data
    """
    pass

@client.event
async def on_raw_thread_delete(payload: RawThreadDeleteEvent):
    """
    Called when a thread is deleted (raw event).
    
    Parameters:
    - payload: Raw thread delete data
    """
    pass

@client.event
async def on_raw_app_command_permissions_update(payload: RawAppCommandPermissionsUpdateEvent):
    """
    Called when app command permissions are updated (raw event).
    
    Parameters:
    - payload: Raw permissions update data
    """
    pass

Error Events

Events for handling errors and exceptions.

@client.event
async def on_error(event: str, *args, **kwargs):
    """
    Called when an event handler raises an uncaught exception.
    
    Parameters:
    - event: Name of the event that raised the exception
    - args: Positional arguments passed to the event
    - kwargs: Keyword arguments passed to the event
    """
    pass

@client.event
async def on_command_error(ctx: Context, error: CommandError):
    """
    Called when a command raises an error.
    Only available when using the commands extension.
    
    Parameters:
    - ctx: Command context
    - error: Error that was raised
    """
    pass

Raw Event Payloads

Raw event payload classes for low-level event handling:

class RawMessageUpdateEvent:
    """Raw message update event payload."""
    message_id: int  # Message ID
    channel_id: int  # Channel ID
    guild_id: Optional[int]  # Guild ID
    data: Dict[str, Any]  # Message data
    cached_message: Optional[Message]  # Cached message if available

class RawMessageDeleteEvent:
    """Raw message delete event payload."""
    message_id: int  # Deleted message ID
    channel_id: int  # Channel ID
    guild_id: Optional[int]  # Guild ID
    cached_message: Optional[Message]  # Cached message if available

class RawBulkMessageDeleteEvent:
    """Raw bulk message delete event payload."""
    message_ids: Set[int]  # Deleted message IDs
    channel_id: int  # Channel ID
    guild_id: Optional[int]  # Guild ID
    cached_messages: List[Message]  # Cached messages if available

class RawReactionActionEvent:
    """Raw reaction add/remove event payload."""
    message_id: int  # Message ID
    user_id: int  # User ID
    channel_id: int  # Channel ID
    guild_id: Optional[int]  # Guild ID
    emoji: PartialEmoji  # Reaction emoji
    member: Optional[Member]  # Member who reacted (if available)
    event_type: str  # 'REACTION_ADD' or 'REACTION_REMOVE'

class RawReactionClearEvent:
    """Raw reaction clear event payload."""
    message_id: int  # Message ID
    channel_id: int  # Channel ID
    guild_id: Optional[int]  # Guild ID

class RawReactionClearEmojiEvent:
    """Raw emoji reaction clear event payload."""
    message_id: int  # Message ID
    channel_id: int  # Channel ID
    guild_id: Optional[int]  # Guild ID
    emoji: PartialEmoji  # Cleared emoji

class RawTypingEvent:
    """Raw typing event payload."""
    channel_id: int  # Channel ID
    user_id: int  # User ID
    timestamp: datetime  # When typing started
    guild_id: Optional[int]  # Guild ID
    member: Optional[Member]  # Member who is typing

class RawMemberRemoveEvent:
    """Raw member remove event payload."""
    user: User  # User who left
    guild_id: int  # Guild ID

class RawThreadUpdateEvent:
    """Raw thread update event payload."""
    thread_id: int  # Thread ID
    guild_id: int  # Guild ID
    data: Dict[str, Any]  # Thread data
    thread: Optional[Thread]  # Thread object if cached

class RawThreadDeleteEvent:
    """Raw thread delete event payload."""
    thread_id: int  # Thread ID
    guild_id: int  # Guild ID
    parent_id: int  # Parent channel ID
    thread_type: ChannelType  # Thread type
    thread: Optional[Thread]  # Thread object if cached

class RawAppCommandPermissionsUpdateEvent:
    """Raw app command permissions update event payload."""
    id: int  # Command ID
    application_id: int  # Application ID
    guild_id: int  # Guild ID
    permissions: List[AppCommandPermissions]  # Updated permissions

Usage Examples

Basic Event Handling

import discord
from discord.ext import commands

bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())

@bot.event
async def on_ready():
    print(f'{bot.user} has connected to Discord!')
    print(f'Connected to {len(bot.guilds)} guilds')

@bot.event
async def on_member_join(member):
    # Send welcome message
    channel = discord.utils.get(member.guild.text_channels, name='welcome')
    if channel:
        embed = discord.Embed(
            title=f'Welcome {member.display_name}!',
            description=f'Welcome to {member.guild.name}!',
            color=0x00ff00
        )
        embed.set_thumbnail(url=member.display_avatar.url)
        embed.add_field(name='Member Count', value=len(member.guild.members))
        await channel.send(embed=embed)

@bot.event
async def on_member_remove(member):
    # Log member leave
    channel = discord.utils.get(member.guild.text_channels, name='mod-log')
    if channel:
        embed = discord.Embed(
            title='Member Left',
            description=f'{member} left the server',
            color=0xff0000,
            timestamp=discord.utils.utcnow()
        )
        await channel.send(embed=embed)

@bot.event
async def on_message(message):
    # Ignore bot messages
    if message.author.bot:
        return
    
    # Auto-react to messages containing "discord.py"
    if 'discord.py' in message.content.lower():
        await message.add_reaction('🐍')
    
    # Process commands
    await bot.process_commands(message)

bot.run('YOUR_TOKEN')

Reaction Role System

@bot.event
async def on_raw_reaction_add(payload):
    """Handle reaction role assignment."""
    # Configuration: message_id -> {emoji: role_id}
    REACTION_ROLES = {
        123456789012345678: {  # Replace with actual message ID
            '🎮': 987654321098765432,  # Gaming role ID
            '🎵': 876543210987654321,  # Music role ID
            '📚': 765432109876543210,  # Study role ID
        }
    }
    
    if payload.message_id not in REACTION_ROLES:
        return
    
    if payload.user_id == bot.user.id:
        return  # Ignore bot reactions
    
    guild = bot.get_guild(payload.guild_id)
    if not guild:
        return
    
    member = guild.get_member(payload.user_id)
    if not member:
        return
    
    emoji_str = str(payload.emoji)
    role_id = REACTION_ROLES[payload.message_id].get(emoji_str)
    
    if role_id:
        role = guild.get_role(role_id)
        if role and role not in member.roles:
            try:
                await member.add_roles(role, reason="Reaction role")
                print(f"Added {role.name} to {member}")
            except discord.HTTPException as e:
                print(f"Failed to add role: {e}")

@bot.event
async def on_raw_reaction_remove(payload):
    """Handle reaction role removal."""
    # Same configuration as above
    REACTION_ROLES = {
        123456789012345678: {
            '🎮': 987654321098765432,
            '🎵': 876543210987654321,
            '📚': 765432109876543210,
        }
    }
    
    if payload.message_id not in REACTION_ROLES:
        return
    
    if payload.user_id == bot.user.id:
        return
    
    guild = bot.get_guild(payload.guild_id)
    if not guild:
        return
    
    member = guild.get_member(payload.user_id)
    if not member:
        return
    
    emoji_str = str(payload.emoji)
    role_id = REACTION_ROLES[payload.message_id].get(emoji_str)
    
    if role_id:
        role = guild.get_role(role_id)
        if role and role in member.roles:
            try:
                await member.remove_roles(role, reason="Reaction role removed")
                print(f"Removed {role.name} from {member}")
            except discord.HTTPException as e:
                print(f"Failed to remove role: {e}")

Advanced Message Monitoring

@bot.event
async def on_message_edit(before, after):
    """Log message edits."""
    if before.author.bot:
        return
    
    if before.content == after.content:
        return  # No content change
    
    # Log to mod channel
    mod_channel = discord.utils.get(before.guild.text_channels, name='mod-log')
    if mod_channel:
        embed = discord.Embed(
            title='Message Edited',
            color=0xffaa00,
            timestamp=after.edited_at
        )
        embed.add_field(name='Author', value=before.author.mention, inline=True)
        embed.add_field(name='Channel', value=before.channel.mention, inline=True)
        embed.add_field(name='Message ID', value=before.id, inline=True)
        embed.add_field(name='Before', value=before.content[:1024], inline=False)
        embed.add_field(name='After', value=after.content[:1024], inline=False)
        embed.add_field(name='Jump to Message', value=f'[Click here]({after.jump_url})', inline=False)
        
        await mod_channel.send(embed=embed)

@bot.event
async def on_message_delete(message):
    """Log message deletions."""
    if message.author.bot:
        return
    
    mod_channel = discord.utils.get(message.guild.text_channels, name='mod-log')
    if mod_channel:
        embed = discord.Embed(
            title='Message Deleted',
            color=0xff0000,
            timestamp=discord.utils.utcnow()
        )
        embed.add_field(name='Author', value=message.author.mention, inline=True)
        embed.add_field(name='Channel', value=message.channel.mention, inline=True)
        embed.add_field(name='Message ID', value=message.id, inline=True)
        embed.add_field(name='Content', value=message.content[:1024] or '*No content*', inline=False)
        
        if message.attachments:
            attachments = '\n'.join([att.filename for att in message.attachments])
            embed.add_field(name='Attachments', value=attachments, inline=False)
        
        await mod_channel.send(embed=embed)

Voice Activity Monitoring

@bot.event
async def on_voice_state_update(member, before, after):
    """Monitor voice activity."""
    
    # Member joined voice
    if before.channel is None and after.channel is not None:
        print(f"{member} joined {after.channel}")
        
        # Create temporary voice channel if joining "Create Channel" channel
        if after.channel.name == "➕ Create Channel":
            category = after.channel.category
            temp_channel = await after.channel.guild.create_voice_channel(
                name=f"{member.display_name}'s Channel",
                category=category,
                user_limit=10
            )
            await member.move_to(temp_channel)
            
            # Set permissions for channel owner
            await temp_channel.set_permissions(member, manage_channels=True, manage_permissions=True)
    
    # Member left voice
    elif before.channel is not None and after.channel is None:
        print(f"{member} left {before.channel}")
        
        # Delete temporary channels when empty
        if before.channel.name.endswith("'s Channel") and len(before.channel.members) == 0:
            await before.channel.delete(reason="Temporary channel cleanup")
    
    # Member moved channels
    elif before.channel != after.channel and before.channel is not None and after.channel is not None:
        print(f"{member} moved from {before.channel} to {after.channel}")
    
    # Voice state changes
    if before.self_mute != after.self_mute:
        status = "muted" if after.self_mute else "unmuted"
        print(f"{member} {status} themselves")
    
    if before.self_deaf != after.self_deaf:
        status = "deafened" if after.self_deaf else "undeafened"
        print(f"{member} {status} themselves")

Error Handling

@bot.event
async def on_error(event, *args, **kwargs):
    """Handle errors in event handlers."""
    import traceback
    import sys
    
    print(f'Ignoring exception in {event}:', file=sys.stderr)
    traceback.print_exc()
    
    # Log to error channel
    error_channel = bot.get_channel(ERROR_CHANNEL_ID)
    if error_channel:
        embed = discord.Embed(
            title='Event Error',
            description=f'Error in event: `{event}`',
            color=0xff0000,
            timestamp=discord.utils.utcnow()
        )
        embed.add_field(name='Traceback', value=f'```py\n{traceback.format_exc()[:1900]}\n```', inline=False)
        await error_channel.send(embed=embed)

@bot.event
async def on_command_error(ctx, error):
    """Handle command errors."""
    if isinstance(error, commands.CommandNotFound):
        return  # Ignore unknown commands
    
    elif isinstance(error, commands.MissingRequiredArgument):
        await ctx.send(f'Missing required argument: `{error.param.name}`')
    
    elif isinstance(error, commands.BadArgument):
        await ctx.send(f'Invalid argument: {error}')
    
    elif isinstance(error, commands.MissingPermissions):
        perms = ', '.join(error.missing_permissions)
        await ctx.send(f'You need the following permissions: {perms}')
    
    elif isinstance(error, commands.BotMissingPermissions):
        perms = ', '.join(error.missing_permissions)
        await ctx.send(f'I need the following permissions: {perms}')
    
    elif isinstance(error, commands.CommandOnCooldown):
        await ctx.send(f'Command is on cooldown. Try again in {error.retry_after:.2f} seconds.')
    
    else:
        # Log unexpected errors
        import traceback
        traceback.print_exception(type(error), error, error.__traceback__)
        await ctx.send('An unexpected error occurred.')

Install with Tessl CLI

npx tessl i tessl/pypi-discord-py

docs

app-commands.md

commands-framework.md

core-objects.md

event-handling.md

index.md

user-interface.md

utilities.md

voice-audio.md

webhooks.md

tile.json