CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-disnake

A modern, easy-to-use, feature-rich async-ready API wrapper for Discord written in Python

Pending
Overview
Eval results
Files

events-gateway.mddocs/

Events and Gateway

Discord gateway events and event handling system for real-time bot functionality including comprehensive event types, custom event dispatching, event filtering, and gateway connection management for responsive Discord bot applications.

Capabilities

Event System

Core event handling infrastructure for Discord gateway events and custom bot events.

@bot.event
async def on_ready():
    """
    Called when the bot is ready and connected to Discord.
    
    This event is called once when the bot successfully connects
    and is ready to receive events and process commands.
    """

@bot.event
async def on_resumed():
    """
    Called when a previously disconnected bot resumes its connection.
    """

@bot.event
async def on_connect():
    """
    Called when the bot connects to Discord (before ready).
    """

@bot.event
async def on_disconnect():
    """
    Called when the bot disconnects from Discord.
    """

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

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

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

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

def wait_for(
    event: str,
    *,
    check: Optional[Callable[..., bool]] = None,
    timeout: Optional[float] = None
) -> Any:
    """
    Wait for a specific event to occur.
    
    Parameters:
    - event: Name of the event to wait for
    - check: Optional function to check event conditions
    - timeout: Maximum time to wait in seconds
    
    Returns:
    Event data when the event occurs
    
    Raises:
    asyncio.TimeoutError: If timeout is reached
    """

def dispatch(event: str, *args, **kwargs) -> None:
    """
    Dispatch a custom event.
    
    Parameters:
    - event: Event name (without 'on_' prefix)
    - args: Event arguments
    - kwargs: Event keyword arguments
    """

Message Events

Events related to message creation, editing, deletion, and reactions.

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

@bot.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
    """

@bot.event
async def on_message_delete(message: Message):
    """
    Called when a message is deleted.
    
    Parameters:
    - message: The deleted message
    """

@bot.event
async def on_bulk_message_delete(messages: List[Message]):
    """
    Called when messages are bulk deleted.
    
    Parameters:
    - messages: List of deleted messages
    """

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

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

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

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

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

@bot.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
    """

@bot.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
    """

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

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

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

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

Member Events

Events related to guild member changes, presence updates, and member activity.

@bot.event
async def on_member_join(member: Member):
    """
    Called when a member joins a guild.
    
    Parameters:
    - member: The member that joined
    """

@bot.event
async def on_member_remove(member: Member):
    """
    Called when a member leaves a guild.
    
    Parameters:
    - member: The member that left
    """

@bot.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
    """

@bot.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
    """

@bot.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 the ban occurred
    - user: User that was banned
    """

@bot.event
async def on_member_unban(guild: Guild, user: User):
    """
    Called when a user is unbanned from a guild.
    
    Parameters:
    - guild: Guild where the unban occurred
    - user: User that was unbanned
    """

@bot.event
async def on_presence_update(before: Member, after: Member):
    """
    Called when a member's presence updates.
    
    Parameters:
    - before: Member presence before update
    - after: Member presence after update
    """

@bot.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
    """

Guild Events

Events related to guild changes, channels, roles, and guild-specific features.

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

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

@bot.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
    """

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

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

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

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

@bot.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
    """

@bot.event
async def on_guild_channel_pins_update(channel: Union[TextChannel, NewsChannel], last_pin: Optional[datetime]):
    """
    Called when channel pins are updated.
    
    Parameters:
    - channel: Channel with updated pins
    - last_pin: Time of last pinned message
    """

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

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

@bot.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
    """

@bot.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 updated emojis
    - before: Emojis before update
    - after: Emojis after update
    """

@bot.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 updated stickers
    - before: Stickers before update
    - after: Stickers after update
    """

Voice Events

Events related to voice channel activity and voice state changes.

@bot.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
    """

@bot.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
    """

@bot.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
    """

@bot.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
    """

Interaction Events

Events related to application commands, components, and modal interactions.

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

@bot.event
async def on_application_command(interaction: ApplicationCommandInteraction):
    """
    Called when an application command is used.
    
    Parameters:
    - interaction: Application command interaction
    """

