A modern, easy-to-use, feature-rich async-ready API wrapper for Discord written in Python
—
Comprehensive guild (server) management including member management, role management, channel organization, permissions, guild-specific features like scheduled events, moderation, and administrative functionality for Discord servers.
Core guild representation with complete server information, member collections, and administrative capabilities.
class Guild:
def __init__(self): ...
id: int
name: str
icon: Optional[Asset]
icon_hash: Optional[str]
splash: Optional[Asset]
discovery_splash: Optional[Asset]
banner: Optional[Asset]
description: Optional[str]
owner_id: int
verification_level: VerificationLevel
default_notifications: NotificationLevel
explicit_content_filter: ContentFilter
features: List[str]
mfa_level: int
application_id: Optional[int]
system_channel_id: Optional[int]
system_channel_flags: SystemChannelFlags
rules_channel_id: Optional[int]
max_presences: Optional[int]
max_members: Optional[int]
vanity_url_code: Optional[str]
premium_tier: int
premium_subscription_count: Optional[int]
preferred_locale: str
public_updates_channel_id: Optional[int]
max_video_channel_users: Optional[int]
max_stage_video_channel_users: Optional[int]
approximate_member_count: Optional[int]
approximate_presence_count: Optional[int]
nsfw_level: NSFWLevel
premium_progress_bar_enabled: bool
@property
def owner(self) -> Optional[Member]:
"""Guild owner member object."""
@property
def members(self) -> List[Member]:
"""All members in the guild."""
@property
def channels(self) -> List[GuildChannel]:
"""All channels in the guild."""
@property
def roles(self) -> List[Role]:
"""All roles in the guild."""
@property
def emojis(self) -> List[Emoji]:
"""All custom emojis in the guild."""
@property
def stickers(self) -> List[GuildSticker]:
"""All custom stickers in the guild."""
@property
def voice_channels(self) -> List[VoiceChannel]:
"""All voice channels in the guild."""
@property
def stage_channels(self) -> List[StageChannel]:
"""All stage channels in the guild."""
@property
def category_channels(self) -> List[CategoryChannel]:
"""All category channels in the guild."""
@property
def text_channels(self) -> List[TextChannel]:
"""All text channels in the guild."""
@property
def news_channels(self) -> List[NewsChannel]:
"""All news channels in the guild."""
@property
def forum_channels(self) -> List[ForumChannel]:
"""All forum channels in the guild."""
async def fetch_member(self, user_id: int) -> Member:
"""
Fetch a specific member by user ID.
Parameters:
- user_id: Discord user ID
Returns:
Member object
"""
def get_member(self, user_id: int) -> Optional[Member]:
"""
Get a member from cache by user ID.
Parameters:
- user_id: Discord user ID
Returns:
Member object if cached
"""
async def fetch_members(
self,
*,
limit: int = 1000,
after: Optional[Union[Snowflake, datetime]] = None
) -> AsyncIterator[Member]:
"""
Fetch guild members with pagination.
Parameters:
- limit: Maximum members to fetch
- after: Fetch members after this user/time
Yields:
Member objects
"""
def get_channel(self, channel_id: int) -> Optional[GuildChannel]:
"""
Get a channel from cache by ID.
Parameters:
- channel_id: Discord channel ID
Returns:
Channel object if cached
"""
def get_role(self, role_id: int) -> Optional[Role]:
"""
Get a role by ID.
Parameters:
- role_id: Discord role ID
Returns:
Role object if found
"""
async def ban(
self,
user: Union[Snowflake, User],
*,
reason: Optional[str] = None,
delete_message_days: int = 1,
delete_message_seconds: Optional[int] = None
) -> None:
"""
Ban a user from the guild.
Parameters:
- user: User to ban
- reason: Reason for the ban
- delete_message_days: Days of messages to delete (0-7, deprecated)
- delete_message_seconds: Seconds of messages to delete (0-604800)
"""
async def unban(self, user: Snowflake, *, reason: Optional[str] = None) -> None:
"""
Unban a user from the guild.
Parameters:
- user: User to unban
- reason: Reason for the unban
"""
async def kick(self, user: Snowflake, *, reason: Optional[str] = None) -> None:
"""
Kick a user from the guild.
Parameters:
- user: User to kick
- reason: Reason for the kick
"""
async def edit(
self,
*,
name: str = ...,
description: Optional[str] = ...,
icon: Optional[bytes] = ...,
banner: Optional[bytes] = ...,
splash: Optional[bytes] = ...,
discovery_splash: Optional[bytes] = ...,
community: bool = ...,
afk_channel: Optional[VoiceChannel] = ...,
afk_timeout: int = ...,
owner: Member = ...,
verification_level: VerificationLevel = ...,
default_notifications: NotificationLevel = ...,
explicit_content_filter: ContentFilter = ...,
vanity_code: str = ...,
system_channel: Optional[TextChannel] = ...,
system_channel_flags: SystemChannelFlags = ...,
preferred_locale: str = ...,
rules_channel: Optional[TextChannel] = ...,
public_updates_channel: Optional[TextChannel] = ...,
premium_progress_bar_enabled: bool = ...,
discoverable: bool = ...,
invites_disabled: bool = ...,
dms_disabled: bool = ...,
reason: Optional[str] = None
) -> Guild:
"""
Edit guild properties.
Parameters:
- name: Guild name
- description: Guild description
- icon: Guild icon bytes
- banner: Guild banner bytes
- splash: Guild invite splash bytes
- discovery_splash: Guild discovery splash bytes
- community: Enable community features
- afk_channel: AFK voice channel
- afk_timeout: AFK timeout in seconds
- owner: Transfer ownership
- verification_level: Member verification level
- default_notifications: Default notification settings
- explicit_content_filter: Content filter level
- vanity_code: Custom invite code
- system_channel: System messages channel
- system_channel_flags: System channel settings
- preferred_locale: Guild language
- rules_channel: Rules channel
- public_updates_channel: Community updates channel
- premium_progress_bar_enabled: Show boost progress bar
- discoverable: Allow discovery
- invites_disabled: Disable invite creation
- dms_disabled: Disable DMs from members
- reason: Audit log reason
Returns:
Updated guild object
"""
async def leave(self) -> None:
"""Leave the guild."""
async def delete(self) -> None:
"""Delete the guild (owner only)."""Guild channel creation, modification, and organization capabilities.
class Guild:
async def create_text_channel(
self,
name: str,
*,
reason: Optional[str] = None,
category: Optional[CategoryChannel] = None,
position: int = ...,
topic: Optional[str] = None,
slowmode_delay: int = 0,
nsfw: bool = False,
news: bool = False,
overwrites: Optional[Dict[Union[Role, Member], PermissionOverwrite]] = None,
default_auto_archive_duration: int = 1440,
default_thread_slowmode_delay: int = 0
) -> TextChannel:
"""
Create a text channel.
Parameters:
- name: Channel name
- reason: Audit log reason
- category: Parent category
- position: Channel position
- topic: Channel topic
- slowmode_delay: Slowmode delay in seconds
- nsfw: Whether channel is NSFW
- news: Create as announcement channel
- overwrites: Permission overwrites
- default_auto_archive_duration: Default thread archive duration
- default_thread_slowmode_delay: Default thread slowmode delay
Returns:
Created text channel
"""
async def create_voice_channel(
self,
name: str,
*,
reason: Optional[str] = None,
category: Optional[CategoryChannel] = None,
position: int = ...,
bitrate: int = 64000,
user_limit: int = 0,
overwrites: Optional[Dict[Union[Role, Member], PermissionOverwrite]] = None,
rtc_region: Optional[str] = None,
video_quality_mode: VideoQualityMode = VideoQualityMode.auto
) -> VoiceChannel:
"""
Create a voice channel.
Parameters:
- name: Channel name
- reason: Audit log reason
- category: Parent category
- position: Channel position
- bitrate: Audio bitrate
- user_limit: Maximum users (0 = unlimited)
- overwrites: Permission overwrites
- rtc_region: Voice region
- video_quality_mode: Video quality setting
Returns:
Created voice channel
"""
async def create_stage_channel(
self,
name: str,
*,
reason: Optional[str] = None,
category: Optional[CategoryChannel] = None,
position: int = ...,
bitrate: int = 64000,
overwrites: Optional[Dict[Union[Role, Member], PermissionOverwrite]] = None,
rtc_region: Optional[str] = None
) -> StageChannel:
"""
Create a stage channel.
Parameters:
- name: Channel name
- reason: Audit log reason
- category: Parent category
- position: Channel position
- bitrate: Audio bitrate
- overwrites: Permission overwrites
- rtc_region: Voice region
Returns:
Created stage channel
"""
async def create_category_channel(
self,
name: str,
*,
reason: Optional[str] = None,
position: int = ...,
overwrites: Optional[Dict[Union[Role, Member], PermissionOverwrite]] = None
) -> CategoryChannel:
"""
Create a category channel.
Parameters:
- name: Category name
- reason: Audit log reason
- position: Category position
- overwrites: Permission overwrites
Returns:
Created category channel
"""
async def create_forum_channel(
self,
name: str,
*,
reason: Optional[str] = None,
category: Optional[CategoryChannel] = None,
position: int = ...,
topic: Optional[str] = None,
slowmode_delay: int = 0,
nsfw: bool = False,
overwrites: Optional[Dict[Union[Role, Member], PermissionOverwrite]] = None,
default_auto_archive_duration: int = 1440,
default_thread_slowmode_delay: int = 0,
default_sort_order: Optional[ThreadSortOrder] = None,
default_layout: ThreadLayout = ThreadLayout.not_set,
available_tags: Optional[List[ForumTag]] = None,
default_reaction_emoji: Optional[Union[str, Emoji, PartialEmoji]] = None,
require_tag: bool = False
) -> ForumChannel:
"""
Create a forum channel.
Parameters:
- name: Channel name
- reason: Audit log reason
- category: Parent category
- position: Channel position
- topic: Channel topic/guidelines
- slowmode_delay: Slowmode delay in seconds
- nsfw: Whether channel is NSFW
- overwrites: Permission overwrites
- default_auto_archive_duration: Default thread archive duration
- default_thread_slowmode_delay: Default thread slowmode delay
- default_sort_order: Default thread sorting
- default_layout: Default thread layout
- available_tags: Available post tags
- default_reaction_emoji: Default reaction emoji
- require_tag: Require tag for posts
Returns:
Created forum channel
"""Role creation, modification, and hierarchy management for guild permissions.
class Guild:
async def create_role(
self,
*,
name: str = "new role",
permissions: Permissions = ...,
colour: Union[Colour, int] = ...,
color: Union[Colour, int] = ...,
hoist: bool = False,
display_icon: Optional[Union[bytes, str]] = None,
unicode_emoji: Optional[str] = None,
mentionable: bool = False,
reason: Optional[str] = None
) -> Role:
"""
Create a new role.
Parameters:
- name: Role name
- permissions: Role permissions
- colour/color: Role color
- hoist: Show separately in member list
- display_icon: Role icon bytes or unicode emoji
- unicode_emoji: Unicode emoji for role icon
- mentionable: Allow role mentions
- reason: Audit log reason
Returns:
Created role
"""
@property
def default_role(self) -> Role:
"""The @everyone role."""
@property
def premium_subscriber_role(self) -> Optional[Role]:
"""The Nitro booster role."""
@property
def self_role(self) -> Optional[Role]:
"""Bot's highest role."""
def get_member_named(self, name: str) -> Optional[Member]:
"""
Get member by name or name#discriminator.
Parameters:
- name: Member name or name#discriminator
Returns:
Member if found
"""
async def estimate_pruned_members(
self,
*,
days: int,
roles: List[Role] = ...
) -> int:
"""
Estimate members that would be pruned.
Parameters:
- days: Days of inactivity
- roles: Roles to include in prune
Returns:
Estimated prune count
"""
async def prune_members(
self,
*,
days: int,
compute_prune_count: bool = True,
roles: List[Role] = ...,
reason: Optional[str] = None
) -> Optional[int]:
"""
Prune inactive members.
Parameters:
- days: Days of inactivity
- compute_prune_count: Return prune count
- roles: Roles to include in prune
- reason: Audit log reason
Returns:
Number of members pruned if compute_prune_count is True
"""
async def fetch_emojis(self) -> List[Emoji]:
"""
Fetch all custom emojis.
Returns:
List of guild emojis
"""
async def fetch_emoji(self, emoji_id: int) -> Emoji:
"""
Fetch a specific emoji by ID.
Parameters:
- emoji_id: Emoji ID
Returns:
Emoji object
"""
async def create_custom_emoji(
self,
*,
name: str,
image: bytes,
roles: List[Role] = ...,
reason: Optional[str] = None
) -> Emoji:
"""
Create a custom emoji.
Parameters:
- name: Emoji name
- image: Emoji image bytes
- roles: Roles that can use emoji
- reason: Audit log reason
Returns:
Created emoji
"""
async def fetch_stickers(self) -> List[GuildSticker]:
"""
Fetch all guild stickers.
Returns:
List of guild stickers
"""
async def fetch_sticker(self, sticker_id: int) -> GuildSticker:
"""
Fetch a specific sticker by ID.
Parameters:
- sticker_id: Sticker ID
Returns:
Sticker object
"""
async def create_sticker(
self,
*,
name: str,
description: str,
emoji: str,
file: File,
reason: Optional[str] = None
) -> GuildSticker:
"""
Create a custom sticker.
Parameters:
- name: Sticker name
- description: Sticker description
- emoji: Related unicode emoji
- file: Sticker image file
- reason: Audit log reason
Returns:
Created sticker
"""Advanced guild features including scheduled events, moderation, and community features.
class GuildScheduledEvent:
def __init__(self): ...
id: int
guild_id: int
channel_id: Optional[int]
creator_id: Optional[int]
name: str
description: Optional[str]
scheduled_start_time: datetime
scheduled_end_time: Optional[datetime]
privacy_level: GuildScheduledEventPrivacyLevel
status: GuildScheduledEventStatus
entity_type: GuildScheduledEventEntityType
entity_id: Optional[int]
entity_metadata: Optional[GuildScheduledEventMetadata]
creator: Optional[User]
user_count: Optional[int]
image: Optional[Asset]
@property
def guild(self) -> Optional[Guild]:
"""Guild the event belongs to."""
@property
def channel(self) -> Optional[GuildChannel]:
"""Channel the event is in."""
@property
def cover_image(self) -> Optional[Asset]:
"""Event cover image."""
async def edit(
self,
*,
name: str = ...,
description: Optional[str] = ...,
channel: Optional[GuildChannel] = ...,
privacy_level: GuildScheduledEventPrivacyLevel = ...,
status: GuildScheduledEventStatus = ...,
entity_type: GuildScheduledEventEntityType = ...,
scheduled_start_time: datetime = ...,
scheduled_end_time: Optional[datetime] = ...,
location: Optional[str] = ...,
image: Optional[bytes] = ...,
reason: Optional[str] = None
) -> GuildScheduledEvent:
"""
Edit the scheduled event.
Parameters:
- name: Event name
- description: Event description
- channel: Event channel
- privacy_level: Event privacy
- status: Event status
- entity_type: Event entity type
- scheduled_start_time: Start time
- scheduled_end_time: End time
- location: Event location (for external events)
- image: Event cover image
- reason: Audit log reason
Returns:
Updated event
"""
async def delete(self, *, reason: Optional[str] = None) -> None:
"""
Delete the scheduled event.
Parameters:
- reason: Audit log reason
"""
async def start(self, *, reason: Optional[str] = None) -> GuildScheduledEvent:
"""
Start the scheduled event.
Parameters:
- reason: Audit log reason
Returns:
Updated event
"""
async def end(self, *, reason: Optional[str] = None) -> GuildScheduledEvent:
"""
End the scheduled event.
Parameters:
- reason: Audit log reason
Returns:
Updated event
"""
class Guild:
async def fetch_scheduled_events(self) -> List[GuildScheduledEvent]:
"""
Fetch all scheduled events.
Returns:
List of scheduled events
"""
async def fetch_scheduled_event(self, event_id: int) -> GuildScheduledEvent:
"""
Fetch a specific scheduled event.
Parameters:
- event_id: Event ID
Returns:
Scheduled event
"""
async def create_scheduled_event(
self,
*,
name: str,
description: Optional[str] = None,
channel: Optional[GuildChannel] = None,
privacy_level: GuildScheduledEventPrivacyLevel = GuildScheduledEventPrivacyLevel.guild_only,
scheduled_start_time: datetime,
scheduled_end_time: Optional[datetime] = None,
entity_type: GuildScheduledEventEntityType = GuildScheduledEventEntityType.stage_instance,
location: Optional[str] = None,
image: Optional[bytes] = None,
reason: Optional[str] = None
) -> GuildScheduledEvent:
"""
Create a scheduled event.
Parameters:
- name: Event name
- description: Event description
- channel: Event channel
- privacy_level: Event privacy
- scheduled_start_time: Start time
- scheduled_end_time: End time
- entity_type: Event entity type
- location: Event location (for external events)
- image: Event cover image
- reason: Audit log reason
Returns:
Created event
"""
async def fetch_bans(self, *, limit: Optional[int] = None, before: Optional[Snowflake] = None, after: Optional[Snowflake] = None) -> AsyncIterator[BanEntry]:
"""
Fetch guild bans.
Parameters:
- limit: Maximum bans to fetch
- before: Fetch bans before this user
- after: Fetch bans after this user
Yields:
Ban entries
"""
async def fetch_ban(self, user: Snowflake) -> BanEntry:
"""
Fetch a specific ban.
Parameters:
- user: Banned user
Returns:
Ban entry
"""
async def fetch_invites(self) -> List[Invite]:
"""
Fetch all guild invites.
Returns:
List of invites
"""
async def fetch_integrations(self) -> List[Integration]:
"""
Fetch guild integrations.
Returns:
List of integrations
"""
async def fetch_webhooks(self) -> List[Webhook]:
"""
Fetch guild webhooks.
Returns:
List of webhooks
"""
async def audit_logs(
self,
*,
limit: int = 100,
before: Optional[Union[Snowflake, AuditLogEntry, datetime]] = None,
after: Optional[Union[Snowflake, AuditLogEntry, datetime]] = None,
oldest_first: Optional[bool] = None,
user: Optional[Snowflake] = None,
action: Optional[AuditLogAction] = None
) -> AsyncIterator[AuditLogEntry]:
"""
Fetch audit log entries.
Parameters:
- limit: Maximum entries to fetch
- before: Fetch entries before this entry/time
- after: Fetch entries after this entry/time
- oldest_first: Sort order
- user: Filter by user
- action: Filter by action type
Yields:
Audit log entries
"""
async def widget(self) -> Widget:
"""
Fetch guild widget.
Returns:
Guild widget
"""
async def chunk(self, *, cache: bool = True) -> List[Member]:
"""
Request all members from Discord.
Parameters:
- cache: Whether to cache members
Returns:
List of all members
"""
async def query_members(
self,
query: Optional[str] = None,
*,
limit: int = 5,
user_ids: Optional[List[int]] = None,
cache: bool = True
) -> List[Member]:
"""
Query guild members.
Parameters:
- query: Username query
- limit: Maximum members to return
- user_ids: Specific user IDs to fetch
- cache: Whether to cache members
Returns:
List of matching members
"""
async def change_voice_state(
self,
*,
channel: Optional[VoiceChannel],
self_mute: bool = False,
self_deaf: bool = False
) -> None:
"""
Change bot's voice state.
Parameters:
- channel: Voice channel to join (None to disconnect)
- self_mute: Whether to self-mute
- self_deaf: Whether to self-deafen
"""Helper class for creating guilds with predefined structure.
class GuildBuilder:
def __init__(self, name: str):
"""
Initialize guild builder.
Parameters:
- name: Guild name
"""
def add_text_channel(
self,
name: str,
*,
category: Optional[str] = None,
topic: Optional[str] = None,
nsfw: bool = False,
slowmode_delay: int = 0,
permissions: Optional[Dict[str, PermissionOverwrite]] = None
) -> GuildBuilder:
"""
Add a text channel to the guild.
Parameters:
- name: Channel name
- category: Parent category name
- topic: Channel topic
- nsfw: Whether channel is NSFW
- slowmode_delay: Slowmode delay
- permissions: Permission overwrites by role name
Returns:
Guild builder for chaining
"""
def add_voice_channel(
self,
name: str,
*,
category: Optional[str] = None,
bitrate: int = 64000,
user_limit: int = 0,
permissions: Optional[Dict[str, PermissionOverwrite]] = None
) -> GuildBuilder:
"""
Add a voice channel to the guild.
Parameters:
- name: Channel name
- category: Parent category name
- bitrate: Audio bitrate
- user_limit: User limit
- permissions: Permission overwrites by role name
Returns:
Guild builder for chaining
"""
def add_category(
self,
name: str,
*,
permissions: Optional[Dict[str, PermissionOverwrite]] = None
) -> GuildBuilder:
"""
Add a category channel to the guild.
Parameters:
- name: Category name
- permissions: Permission overwrites by role name
Returns:
Guild builder for chaining
"""
def add_role(
self,
name: str,
*,
permissions: Optional[Permissions] = None,
color: Optional[Union[Colour, int]] = None,
hoist: bool = False,
mentionable: bool = False
) -> GuildBuilder:
"""
Add a role to the guild.
Parameters:
- name: Role name
- permissions: Role permissions
- color: Role color
- hoist: Show separately in member list
- mentionable: Allow mentions
Returns:
Guild builder for chaining
"""
async def create(self, *, icon: Optional[bytes] = None) -> Guild:
"""
Create the guild with configured structure.
Parameters:
- icon: Guild icon bytes
Returns:
Created guild
"""import disnake
from disnake.ext import commands
bot = commands.Bot(command_prefix='!', intents=disnake.Intents.all())
@bot.command()
async def serverinfo(ctx):
"""Display server information."""
guild = ctx.guild
embed = disnake.Embed(title=guild.name, color=0x00ff00)
embed.set_thumbnail(url=guild.icon.url if guild.icon else None)
embed.add_field(name="Owner", value=guild.owner.mention, inline=True)
embed.add_field(name="Members", value=guild.member_count, inline=True)
embed.add_field(name="Channels", value=len(guild.channels), inline=True)
embed.add_field(name="Roles", value=len(guild.roles), inline=True)
embed.add_field(name="Boost Level", value=guild.premium_tier, inline=True)
embed.add_field(name="Boosts", value=guild.premium_subscription_count or 0, inline=True)
await ctx.send(embed=embed)
@bot.command()
async def createchannel(ctx, channel_type: str, *, name: str):
"""Create a new channel."""
if not ctx.author.guild_permissions.manage_channels:
return await ctx.send("You don't have permission to manage channels.")
guild = ctx.guild
if channel_type.lower() == "text":
channel = await guild.create_text_channel(name)
await ctx.send(f"Created text channel: {channel.mention}")
elif channel_type.lower() == "voice":
channel = await guild.create_voice_channel(name)
await ctx.send(f"Created voice channel: {channel.name}")
elif channel_type.lower() == "category":
channel = await guild.create_category_channel(name)
await ctx.send(f"Created category: {channel.name}")
else:
await ctx.send("Invalid channel type. Use: text, voice, or category")@bot.command()
async def ban(ctx, member: disnake.Member, *, reason="No reason provided"):
"""Ban a member from the server."""
if not ctx.author.guild_permissions.ban_members:
return await ctx.send("You don't have permission to ban members.")
if member.top_role >= ctx.author.top_role:
return await ctx.send("You cannot ban this member.")
await ctx.guild.ban(member, reason=reason)
await ctx.send(f"Banned {member} for: {reason}")
@bot.command()
async def kick(ctx, member: disnake.Member, *, reason="No reason provided"):
"""Kick a member from the server."""
if not ctx.author.guild_permissions.kick_members:
return await ctx.send("You don't have permission to kick members.")
if member.top_role >= ctx.author.top_role:
return await ctx.send("You cannot kick this member.")
await ctx.guild.kick(member, reason=reason)
await ctx.send(f"Kicked {member} for: {reason}")
@bot.command()
async def unban(ctx, user_id: int):
"""Unban a user by ID."""
if not ctx.author.guild_permissions.ban_members:
return await ctx.send("You don't have permission to unban members.")
user = disnake.Object(id=user_id)
await ctx.guild.unban(user)
await ctx.send(f"Unbanned user with ID {user_id}")
@bot.command()
async def prune(ctx, days: int = 7):
"""Prune inactive members."""
if not ctx.author.guild_permissions.kick_members:
return await ctx.send("You don't have permission to prune members.")
if not 1 <= days <= 30:
return await ctx.send("Days must be between 1 and 30.")
# Estimate prune count first
count = await ctx.guild.estimate_pruned_members(days=days)
if count == 0:
return await ctx.send("No members would be pruned.")
# Confirm with user
await ctx.send(f"This will prune {count} members. React with ✅ to confirm.")
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) == '✅'
try:
await bot.wait_for('reaction_add', timeout=30.0, check=check)
pruned = await ctx.guild.prune_members(days=days)
await ctx.send(f"Pruned {pruned} members.")
except asyncio.TimeoutError:
await ctx.send("Prune cancelled - no confirmation received.")@bot.command()
async def createrole(ctx, *, name: str):
"""Create a new role."""
if not ctx.author.guild_permissions.manage_roles:
return await ctx.send("You don't have permission to manage roles.")
role = await ctx.guild.create_role(name=name, reason=f"Created by {ctx.author}")
await ctx.send(f"Created role: {role.mention}")
@bot.command()
async def giverole(ctx, member: disnake.Member, role: disnake.Role):
"""Give a role to a member."""
if not ctx.author.guild_permissions.manage_roles:
return await ctx.send("You don't have permission to manage roles.")
if role >= ctx.author.top_role:
return await ctx.send("You cannot assign this role.")
if role in member.roles:
return await ctx.send(f"{member} already has the {role.name} role.")
await member.add_roles(role, reason=f"Added by {ctx.author}")
await ctx.send(f"Gave {role.name} to {member.mention}")
@bot.command()
async def removerole(ctx, member: disnake.Member, role: disnake.Role):
"""Remove a role from a member."""
if not ctx.author.guild_permissions.manage_roles:
return await ctx.send("You don't have permission to manage roles.")
if role >= ctx.author.top_role:
return await ctx.send("You cannot manage this role.")
if role not in member.roles:
return await ctx.send(f"{member} doesn't have the {role.name} role.")
await member.remove_roles(role, reason=f"Removed by {ctx.author}")
await ctx.send(f"Removed {role.name} from {member.mention}")from datetime import datetime, timedelta
@bot.slash_command(description="Create a scheduled event")
async def create_event(
inter: disnake.ApplicationCommandInteraction,
name: str,
description: str,
channel: disnake.VoiceChannel,
start_time: str, # Format: "YYYY-MM-DD HH:MM"
duration_hours: int = 2
):
"""Create a scheduled event in a voice channel."""
if not inter.author.guild_permissions.manage_events:
return await inter.response.send_message("You don't have permission to manage events.")
try:
# Parse start time
start_dt = datetime.strptime(start_time, "%Y-%m-%d %H:%M")
end_dt = start_dt + timedelta(hours=duration_hours)
event = await inter.guild.create_scheduled_event(
name=name,
description=description,
channel=channel,
scheduled_start_time=start_dt,
scheduled_end_time=end_dt,
entity_type=disnake.GuildScheduledEventEntityType.voice,
reason=f"Created by {inter.author}"
)
await inter.response.send_message(f"Created event: **{event.name}**\nStarts: <t:{int(start_dt.timestamp())}:F>")
except ValueError:
await inter.response.send_message("Invalid time format. Use: YYYY-MM-DD HH:MM")
@bot.slash_command(description="List upcoming events")
async def events(inter: disnake.ApplicationCommandInteraction):
"""List all scheduled events."""
events = await inter.guild.fetch_scheduled_events()
if not events:
return await inter.response.send_message("No scheduled events found.")
embed = disnake.Embed(title=f"Scheduled Events in {inter.guild.name}", color=0x00ff00)
for event in events:
status_emoji = {
disnake.GuildScheduledEventStatus.scheduled: "📅",
disnake.GuildScheduledEventStatus.active: "🔴",
disnake.GuildScheduledEventStatus.completed: "✅",
disnake.GuildScheduledEventStatus.cancelled: "❌"
}
embed.add_field(
name=f"{status_emoji.get(event.status, '📅')} {event.name}",
value=f"<t:{int(event.scheduled_start_time.timestamp())}:F>",
inline=False
)
await inter.response.send_message(embed=embed)@bot.command()
async def setup_server(ctx):
"""Set up a complete server structure."""
if not ctx.author.guild_permissions.administrator:
return await ctx.send("You need Administrator permission to set up the server.")
guild = ctx.guild
# Create roles
roles = {
"Moderator": {"color": 0xff0000, "permissions": disnake.Permissions(moderate_members=True, manage_messages=True)},
"Helper": {"color": 0x00ff00, "permissions": disnake.Permissions(manage_messages=True)},
"Member": {"color": 0x0099ff, "permissions": disnake.Permissions.none()}
}
created_roles = {}
for role_name, role_config in roles.items():
role = await guild.create_role(
name=role_name,
color=role_config["color"],
permissions=role_config["permissions"],
reason="Server setup"
)
created_roles[role_name] = role
await ctx.send(f"Created role: {role.mention}")
# Create categories and channels
# General category
general_cat = await guild.create_category_channel("General")
await guild.create_text_channel("general", category=general_cat)
await guild.create_text_channel("announcements", category=general_cat)
await guild.create_voice_channel("General Voice", category=general_cat)
# Staff category with permissions
staff_overwrites = {
guild.default_role: disnake.PermissionOverwrite(view_channel=False),
created_roles["Moderator"]: disnake.PermissionOverwrite(view_channel=True),
created_roles["Helper"]: disnake.PermissionOverwrite(view_channel=True)
}
staff_cat = await guild.create_category_channel("Staff", overwrites=staff_overwrites)
await guild.create_text_channel("staff-chat", category=staff_cat)
await guild.create_text_channel("moderation-logs", category=staff_cat)
await ctx.send("✅ Server setup complete!")Install with Tessl CLI
npx tessl i tessl/pypi-disnake