@bot.event
async def on_message_interaction(interaction: MessageInteraction):
    """
    Called when a message component interaction occurs.
    
    Parameters:
    - interaction: Message component interaction
    """

@bot.event
async def on_modal_submit(interaction: ModalInteraction):
    """
    Called when a modal is submitted.
    
    Parameters:
    - interaction: Modal submission interaction
    """

@bot.event
async def on_dropdown(interaction: MessageInteraction):
    """
    Called when a dropdown/select menu is used.
    
    Parameters:
    - interaction: Dropdown interaction
    """

@bot.event
async def on_button_click(interaction: MessageInteraction):
    """
    Called when a button is clicked.
    
    Parameters:
    - interaction: Button click interaction
    """

@bot.event
async def on_application_command_error(interaction: ApplicationCommandInteraction, error: Exception):
    """
    Called when an application command raises an error.
    
    Parameters:
    - interaction: Command interaction that caused error
    - error: Exception that was raised
    """

Thread Events

Events related to thread creation, updates, and member management.

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

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

@bot.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
    """

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

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

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

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

Scheduled Events

Events related to guild scheduled events and event management.

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

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

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

@bot.event
async def on_scheduled_event_user_add(event: GuildScheduledEvent, user: User):
    """
    Called when a user subscribes to a scheduled event.
    
    Parameters:
    - event: Scheduled event
    - user: User that subscribed
    """

@bot.event
async def on_scheduled_event_user_remove(event: GuildScheduledEvent, user: User):
    """
    Called when a user unsubscribes from a scheduled event.
    
    Parameters:
    - event: Scheduled event
    - user: User that unsubscribed
    """

Raw Events

Raw gateway events for handling events without cached objects.

class RawMessageUpdateEvent:
    """Raw message update event data."""
    
    message_id: int
    channel_id: int
    guild_id: Optional[int]
    data: Dict[str, Any]

class RawMessageDeleteEvent:
    """Raw message delete event data."""
    
    message_id: int
    channel_id: int
    guild_id: Optional[int]

class RawBulkMessageDeleteEvent:
    """Raw bulk message delete event data."""
    
    message_ids: List[int]
    channel_id: int
    guild_id: Optional[int]

class RawReactionActionEvent:
    """Raw reaction add/remove event data."""
    
    message_id: int
    channel_id: int
    guild_id: Optional[int]
    user_id: int
    emoji: PartialEmoji
    member: Optional[Member]

class RawReactionClearEvent:
    """Raw reaction clear event data."""
    
    message_id: int
    channel_id: int
    guild_id: Optional[int]

class RawReactionClearEmojiEvent:
    """Raw emoji reaction clear event data."""
    
    message_id: int
    channel_id: int
    guild_id: Optional[int]
    emoji: PartialEmoji

class RawThreadUpdateEvent:
    """Raw thread update event data."""
    
    thread_id: int
    guild_id: int
    parent_id: int
    data: Dict[str, Any]

class RawThreadDeleteEvent:
    """Raw thread delete event data."""
    
    thread_id: int
    guild_id: int
    parent_id: int
    thread_type: ChannelType

Gateway Connection

Gateway connection management and configuration for Discord real-time events.

class GatewayParams:
    """Gateway connection parameters."""
    
    def __init__(self): ...
    
    url: str
    shard_id: Optional[int]
    shard_count: Optional[int]
    session_start_limit: SessionStartLimit

class SessionStartLimit:
    """Gateway session start limit information."""
    
    def __init__(self): ...
    
    total: int
    remaining: int
    reset_after: int
    max_concurrency: int

class Intents:
    """Gateway intents bitfield."""
    
    def __init__(self, **kwargs): ...
    
    @classmethod
    def default(cls) -> Intents:
        """Default intents (recommended for most bots)."""
    
    @classmethod
    def all(cls) -> Intents:
        """All intents (requires privileged intents approval)."""
    
    @classmethod
    def none(cls) -> Intents:
        """No intents enabled."""
    
    # Privileged intents (require approval)
    @property
    def presences(self) -> bool:
        """Presence update intents."""
    
    @property
    def members(self) -> bool:
        """Member update intents."""
    
    @property
    def message_content(self) -> bool:
        """Message content intents."""
    
    # Non-privileged intents
    @property
    def guilds(self) -> bool:
        """Guild-related events."""
    
    @property
    def guild_messages(self) -> bool:
        """Guild message events."""
    
    @property
    def guild_reactions(self) -> bool:
        """Guild reaction events."""
    
    @property
    def guild_typing(self) -> bool:
        """Guild typing events."""
    
    @property
    def direct_messages(self) -> bool:
        """Direct message events."""
    
    @property
    def direct_message_reactions(self) -> bool:
        """DM reaction events."""
    
    @property
    def direct_message_typing(self) -> bool:
        """DM typing events."""
    
    @property
    def guild_integrations(self) -> bool:
        """Guild integration events."""
    
    @property
    def guild_webhooks(self) -> bool:
        """Guild webhook events."""
    
    @property
    def guild_invites(self) -> bool:
        """Guild invite events."""
    
    @property
    def guild_voice_states(self) -> bool:
        """Voice state events."""
    
    @property
    def guild_scheduled_events(self) -> bool:
        """Scheduled event intents."""
    
    @property
    def auto_moderation_configuration(self) -> bool:
        """AutoMod configuration events."""
    
    @property
    def auto_moderation_execution(self) -> bool:
        """AutoMod execution events."""

Usage Examples

Basic Event Handling

import disnake
from disnake.ext import commands

# Set up intents
intents = disnake.Intents.default()
intents.message_content = True
intents.members = True
intents.presences = True

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

@bot.event
async def on_ready():
    print(f'Bot is ready! Logged in as {bot.user}')
    print(f'Connected to {len(bot.guilds)} guilds')
    print(f'Serving {len(bot.users)} users')
    
    # Set bot activity
    await bot.change_presence(
        status=disnake.Status.online,
        activity=disnake.Game(name="Managing the server!")
    )

@bot.event
async def on_guild_join(guild):
    """Welcome message when bot joins a server."""
    print(f'Joined new guild: {guild.name} (ID: {guild.id})')
    
    # Send welcome message to system channel
    if guild.system_channel and guild.system_channel.permissions_for(guild.me).send_messages:
        embed = disnake.Embed(
            title="Thanks for adding me!",
            description="Use `!help` to see available commands.",
            color=0x00ff00
        )
        embed.set_thumbnail(url=bot.user.display_avatar.url)
        await guild.system_channel.send(embed=embed)

@bot.event
async def on_guild_remove(guild):
    """Log when bot leaves a server."""
    print(f'Left guild: {guild.name} (ID: {guild.id})')

@bot.event
async def on_message(message):
    """Process messages and auto-responses."""
    # Ignore bot messages
    if message.author.bot:
        return
    
    # Auto-react to certain messages
    if 'good bot' in message.content.lower():
        await message.add_reaction('😊')
    elif 'bad bot' in message.content.lower():
        await message.add_reaction('😢')
    
    # Process commands
    await bot.process_commands(message)

@bot.event
async def on_message_edit(before, after):
    """Log message edits."""
    if before.author.bot or before.content == after.content:
        return
    
    print(f'Message edited in {before.channel}:')
    print(f'Before: {before.content}')
    print(f'After: {after.content}')

@bot.event
async def on_message_delete(message):
    """Log message deletions."""
    if message.author.bot:
        return
    
    print(f'Message deleted in {message.channel}: {message.content}')

bot.run('YOUR_BOT_TOKEN')

Member Event Handling

@bot.event
async def on_member_join(member):
    """Welcome new members."""
    guild = member.guild
    
    # Create welcome embed
    embed = disnake.Embed(
        title=f"Welcome to {guild.name}!",
        description=f"Hello {member.mention}, welcome to our community!",
        color=0x00ff00
    )
    embed.set_thumbnail(url=member.display_avatar.url)
    embed.add_field(name="Member Count", value=f"You're member #{guild.member_count}!", inline=False)
    embed.add_field(name="Account Created", value=f"<t:{int(member.created_at.timestamp())}:F>", inline=True)
    embed.set_footer(text=f"User ID: {member.id}")
    
    # Send to welcome channel
    welcome_channel = disnake.utils.get(guild.channels, name='welcome')
    if welcome_channel:
        await welcome_channel.send(embed=embed)
    
    # Auto-role assignment
    auto_role = disnake.utils.get(guild.roles, name='Member')
    if auto_role:
        try:
            await member.add_roles(auto_role, reason="Auto-role on join")
        except disnake.Forbidden:
            print(f"Cannot assign auto-role in {guild.name}")
    
    # Send DM welcome message
    try:
        dm_embed = disnake.Embed(
            title=f"Welcome to {guild.name}!",
            description="Thanks for joining! Here are some helpful tips:",
            color=0x00ff00
        )
        dm_embed.add_field(
            name="Getting Started",
            value="• Read the rules in #rules\n• Introduce yourself in #introductions\n• Use `!help` to see bot commands",
            inline=False
        )
        await member.send(embed=dm_embed)
    except disnake.Forbidden:
        pass  # User has DMs disabled

@bot.event
async def on_member_remove(member):
    """Log member departures."""
    guild = member.guild
    
    # Log to departure channel
    log_channel = disnake.utils.get(guild.channels, name='member-logs')
    if log_channel:
        embed = disnake.Embed(
            title="Member Left",
            description=f"{member} ({member.id}) has left the server",
            color=0xff0000,
            timestamp=disnake.utils.utcnow()
        )
        embed.set_thumbnail(url=member.display_avatar.url)
        embed.add_field(name="Joined", value=f"<t:{int(member.joined_at.timestamp())}:F>" if member.joined_at else "Unknown", inline=True)
        embed.add_field(name="Member Count", value=f"{guild.member_count} members remaining", inline=True)
        
        if member.roles[1:]:  # Exclude @everyone
            roles = [role.name for role in member.roles[1:]]
            embed.add_field(name="Roles", value=", ".join(roles), inline=False)
        
        await log_channel.send(embed=embed)

@bot.event
async def on_member_update(before, after):
    """Track member changes."""
    # Nickname changes
    if before.nick != after.nick:
        log_channel = disnake.utils.get(after.guild.channels, name='member-logs')
        if log_channel:
            embed = disnake.Embed(
                title="Nickname Changed",
                color=0x0099ff,
                timestamp=disnake.utils.utcnow()
            )
            embed.add_field(name="Member", value=after.mention, inline=True)
            embed.add_field(name="Before", value=before.display_name, inline=True)
            embed.add_field(name="After", value=after.display_name, inline=True)
            await log_channel.send(embed=embed)
    
    # Role changes
    if before.roles != after.roles:
        added_roles = set(after.roles) - set(before.roles)
        removed_roles = set(before.roles) - set(after.roles)
        
        if added_roles or removed_roles:
            log_channel = disnake.utils.get(after.guild.channels, name='member-logs')
            if log_channel:
                embed = disnake.Embed(
                    title="Roles Updated",
                    color=0x0099ff,
                    timestamp=disnake.utils.utcnow()
                )
                embed.add_field(name="Member", value=after.mention, inline=False)
                
                if added_roles:
                    embed.add_field(name="Roles Added", value=", ".join([role.name for role in added_roles]), inline=False)
                if removed_roles:
                    embed.add_field(name="Roles Removed", value=", ".join([role.name for role in removed_roles]), inline=False)
                
                await log_channel.send(embed=embed)

@bot.event
async def on_member_ban(guild, user):
    """Log member bans."""
    log_channel = disnake.utils.get(guild.channels, name='moderation-logs')
    if log_channel:
        embed = disnake.Embed(
            title="Member Banned",
            description=f"{user} ({user.id}) was banned",
            color=0xff0000,
            timestamp=disnake.utils.utcnow()
        )
        embed.set_thumbnail(url=user.display_avatar.url)
        
        # Try to get ban reason from audit logs
        try:
            async for entry in guild.audit_logs(limit=1, action=disnake.AuditLogAction.ban):
                if entry.target.id == user.id:
                    embed.add_field(name="Reason", value=entry.reason or "No reason provided", inline=False)
                    embed.add_field(name="Moderator", value=entry.user.mention, inline=True)
                    break
        except disnake.Forbidden:
            pass
        
        await log_channel.send(embed=embed)

@bot.event
async def on_member_unban(guild, user):
    """Log member unbans."""
    log_channel = disnake.utils.get(guild.channels, name='moderation-logs')
    if log_channel:
        embed = disnake.Embed(
            title="Member Unbanned",
            description=f"{user} ({user.id}) was unbanned",
            color=0x00ff00,
            timestamp=disnake.utils.utcnow()
        )
        embed.set_thumbnail(url=user.display_avatar.url)
        await log_channel.send(embed=embed)

Voice Event Monitoring

@bot.event
async def on_voice_state_update(member, before, after):
    """Track voice channel activity."""
    # Member joined a voice channel
    if before.channel is None and after.channel is not None:
        log_channel = disnake.utils.get(member.guild.channels, name='voice-logs')
        if log_channel:
            embed = disnake.Embed(
                title="Voice Channel Joined",
                description=f"{member.mention} joined {after.channel.mention}",
                color=0x00ff00,
                timestamp=disnake.utils.utcnow()
            )
            await log_channel.send(embed=embed)
    
    # Member left a voice channel
    elif before.channel is not None and after.channel is None:
        log_channel = disnake.utils.get(member.guild.channels, name='voice-logs')
        if log_channel:
            embed = disnake.Embed(
                title="Voice Channel Left",
                description=f"{member.mention} left {before.channel.mention}",
                color=0xff0000,
                timestamp=disnake.utils.utcnow()
            )
            await log_channel.send(embed=embed)
    
    # Member switched voice channels
    elif before.channel is not None and after.channel is not None and before.channel != after.channel:
        log_channel = disnake.utils.get(member.guild.channels, name='voice-logs')
        if log_channel:
            embed = disnake.Embed(
                title="Voice Channel Switched",
                description=f"{member.mention} moved from {before.channel.mention} to {after.channel.mention}",
                color=0x0099ff,
                timestamp=disnake.utils.utcnow()
            )
            await log_channel.send(embed=embed)
    
    # Voice state changes (mute, deafen, etc.)
    changes = []
    if before.self_mute != after.self_mute:
        changes.append(f"Self Mute: {after.self_mute}")
    if before.self_deaf != after.self_deaf:
        changes.append(f"Self Deafen: {after.self_deaf}")
    if before.mute != after.mute:
        changes.append(f"Server Mute: {after.mute}")
    if before.deaf != after.deaf:
        changes.append(f"Server Deafen: {after.deaf}")
    
    if changes and after.channel:
        log_channel = disnake.utils.get(member.guild.channels, name='voice-logs')
        if log_channel:
            embed = disnake.Embed(
                title="Voice State Changed",
                description=f"{member.mention} in {after.channel.mention}:\n" + "\n".join(changes),
                color=0xffa500,
                timestamp=disnake.utils.utcnow()
            )
            await log_channel.send(embed=embed)

Custom Event System

# Custom events using dispatch
@bot.event
async def on_level_up(member, old_level, new_level):
    """Custom event for level system."""
    channel = disnake.utils.get(member.guild.channels, name='general')
    if channel:
        embed = disnake.Embed(
            title="Level Up!",
            description=f"{member.mention} reached level {new_level}!",
            color=0xffd700
        )
        embed.set_thumbnail(url=member.display_avatar.url)
        await channel.send(embed=embed)

# Dispatch custom events
def check_level_up(member, xp):
    old_level = calculate_level(member.old_xp)  # Your level calculation
    new_level = calculate_level(xp)
    
    if new_level > old_level:
        bot.dispatch('level_up', member, old_level, new_level)

# Event filtering and conditions
@bot.event
async def on_message(message):
    # Only process messages in specific channels
    if message.channel.name not in ['general', 'bot-commands']:
        return
    
    # Ignore bot messages
    if message.author.bot:
        return
    
    # Custom processing
    await process_xp(message.author, 10)  # Give XP
    await bot.process_commands(message)

# Wait for specific events
async def wait_for_confirmation(ctx, timeout=30):
    """Wait for user confirmation."""
    def check(reaction, user):
        return (user == ctx.author and 
                str(reaction.emoji) in ['✅', '❌'] and 
                reaction.message.id == ctx.message.id)
    
    try:
        reaction, user = await bot.wait_for('reaction_add', timeout=timeout, check=check)
        return str(reaction.emoji) == '✅'
    except asyncio.TimeoutError:
        return False

# Advanced event handling with error recovery
@bot.event
async def on_error(event, *args, **kwargs):
    """Handle errors in event handlers."""
    import traceback
    
    print(f'Error in event {event}:')
    traceback.print_exc()
    
    # Log to error channel
    error_channel = bot.get_channel(ERROR_CHANNEL_ID)
    if error_channel:
        error_embed = disnake.Embed(
            title=f"Error in {event}",
            description=f"```py\n{traceback.format_exc()[:1900]}\n```",
            color=0xff0000,
            timestamp=disnake.utils.utcnow()
        )
        await error_channel.send(embed=error_embed)

# Rate limiting and event throttling
from collections import defaultdict, deque
import time

event_buckets = defaultdict(lambda: deque())

async def throttled_event_handler(event_name, handler, *args, **kwargs):
    """Throttle event handlers to prevent spam."""
    now = time.time()
    bucket = event_buckets[event_name]
    
    # Remove old entries (older than 1 minute)
    while bucket and bucket[0] < now - 60:
        bucket.popleft()
    
    # Check rate limit (max 10 events per minute)
    if len(bucket) >= 10:
        print(f"Rate limited event: {event_name}")
        return
    
    bucket.append(now)
    await handler(*args, **kwargs)

Gateway Connection Management

import disnake
import asyncio

# Custom gateway configuration
class CustomBot(disnake.Client):
    def __init__(self, **kwargs):
        # Configure intents
        intents = disnake.Intents.default()
        intents.message_content = True
        intents.members = True
        intents.presences = True
        
        super().__init__(
            intents=intents,
            heartbeat_timeout=60.0,
            guild_ready_timeout=2.0,
            max_messages=1000,
            **kwargs
        )
    
    async def on_connect(self):
        """Called when bot connects to gateway."""
        print("Connected to Discord gateway")
    
    async def on_disconnect(self):
        """Called when bot disconnects from gateway."""
        print("Disconnected from Discord gateway")
    
    async def on_resumed(self):
        """Called when connection is resumed."""
        print("Connection resumed")
    
    async def setup_hook(self):
        """Called during bot setup."""
        print("Setting up bot...")
        # Add any async setup code here
        
        # Sync commands on startup
        if hasattr(self, 'sync_commands'):
            await self.sync_commands()

# Connection retry logic
async def run_bot_with_retry(bot, token, max_retries=5):
    """Run bot with automatic reconnection."""
    for attempt in range(max_retries):
        try:
            await bot.start(token)
            break
        except (disnake.ConnectionClosed, disnake.GatewayNotFound) as e:
            print(f"Connection failed (attempt {attempt + 1}/{max_retries}): {e}")
            if attempt < max_retries - 1:
                wait_time = 2 ** attempt  # Exponential backoff
                print(f"Retrying in {wait_time} seconds...")
                await asyncio.sleep(wait_time)
            else:
                print("Max retries exceeded. Bot failed to connect.")
                raise

# Shard-aware event handling
class ShardedBot(commands.AutoShardedBot):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
    
    async def on_shard_connect(self, shard_id):
        print(f"Shard {shard_id} connected")
    
    async def on_shard_disconnect(self, shard_id):
        print(f"Shard {shard_id} disconnected")
    
    async def on_shard_ready(self, shard_id):
        print(f"Shard {shard_id} is ready")
        shard = self.get_shard(shard_id)
        print(f"Shard {shard_id} latency: {shard.latency * 1000:.2f}ms")
    
    async def on_shard_resumed(self, shard_id):
        print(f"Shard {shard_id} resumed connection")

# Usage
if __name__ == "__main__":
    bot = CustomBot()
    
    # Run with retry logic
    asyncio.run(run_bot_with_retry(bot, 'YOUR_BOT_TOKEN'))

Install with Tessl CLI

npx tessl i tessl/pypi-disnake

docs

application-commands.md

automod.md

channels-messaging.md

client-bot.md

command-framework.md

error-handling.md

events-gateway.md

guild-management.md

index.md

interactions-ui.md

localization-i18n.md

permissions-security.md

polls.md

users-members.md

voice-audio.md

tile.json