{"id":"53428ea7-14e4-4b3f-b927-af5ad6442bc0","shortId":"hwH2nx","kind":"skill","title":"discord-bot-architect","tagline":"Specialized skill for building production-ready Discord bots.","description":"# Discord Bot Architect\n\nSpecialized skill for building production-ready Discord bots.\nCovers Discord.js (JavaScript) and Pycord (Python), gateway intents,\nslash commands, interactive components, rate limiting, and sharding.\n\n## Principles\n\n- Slash commands over message parsing (Message Content Intent deprecated)\n- Acknowledge interactions within 3 seconds, always\n- Request only required intents (minimize privileged intents)\n- Handle rate limits gracefully with exponential backoff\n- Plan for sharding from the start (required at 2500+ guilds)\n- Use components (buttons, selects, modals) for rich UX\n- Test with guild commands first, deploy global when ready\n\n## Patterns\n\n### Discord.js v14 Foundation\n\nModern Discord bot setup with Discord.js v14 and slash commands\n\n**When to use**: Building Discord bots with JavaScript/TypeScript,Need full gateway connection with events,Building bots with complex interactions\n\n```javascript\n// src/index.js\nconst { Client, Collection, GatewayIntentBits, Events } = require('discord.js');\nconst fs = require('node:fs');\nconst path = require('node:path');\nrequire('dotenv').config();\n\n// Create client with minimal required intents\nconst client = new Client({\n  intents: [\n    GatewayIntentBits.Guilds,\n    // Add only what you need:\n    // GatewayIntentBits.GuildMessages,\n    // GatewayIntentBits.MessageContent,  // PRIVILEGED - avoid if possible\n  ]\n});\n\n// Load commands\nclient.commands = new Collection();\nconst commandsPath = path.join(__dirname, 'commands');\nconst commandFiles = fs.readdirSync(commandsPath).filter(f => f.endsWith('.js'));\n\nfor (const file of commandFiles) {\n  const filePath = path.join(commandsPath, file);\n  const command = require(filePath);\n  if ('data' in command && 'execute' in command) {\n    client.commands.set(command.data.name, command);\n  }\n}\n\n// Load events\nconst eventsPath = path.join(__dirname, 'events');\nconst eventFiles = fs.readdirSync(eventsPath).filter(f => f.endsWith('.js'));\n\nfor (const file of eventFiles) {\n  const filePath = path.join(eventsPath, file);\n  const event = require(filePath);\n  if (event.once) {\n    client.once(event.name, (...args) => event.execute(...args));\n  } else {\n    client.on(event.name, (...args) => event.execute(...args));\n  }\n}\n\nclient.login(process.env.DISCORD_TOKEN);\n```\n\n```javascript\n// src/commands/ping.js\nconst { SlashCommandBuilder } = require('discord.js');\n\nmodule.exports = {\n  data: new SlashCommandBuilder()\n    .setName('ping')\n    .setDescription('Replies with Pong!'),\n\n  async execute(interaction) {\n    const sent = await interaction.reply({\n      content: 'Pinging...',\n      fetchReply: true\n    });\n\n    const latency = sent.createdTimestamp - interaction.createdTimestamp;\n    await interaction.editReply(`Pong! Latency: ${latency}ms`);\n  }\n};\n```\n\n```javascript\n// src/events/interactionCreate.js\nconst { Events } = require('discord.js');\n\nmodule.exports = {\n  name: Events.InteractionCreate,\n  async execute(interaction) {\n    if (!interaction.isChatInputCommand()) return;\n\n    const command = interaction.client.commands.get(interaction.commandName);\n    if (!command) {\n      console.error(`No command matching ${interaction.commandName}`);\n      return;\n    }\n\n    try {\n      await command.execute(interaction);\n    } catch (error) {\n      console.error(error);\n      const reply = {\n        content: 'There was an error executing this command!',\n        ephemeral: true\n      };\n\n      if (interaction.replied || interaction.deferred) {\n        await interaction.followUp(reply);\n      } else {\n        await interaction.reply(reply);\n      }\n    }\n  }\n};\n```\n\n```javascript\n// src/deploy-commands.js\nconst { REST, Routes } = require('discord.js');\nconst fs = require('node:fs');\nconst path = require('node:path');\nrequire('dotenv').config();\n\nconst commands = [];\nconst commandsPath = path.join(__dirname, 'commands');\nconst commandFiles = fs.readdirSync(commandsPath).filter(f => f.endsWith('.js'));\n\nfor (const file of commandFiles) {\n  const command = require(path.join(commandsPath, file));\n  commands.push(command.data.toJSON());\n}\n\nconst rest = new REST().setToken(process.env.DISCORD_TOKEN);\n\n(async () => {\n  try {\n    console.log(`Refreshing ${commands.length} commands...`);\n\n    // Guild commands (instant, for testing)\n    // const data = await rest.put(\n    //   Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID),\n    //   { body: commands }\n    // );\n\n    // Global commands (can take up to 1 hour to propagate)\n    const data = await rest.put(\n      Routes.applicationCommands(process.env.CLIENT_ID),\n      { body: commands }\n    );\n\n    console.log(`Successfully registered ${data.length} commands`);\n  } catch (error) {\n    console.error(error);\n  }\n})();\n```\n\n### Structure\n\ndiscord-bot/\n├── src/\n│   ├── index.js           # Main entry point\n│   ├── deploy-commands.js # Command registration script\n│   ├── commands/          # Slash command handlers\n│   │   └── ping.js\n│   └── events/            # Event handlers\n│       ├── ready.js\n│       └── interactionCreate.js\n├── .env\n└── package.json\n\n### Pycord Bot Foundation\n\nDiscord bot with Pycord (Python) and application commands\n\n**When to use**: Building Discord bots with Python,Prefer async/await patterns,Need good slash command support\n\n```python\n# main.py\nimport os\nimport discord\nfrom discord.ext import commands\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\n# Configure intents - only enable what you need\nintents = discord.Intents.default()\n# intents.message_content = True  # PRIVILEGED - avoid if possible\n# intents.members = True          # PRIVILEGED\n\nbot = commands.Bot(\n    command_prefix=\"!\",  # Legacy, prefer slash commands\n    intents=intents\n)\n\n@bot.event\nasync def on_ready():\n    print(f\"Logged in as {bot.user}\")\n    # Sync commands (do this carefully - see sharp edges)\n    # await bot.sync_commands()\n\n# Slash command\n@bot.slash_command(name=\"ping\", description=\"Check bot latency\")\nasync def ping(ctx: discord.ApplicationContext):\n    latency = round(bot.latency * 1000)\n    await ctx.respond(f\"Pong! Latency: {latency}ms\")\n\n# Slash command with options\n@bot.slash_command(name=\"greet\", description=\"Greet a user\")\nasync def greet(\n    ctx: discord.ApplicationContext,\n    user: discord.Option(discord.Member, \"User to greet\"),\n    message: discord.Option(str, \"Custom message\", required=False)\n):\n    msg = message or \"Hello!\"\n    await ctx.respond(f\"{user.mention}, {msg}\")\n\n# Load cogs\nfor filename in os.listdir(\"./cogs\"):\n    if filename.endswith(\".py\"):\n        bot.load_extension(f\"cogs.{filename[:-3]}\")\n\nbot.run(os.environ[\"DISCORD_TOKEN\"])\n```\n\n```python\n# cogs/general.py\nimport discord\nfrom discord.ext import commands\n\nclass General(commands.Cog):\n    def __init__(self, bot):\n        self.bot = bot\n\n    @commands.slash_command(name=\"info\", description=\"Bot information\")\n    async def info(self, ctx: discord.ApplicationContext):\n        embed = discord.Embed(\n            title=\"Bot Info\",\n            description=\"A helpful Discord bot\",\n            color=discord.Color.blue()\n        )\n        embed.add_field(name=\"Servers\", value=len(self.bot.guilds))\n        embed.add_field(name=\"Latency\", value=f\"{round(self.bot.latency * 1000)}ms\")\n        await ctx.respond(embed=embed)\n\n    @commands.Cog.listener()\n    async def on_member_join(self, member: discord.Member):\n        # Requires Members intent (PRIVILEGED)\n        channel = member.guild.system_channel\n        if channel:\n            await channel.send(f\"Welcome {member.mention}!\")\n\ndef setup(bot):\n    bot.add_cog(General(bot))\n```\n\n### Structure\n\ndiscord-bot/\n├── main.py           # Main bot file\n├── cogs/             # Command groups\n│   └── general.py\n├── .env\n└── requirements.txt\n\n### Interactive Components Pattern\n\nUsing buttons, select menus, and modals for rich UX\n\n**When to use**: Need interactive user interfaces,Collecting user input beyond slash command options,Building menus, confirmations, or forms\n\n```javascript\n// Discord.js - Buttons and Select Menus\nconst {\n  SlashCommandBuilder,\n  ActionRowBuilder,\n  ButtonBuilder,\n  ButtonStyle,\n  StringSelectMenuBuilder,\n  ModalBuilder,\n  TextInputBuilder,\n  TextInputStyle\n} = require('discord.js');\n\nmodule.exports = {\n  data: new SlashCommandBuilder()\n    .setName('menu')\n    .setDescription('Shows an interactive menu'),\n\n  async execute(interaction) {\n    // Button row\n    const buttonRow = new ActionRowBuilder()\n      .addComponents(\n        new ButtonBuilder()\n          .setCustomId('confirm')\n          .setLabel('Confirm')\n          .setStyle(ButtonStyle.Primary),\n        new ButtonBuilder()\n          .setCustomId('cancel')\n          .setLabel('Cancel')\n          .setStyle(ButtonStyle.Danger),\n        new ButtonBuilder()\n          .setLabel('Documentation')\n          .setURL('https://discord.js.org')\n          .setStyle(ButtonStyle.Link)  // Link buttons don't emit events\n      );\n\n    // Select menu row (one per row, takes all 5 slots)\n    const selectRow = new ActionRowBuilder()\n      .addComponents(\n        new StringSelectMenuBuilder()\n          .setCustomId('select-role')\n          .setPlaceholder('Select a role')\n          .setMinValues(1)\n          .setMaxValues(3)\n          .addOptions([\n            { label: 'Developer', value: 'dev', emoji: '💻' },\n            { label: 'Designer', value: 'design', emoji: '🎨' },\n            { label: 'Community', value: 'community', emoji: '🎉' }\n          ])\n      );\n\n    await interaction.reply({\n      content: 'Choose an option:',\n      components: [buttonRow, selectRow]\n    });\n\n    // Collect responses\n    const collector = interaction.channel.createMessageComponentCollector({\n      filter: i => i.user.id === interaction.user.id,\n      time: 60_000  // 60 seconds timeout\n    });\n\n    collector.on('collect', async i => {\n      if (i.customId === 'confirm') {\n        await i.update({ content: 'Confirmed!', components: [] });\n        collector.stop();\n      } else if (i.customId === 'cancel') {\n        await i.update({ content: 'Cancelled', components: [] });\n        collector.stop();\n      } else if (i.customId === 'select-role') {\n        await i.update({ content: `You selected: ${i.values.join(', ')}` });\n      }\n    });\n  }\n};\n```\n\n```javascript\n// Modals (forms)\nmodule.exports = {\n  data: new SlashCommandBuilder()\n    .setName('feedback')\n    .setDescription('Submit feedback'),\n\n  async execute(interaction) {\n    const modal = new ModalBuilder()\n      .setCustomId('feedback-modal')\n      .setTitle('Submit Feedback');\n\n    const titleInput = new TextInputBuilder()\n      .setCustomId('feedback-title')\n      .setLabel('Title')\n      .setStyle(TextInputStyle.Short)\n      .setRequired(true)\n      .setMaxLength(100);\n\n    const bodyInput = new TextInputBuilder()\n      .setCustomId('feedback-body')\n      .setLabel('Your feedback')\n      .setStyle(TextInputStyle.Paragraph)\n      .setRequired(true)\n      .setMaxLength(1000)\n      .setPlaceholder('Describe your feedback...');\n\n    modal.addComponents(\n      new ActionRowBuilder().addComponents(titleInput),\n      new ActionRowBuilder().addComponents(bodyInput)\n    );\n\n    // Show modal - MUST be first response\n    await interaction.showModal(modal);\n  }\n};\n\n// Handle modal submission in interactionCreate\nif (interaction.isModalSubmit()) {\n  if (interaction.customId === 'feedback-modal') {\n    const title = interaction.fields.getTextInputValue('feedback-title');\n    const body = interaction.fields.getTextInputValue('feedback-body');\n\n    await interaction.reply({\n      content: `Thanks for your feedback!\\n**${title}**\\n${body}`,\n      ephemeral: true\n    });\n  }\n}\n```\n\n```python\n# Pycord - Buttons and Views\nimport discord\n\nclass ConfirmView(discord.ui.View):\n    def __init__(self):\n        super().__init__(timeout=60)\n        self.value = None\n\n    @discord.ui.button(label=\"Confirm\", style=discord.ButtonStyle.green)\n    async def confirm(self, button, interaction):\n        self.value = True\n        await interaction.response.edit_message(content=\"Confirmed!\", view=None)\n        self.stop()\n\n    @discord.ui.button(label=\"Cancel\", style=discord.ButtonStyle.red)\n    async def cancel(self, button, interaction):\n        self.value = False\n        await interaction.response.edit_message(content=\"Cancelled\", view=None)\n        self.stop()\n\n@bot.slash_command(name=\"confirm\")\nasync def confirm_cmd(ctx: discord.ApplicationContext):\n    view = ConfirmView()\n    await ctx.respond(\"Are you sure?\", view=view)\n\n    await view.wait()  # Wait for user interaction\n    if view.value is None:\n        await ctx.followup.send(\"Timed out\")\n\n# Select Menu\nclass RoleSelect(discord.ui.Select):\n    def __init__(self):\n        options = [\n            discord.SelectOption(label=\"Developer\", value=\"dev\", emoji=\"💻\"),\n            discord.SelectOption(label=\"Designer\", value=\"design\", emoji=\"🎨\"),\n        ]\n        super().__init__(\n            placeholder=\"Select roles...\",\n            min_values=1,\n            max_values=2,\n            options=options\n        )\n\n    async def callback(self, interaction):\n        await interaction.response.send_message(\n            f\"You selected: {', '.join(self.values)}\",\n            ephemeral=True\n        )\n\nclass RoleView(discord.ui.View):\n    def __init__(self):\n        super().__init__()\n        self.add_item(RoleSelect())\n\n# Modal\nclass FeedbackModal(discord.ui.Modal):\n    def __init__(self):\n        super().__init__(title=\"Submit Feedback\")\n\n        self.add_item(discord.ui.InputText(\n            label=\"Title\",\n            style=discord.InputTextStyle.short,\n            required=True,\n            max_length=100\n        ))\n        self.add_item(discord.ui.InputText(\n            label=\"Feedback\",\n            style=discord.InputTextStyle.long,\n            required=True,\n            max_length=1000\n        ))\n\n    async def callback(self, interaction):\n        title = self.children[0].value\n        body = self.children[1].value\n        await interaction.response.send_message(\n            f\"Thanks!\\n**{title}**\\n{body}\",\n            ephemeral=True\n        )\n\n@bot.slash_command(name=\"feedback\")\nasync def feedback(ctx: discord.ApplicationContext):\n    await ctx.send_modal(FeedbackModal())\n```\n\n### Limits\n\n- 5 ActionRows per message/modal\n- 5 buttons per ActionRow\n- 1 select menu per ActionRow (takes all 5 slots)\n- 5 select menus max per message\n- 25 options per select menu\n- Modal must be first response (cannot defer first)\n\n### Deferred Response Pattern\n\nHandle slow operations without timing out\n\n**When to use**: Operation takes more than 3 seconds,Database queries, API calls, LLM responses,File processing or generation\n\n```javascript\n// Discord.js - Deferred response\nmodule.exports = {\n  data: new SlashCommandBuilder()\n    .setName('slow-task')\n    .setDescription('Performs a slow operation'),\n\n  async execute(interaction) {\n    // Defer immediately - you have 3 seconds!\n    await interaction.deferReply();\n    // For ephemeral: await interaction.deferReply({ ephemeral: true });\n\n    try {\n      // Now you have 15 minutes to complete\n      const result = await slowDatabaseQuery();\n      const aiResponse = await callOpenAI(result);\n\n      // Edit the deferred reply\n      await interaction.editReply({\n        content: `Result: ${aiResponse}`,\n        embeds: [resultEmbed]\n      });\n    } catch (error) {\n      await interaction.editReply({\n        content: 'An error occurred while processing your request.'\n      });\n    }\n  }\n};\n\n// For components (buttons, select menus)\ncollector.on('collect', async i => {\n  await i.deferUpdate();  // Acknowledge without visual change\n  // Or: await i.deferReply({ ephemeral: true });\n\n  const result = await slowOperation();\n  await i.editReply({ content: result });\n});\n```\n\n```python\n# Pycord - Deferred response\n@bot.slash_command(name=\"slow-task\")\nasync def slow_task(ctx: discord.ApplicationContext):\n    # Defer immediately\n    await ctx.defer()\n    # For ephemeral: await ctx.defer(ephemeral=True)\n\n    try:\n        result = await slow_database_query()\n        ai_response = await call_openai(result)\n\n        await ctx.followup.send(f\"Result: {ai_response}\")\n    except Exception as e:\n        await ctx.followup.send(\"An error occurred\")\n```\n\n### Timing\n\n- Initial_response: 3 seconds\n- Deferred_followup: 15 minutes\n- Ephemeral_note: Can only be set on initial response, not changed later\n\n### Embed Builder Pattern\n\nRich embedded messages for professional-looking content\n\n**When to use**: Displaying formatted information,Status updates, help menus, logs,Data with structure (fields, images)\n\n```javascript\nconst { EmbedBuilder, Colors } = require('discord.js');\n\n// Basic embed\nconst embed = new EmbedBuilder()\n  .setColor(Colors.Blue)\n  .setTitle('Bot Status')\n  .setURL('https://example.com')\n  .setAuthor({\n    name: 'Bot Name',\n    iconURL: client.user.displayAvatarURL()\n  })\n  .setDescription('Current status and statistics')\n  .addFields(\n    { name: 'Servers', value: `${client.guilds.cache.size}`, inline: true },\n    { name: 'Users', value: `${client.users.cache.size}`, inline: true },\n    { name: 'Uptime', value: formatUptime(), inline: true }\n  )\n  .setThumbnail(client.user.displayAvatarURL())\n  .setImage('https://example.com/banner.png')\n  .setTimestamp()\n  .setFooter({\n    text: 'Requested by User',\n    iconURL: interaction.user.displayAvatarURL()\n  });\n\nawait interaction.reply({ embeds: [embed] });\n\n// Multiple embeds (max 10)\nawait interaction.reply({ embeds: [embed1, embed2, embed3] });\n```\n\n```python\n# Pycord\nembed = discord.Embed(\n    title=\"Bot Status\",\n    description=\"Current status and statistics\",\n    color=discord.Color.blue(),\n    url=\"https://example.com\"\n)\nembed.set_author(\n    name=\"Bot Name\",\n    icon_url=bot.user.display_avatar.url\n)\nembed.add_field(name=\"Servers\", value=len(bot.guilds), inline=True)\nembed.add_field(name=\"Users\", value=len(bot.users), inline=True)\nembed.set_thumbnail(url=bot.user.display_avatar.url)\nembed.set_image(url=\"https://example.com/banner.png\")\nembed.set_footer(text=\"Requested by User\", icon_url=ctx.author.display_avatar.url)\nembed.timestamp = discord.utils.utcnow()\n\nawait ctx.respond(embed=embed)\n```\n\n### Limits\n\n- 10 embeds per message\n- 6000 characters total across all embeds\n- 256 characters for title\n- 4096 characters for description\n- 25 fields per embed\n- 256 characters per field name\n- 1024 characters per field value\n\n### Rate Limit Handling Pattern\n\nGracefully handle Discord API rate limits\n\n**When to use**: High-volume operations,Bulk messaging or role assignments,Any repeated API calls\n\n```javascript\n// Discord.js handles rate limits automatically, but for custom handling:\nconst { REST } = require('discord.js');\n\nconst rest = new REST({ version: '10' })\n  .setToken(process.env.DISCORD_TOKEN);\n\nrest.on('rateLimited', (info) => {\n  console.log(`Rate limited! Retry after ${info.retryAfter}ms`);\n  console.log(`Route: ${info.route}`);\n  console.log(`Global: ${info.global}`);\n});\n\n// Queue pattern for bulk operations\nclass RateLimitQueue {\n  constructor() {\n    this.queue = [];\n    this.processing = false;\n    this.requestsPerSecond = 40; // Safe margin below 50\n  }\n\n  async add(operation) {\n    return new Promise((resolve, reject) => {\n      this.queue.push({ operation, resolve, reject });\n      this.process();\n    });\n  }\n\n  async process() {\n    if (this.processing || this.queue.length === 0) return;\n    this.processing = true;\n\n    while (this.queue.length > 0) {\n      const { operation, resolve, reject } = this.queue.shift();\n\n      try {\n        const result = await operation();\n        resolve(result);\n      } catch (error) {\n        reject(error);\n      }\n\n      // Throttle: ~40 requests per second\n      await new Promise(r => setTimeout(r, 1000 / this.requestsPerSecond));\n    }\n\n    this.processing = false;\n  }\n}\n\nconst queue = new RateLimitQueue();\n\n// Usage: Send 200 messages without hitting rate limits\nfor (const user of users) {\n  await queue.add(() => user.send('Welcome!'));\n}\n```\n\n```python\n# Pycord/discord.py handles rate limits automatically\n# For custom handling:\nimport asyncio\nfrom collections import deque\n\nclass RateLimitQueue:\n    def __init__(self, requests_per_second=40):\n        self.queue = deque()\n        self.processing = False\n        self.delay = 1 / requests_per_second\n\n    async def add(self, coro):\n        future = asyncio.Future()\n        self.queue.append((coro, future))\n        if not self.processing:\n            asyncio.create_task(self._process())\n        return await future\n\n    async def _process(self):\n        self.processing = True\n        while self.queue:\n            coro, future = self.queue.popleft()\n            try:\n                result = await coro\n                future.set_result(result)\n            except Exception as e:\n                future.set_exception(e)\n            await asyncio.sleep(self.delay)\n        self.processing = False\n\nqueue = RateLimitQueue()\n\n# Usage\nfor member in guild.members:\n    await queue.add(member.send(\"Welcome!\"))\n```\n\n### Rate_limits\n\n- Global: 50 requests per second\n- Gateway: 120 requests per 60 seconds\n- Specific: Messages to same channel: 5/5s, Bulk delete: 1/1s, Guild member requests: varies by guild size\n\n### Sharding Pattern\n\nScale bots to 2500+ servers with sharding\n\n**When to use**: Bot approaching 2500 guilds (required),Want horizontal scaling,Memory optimization for large bots\n\n```javascript\n// Discord.js Sharding Manager\n// shard.js (main entry)\nconst { ShardingManager } = require('discord.js');\n\nconst manager = new ShardingManager('./bot.js', {\n  token: process.env.DISCORD_TOKEN,\n  totalShards: 'auto',  // Discord determines optimal count\n  // Or specify: totalShards: 4\n});\n\nmanager.on('shardCreate', shard => {\n  console.log(`Launched shard ${shard.id}`);\n\n  shard.on('ready', () => {\n    console.log(`Shard ${shard.id} ready`);\n  });\n\n  shard.on('disconnect', () => {\n    console.log(`Shard ${shard.id} disconnected`);\n  });\n});\n\nmanager.spawn();\n\n// bot.js - Modified for sharding\nconst { Client } = require('discord.js');\n\nconst client = new Client({ intents: [...] });\n\n// Get shard info\nclient.on('ready', () => {\n  console.log(`Shard ${client.shard.ids[0]} ready with ${client.guilds.cache.size} guilds`);\n});\n\n// Cross-shard data\nasync function getTotalGuilds() {\n  const results = await client.shard.fetchClientValues('guilds.cache.size');\n  return results.reduce((acc, count) => acc + count, 0);\n}\n\n// Broadcast to all shards\nasync function broadcastMessage(channelId, message) {\n  await client.shard.broadcastEval(\n    (c, { channelId, message }) => {\n      const channel = c.channels.cache.get(channelId);\n      if (channel) channel.send(message);\n    },\n    { context: { channelId, message } }\n  );\n}\n```\n\n```python\n# Pycord - AutoShardedBot\nimport discord\nfrom discord.ext import commands\n\n# Automatically handles sharding\nbot = commands.AutoShardedBot(\n    command_prefix=\"!\",\n    intents=discord.Intents.default(),\n    shard_count=None  # Auto-determine\n)\n\n@bot.event\nasync def on_ready():\n    print(f\"Logged in on {len(bot.shards)} shards\")\n    for shard_id, shard in bot.shards.items():\n        print(f\"Shard {shard_id}: {shard.latency * 1000:.2f}ms\")\n\n@bot.event\nasync def on_shard_ready(shard_id):\n    print(f\"Shard {shard_id} is ready\")\n\n# Get guilds per shard\nfor shard_id, guilds in bot.guilds_by_shard().items():\n    print(f\"Shard {shard_id}: {len(guilds)} guilds\")\n```\n\n### Scaling_guide\n\n- 1-2500 guilds: No sharding required\n- 2500+ guilds: Sharding required by Discord\n- Recommended: ~1000 guilds per shard\n- Memory: Each shard runs in separate process\n\n## Sharp Edges\n\n### Interaction Timeout (3 Second Rule)\n\nSeverity: CRITICAL\n\nSituation: Handling slash commands, buttons, select menus, or modals\n\nSymptoms:\nUser sees \"This interaction failed\" or \"The application did not respond.\"\nCommand works locally but fails in production.\nSlow operations never complete.\n\nWhy this breaks:\nDiscord requires ALL interactions to be acknowledged within 3 seconds:\n- Slash commands\n- Button clicks\n- Select menu selections\n- Context menu commands\n\nIf you do ANY slow operation (database, API, file I/O) before responding,\nyou'll miss the window. Discord shows an error even if your bot processes\nthe request correctly afterward.\n\nAfter acknowledgment, you have 15 minutes for follow-up responses.\n\nRecommended fix:\n\n## Acknowledge immediately, process later\n\n```javascript\n// Discord.js - Defer for slow operations\nmodule.exports = {\n  async execute(interaction) {\n    // DEFER IMMEDIATELY - before any slow operation\n    await interaction.deferReply();\n    // For ephemeral: await interaction.deferReply({ ephemeral: true });\n\n    // Now you have 15 minutes\n    const result = await slowDatabaseQuery();\n    const aiResponse = await callLLM(result);\n\n    // Edit the deferred reply\n    await interaction.editReply(`Result: ${aiResponse}`);\n  }\n};\n```\n\n```python\n# Pycord\n@bot.slash_command()\nasync def slow_command(ctx):\n    await ctx.defer()  # Acknowledge immediately\n    # await ctx.defer(ephemeral=True)  # For private response\n\n    result = await slow_operation()\n    await ctx.followup.send(f\"Result: {result}\")\n```\n\n## For components (buttons, menus)\n\n```javascript\n// If you're updating the message\nawait interaction.deferUpdate();\n\n// If you're sending a new response\nawait interaction.deferReply({ ephemeral: true });\n```\n\n### Missing Privileged Intent Configuration\n\nSeverity: CRITICAL\n\nSituation: Bot needs member data, presences, or message content\n\nSymptoms:\nMembers intent: member lists empty, on_member_join doesn't fire\nPresences intent: statuses always unknown/offline\nMessage content intent: message.content is empty string\n\nWhy this breaks:\nDiscord has 3 privileged intents that require manual enablement:\n1. **GUILD_MEMBERS** - Member join/leave, member lists\n2. **GUILD_PRESENCES** - Online status, activities\n3. **MESSAGE_CONTENT** - Read message text (deprecated for commands)\n\nThese must be:\n1. Enabled in Discord Developer Portal > Bot > Privileged Gateway Intents\n2. Requested in your bot code\n\nAt 100+ servers, you need Discord verification to keep using them.\n\nRecommended fix:\n\n## Step 1: Enable in Developer Portal\n\n```\n1. Go to https://discord.com/developers/applications\n2. Select your application\n3. Go to Bot section\n4. Scroll to Privileged Gateway Intents\n5. Toggle ON the intents you need\n```\n\n## Step 2: Request in code\n\n```javascript\n// Discord.js\nconst { Client, GatewayIntentBits } = require('discord.js');\n\nconst client = new Client({\n  intents: [\n    GatewayIntentBits.Guilds,\n    GatewayIntentBits.GuildMembers,       // PRIVILEGED\n    // GatewayIntentBits.GuildPresences,  // PRIVILEGED\n    // GatewayIntentBits.MessageContent,  // PRIVILEGED - avoid!\n  ]\n});\n```\n\n```python\n# Pycord\nintents = discord.Intents.default()\nintents.members = True       # PRIVILEGED\n# intents.presences = True   # PRIVILEGED\n# intents.message_content = True  # PRIVILEGED - avoid!\n\nbot = commands.Bot(intents=intents)\n```\n\n## Avoid Message Content Intent if possible\n\nUse slash commands, buttons, and modals instead of message parsing.\nThese don't require the Message Content intent.\n\n### Command Registration Rate Limited\n\nSeverity: HIGH\n\nSituation: Registering slash commands\n\nSymptoms:\nCommands not appearing. 429 errors when deploying.\n\"You are being rate limited\" messages.\nCommands appear for some guilds but not others.\n\nWhy this breaks:\nCommand registration is rate limited:\n- Global commands: 200 creates/day, updates take up to 1 hour to propagate\n- Guild commands: 200 creates/day per guild, instant update\n\nCommon mistakes:\n- Registering commands on every bot startup\n- Registering in every guild separately\n- Making changes in a loop without delays\n\nRecommended fix:\n\n## Use a separate deploy script (not on startup)\n\n```javascript\n// deploy-commands.js - Run manually, not on bot start\nconst { REST, Routes } = require('discord.js');\n\nconst rest = new REST().setToken(process.env.DISCORD_TOKEN);\n\nasync function deploy() {\n  // For development: Guild commands (instant)\n  if (process.env.GUILD_ID) {\n    await rest.put(\n      Routes.applicationGuildCommands(\n        process.env.CLIENT_ID,\n        process.env.GUILD_ID\n      ),\n      { body: commands }\n    );\n    console.log('Guild commands deployed instantly');\n  }\n\n  // For production: Global commands (up to 1 hour)\n  else {\n    await rest.put(\n      Routes.applicationCommands(process.env.CLIENT_ID),\n      { body: commands }\n    );\n    console.log('Global commands deployed (may take up to 1 hour)');\n  }\n}\n\ndeploy();\n```\n\n```python\n# Pycord - Don't sync on every startup\n@bot.event\nasync def on_ready():\n    # DON'T DO THIS:\n    # await bot.sync_commands()\n\n    print(f\"Ready! Commands should already be registered.\")\n\n# Instead, sync manually or use a flag\nif __name__ == \"__main__\":\n    if \"--sync\" in sys.argv:\n        # Only sync when explicitly requested\n        bot.sync_commands_on_start = True\n    bot.run(token)\n```\n\n## Testing workflow\n\n1. Use guild commands during development (instant updates)\n2. Only deploy global commands when ready for production\n3. Run deploy script manually, not on every restart\n\n### Bot Token Exposed\n\nSeverity: CRITICAL\n\nSituation: Storing or sharing bot token\n\nSymptoms:\nUnauthorized actions from your bot.\nBot joins random servers.\nBot sends spam or malicious content.\n\"Invalid token\" after Discord invalidates it.\n\nWhy this breaks:\nYour bot token provides FULL control over your bot. Attackers can:\n- Send messages as your bot\n- Join servers, create invites\n- Access all data your bot can access\n- Potentially take over servers where bot has admin\n\nDiscord actively scans GitHub for exposed tokens and invalidates them.\nCommon exposure points:\n- Committed to Git\n- Shared in Discord itself\n- In client-side code\n- In public screenshots\n\nRecommended fix:\n\n## Never hardcode tokens\n\n```javascript\n// BAD - never do this\nconst token = 'MTIzNDU2Nzg5MDEyMzQ1Njc4.ABCDEF.xyz...';\n\n// GOOD - environment variables\nrequire('dotenv').config();\nclient.login(process.env.DISCORD_TOKEN);\n```\n\n## Use .gitignore\n\n```\n# .gitignore\n.env\n.env.local\nconfig.json\n```\n\n## If token is exposed\n\n1. Go to Developer Portal immediately\n2. Regenerate the token\n3. Update all deployments\n4. Review bot activity for unauthorized actions\n5. Check git history and force push to remove if needed\n\n## Use environment variables properly\n\n```bash\n# .env (never commit)\nDISCORD_TOKEN=your_token_here\nCLIENT_ID=your_client_id\n```\n\n```javascript\n// Load with dotenv\nrequire('dotenv').config();\nconst token = process.env.DISCORD_TOKEN;\n```\n\n### Bot Missing applications.commands Scope\n\nSeverity: HIGH\n\nSituation: Slash commands not appearing for users\n\nSymptoms:\nBot is in server but slash commands don't show up.\nTyping / shows no commands from your bot.\nCommands worked in development server but not others.\n\nWhy this breaks:\nDiscord has two important OAuth scopes:\n- `bot` - Traditional bot permissions (messages, reactions, etc.)\n- `applications.commands` - Slash command permissions\n\nMany bots were invited with only the `bot` scope before slash commands\nexisted. They need to be re-invited with both scopes.\n\nRecommended fix:\n\n## Generate correct invite URL\n\n```\nhttps://discord.com/api/oauth2/authorize\n  ?client_id=YOUR_CLIENT_ID\n  &permissions=0\n  &scope=bot%20applications.commands\n```\n\n## In Discord Developer Portal\n\n1. Go to OAuth2 > URL Generator\n2. Select BOTH:\n   - `bot`\n   - `applications.commands`\n3. Select required bot permissions\n4. Use generated URL\n\n## Re-invite without kicking\n\nUsers can use the new invite URL even if bot is already in server.\nThis adds the new scope without removing the bot.\n\n```javascript\n// Generate invite URL in code\nconst inviteUrl = client.generateInvite({\n  scopes: ['bot', 'applications.commands'],\n  permissions: [\n    'SendMessages',\n    'EmbedLinks',\n    // Add other needed permissions\n  ]\n});\n```\n\n### Global Commands Not Appearing Immediately\n\nSeverity: MEDIUM\n\nSituation: Deploying global slash commands\n\nSymptoms:\nCommands don't appear after deployment.\nGuild commands work but global commands don't.\nCommands appear after an hour.\n\nWhy this breaks:\nGlobal commands can take up to 1 hour to propagate to all Discord servers.\nThis is by design for Discord's caching and CDN.\n\nGuild commands are instant but only work in that specific guild.\n\nRecommended fix:\n\n## Development: Use guild commands\n\n```javascript\n// Instant updates for testing\nawait rest.put(\n  Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID),\n  { body: commands }\n);\n```\n\n## Production: Deploy global commands during off-peak\n\n```javascript\n// Takes up to 1 hour to propagate\nawait rest.put(\n  Routes.applicationCommands(CLIENT_ID),\n  { body: commands }\n);\n```\n\n## Workflow\n\n1. Develop and test with guild commands (instant)\n2. When ready, deploy global commands\n3. Wait up to 1 hour for propagation\n4. Don't deploy global commands frequently\n\n### Frequent Gateway Disconnections\n\nSeverity: MEDIUM\n\nSituation: Bot randomly goes offline or misses events\n\nSymptoms:\nBot shows as offline intermittently.\nEvents are missed (member joins, messages).\nReconnection messages in logs.\n\nWhy this breaks:\nDiscord gateway requires regular heartbeats. Issues:\n- Blocking operations prevent heartbeat\n- Network instability\n- Memory pressure causing GC pauses\n- Too many guilds without sharding (2500+ requires sharding)\n\nRecommended fix:\n\n## Never block the event loop\n\n```javascript\n// BAD - blocks event loop\nconst data = fs.readFileSync('file.json');\n\n// GOOD - async\nconst data = await fs.promises.readFile('file.json');\n```\n\n## Handle reconnections gracefully\n\n```javascript\nclient.on('shardResume', (id, replayedEvents) => {\n  console.log(`Shard ${id} resumed, replayed ${replayedEvents} events`);\n});\n\nclient.on('shardDisconnect', (event, id) => {\n  console.log(`Shard ${id} disconnected`);\n});\n\nclient.on('shardReconnecting', (id) => {\n  console.log(`Shard ${id} reconnecting...`);\n});\n```\n\n## Implement sharding at scale\n\n```javascript\n// Required at 2500+ guilds\nconst manager = new ShardingManager('./bot.js', {\n  token: process.env.DISCORD_TOKEN,\n  totalShards: 'auto'\n});\nmanager.spawn();\n```\n\n### Modal Must Be First Response\n\nSeverity: MEDIUM\n\nSituation: Showing a modal from a slash command or button\n\nSymptoms:\n\"Interaction has already been acknowledged\" error.\nModal doesn't appear.\nWorks sometimes but not others.\n\nWhy this breaks:\nModals have a special requirement: showing a modal MUST be the first\nresponse to an interaction. You cannot:\n- defer() then showModal()\n- reply() then showModal()\n- Think for more than 3 seconds then showModal()\n\nRecommended fix:\n\n## Show modal immediately\n\n```javascript\n// CORRECT - modal is first response\nasync execute(interaction) {\n  const modal = new ModalBuilder()\n    .setCustomId('my-modal')\n    .setTitle('Input Form');\n\n  // Show immediately - no defer, no reply first\n  await interaction.showModal(modal);\n}\n```\n\n```javascript\n// WRONG - deferred first\nasync execute(interaction) {\n  await interaction.deferReply();  // CAN'T DO THIS\n  await interaction.showModal(modal);  // Will fail\n}\n```\n\n## If you need to check something first\n\n```javascript\nasync execute(interaction) {\n  // Quick sync check is OK (under 3 seconds)\n  if (!hasPermission(interaction.user.id)) {\n    return interaction.reply({\n      content: 'No permission',\n      ephemeral: true\n    });\n  }\n\n  // Show modal (still first interaction response for this path)\n  await interaction.showModal(modal);\n}\n```\n\n## Validation Checks\n\n### Hardcoded Discord Token\n\nSeverity: ERROR\n\nDiscord tokens must never be hardcoded\n\nMessage: Hardcoded Discord token detected. Use environment variables.\n\n### Token Variable Assignment\n\nSeverity: ERROR\n\nTokens should come from environment, not strings\n\nMessage: Token assigned from string literal. Use environment variable.\n\n### Token in Client-Side Code\n\nSeverity: ERROR\n\nNever expose Discord tokens to browsers\n\nMessage: Discord credentials exposed client-side. Only use server-side.\n\n### Slow Operation Without Defer\n\nSeverity: WARNING\n\nSlow operations should be deferred to avoid timeout\n\nMessage: Slow operation without defer. Interaction may timeout.\n\n### Interaction Without Error Handling\n\nSeverity: WARNING\n\nInteractions should have try/catch for graceful errors\n\nMessage: Interaction without error handling. Add try/catch.\n\n### Using Message Content Intent\n\nSeverity: WARNING\n\nMessage Content is privileged, prefer slash commands\n\nMessage: Using Message Content intent. Consider slash commands instead.\n\n### Requesting All Intents\n\nSeverity: WARNING\n\nOnly request intents you actually need\n\nMessage: Requesting all intents. Only enable what you need.\n\n### Syncing Commands on Ready Event\n\nSeverity: WARNING\n\nDon't sync commands on every bot startup\n\nMessage: Syncing commands on startup. Use separate deploy script.\n\n### Registering Commands in Loop\n\nSeverity: WARNING\n\nUse bulk registration, not individual calls\n\nMessage: Registering commands in loop. Use bulk registration.\n\n### No Rate Limit Handling\n\nSeverity: INFO\n\nConsider handling rate limits for bulk operations\n\nMessage: Bulk operation without rate limit handling.\n\n## Collaboration\n\n### Delegation Triggers\n\n- user needs AI-powered Discord bot -> llm-architect (Integrate LLM for conversational Discord bot)\n- user needs Slack integration too -> slack-bot-builder (Cross-platform bot architecture)\n- user needs voice features -> voice-agents (Discord voice channel integration)\n- user needs database for bot data -> postgres-wizard (Store user data, server configs, moderation logs)\n- user needs workflow automation -> workflow-automation (Discord events trigger workflows)\n- user needs high availability -> devops (Sharding, scaling, monitoring for large bots)\n- user needs payment integration -> stripe-specialist (Premium bot features, subscription management)\n\n## When to Use\nUse this skill when the request clearly matches the capabilities and patterns described above.\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["discord","bot","architect","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding"],"capabilities":["skill","source-sickn33","skill-discord-bot-architect","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/discord-bot-architect","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 37911 github stars · SKILL.md body (38,295 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:50:56.805Z","embedding":null,"createdAt":"2026-04-18T20:34:53.909Z","updatedAt":"2026-05-18T18:50:56.805Z","lastSeenAt":"2026-05-18T18:50:56.805Z","tsv":"'-2500':2284 '-3':663 '/api/oauth2/authorize':3251 '/banner.png':1719 '/banner.png'')':1645 '/bot.js':2089,3599 '/cogs':654 '/developers/applications':2633 '0':1293,1868,1874,2144,2167,3258 '000':939 '1':441,900,1218,1297,1332,1956,2283,2568,2593,2623,2628,2772,2865,2883,2942,3099,3266,3374,3435,3447,3465 '1/1s':2041 '10':1661,1736,1813 '100':1019,1273,2610 '1000':601,725,1036,1285,1902,2242,2296 '1024':1763 '120':2028 '15':1426,1550,2405,2445 '2':1221,2575,2603,2634,2657,2950,3105,3272,3455 '200':1912,2766,2778 '20applications.commands':3261 '25':1347,1754 '2500':80,2054,2063,2289,3530,3593 '256':1746,1758 '2f':2243 '3':55,902,1376,1412,1546,2311,2359,2561,2581,2638,2959,3109,3277,3461,3670,3744 '4':2102,2643,3113,3282,3469 '40':1845,1892,1950 '4096':1750 '429':2738 '5':882,1324,1328,1339,1341,2649,3120 '5/5s':2038 '50':1849,2023 '60':938,940,1112,2031 '6000':1740 'acc':2163,2165 'access':3024,3030 'acknowledg':52,1473,2357,2402,2414,2475,3628 'across':1743 'action':2981,3119 'actionrow':1325,1331,1336 'actionrowbuild':814,842,887,1043,1047 'activ':2580,3040,3116 'actual':3909 'add':166,1851,1962,3306,3329,3876 'addcompon':843,888,1044,1048 'addfield':1621 'addopt':903 'admin':3038 'afterward':2400 'agent':4023 'ai':1522,1532,3990 'ai-pow':3989 'airespons':1435,1447,2452,2463 'alreadi':2911,3302,3626 'alway':57,2547 'api':1380,1775,1792,2378 'appear':2737,2749,3170,3336,3349,3361,3633 'applic':497,2333,2637 'applications.commands':3162,3216,3276,3325 'approach':2062 'architect':4,16,3996 'architectur':4016 'arg':252,254,258,260 'ask':4128 'assign':1789,3791,3803 'async':280,310,413,562,593,621,692,732,834,945,990,1120,1141,1161,1224,1286,1314,1405,1469,1500,1850,1863,1960,1979,2153,2172,2218,2246,2425,2468,2834,2895,3550,3685,3713,3735 'async/await':508 'asyncio':1937 'asyncio.create':1973 'asyncio.future':1966 'asyncio.sleep':2005 'attack':3013 'author':1685 'auto':2094,2215,3604 'auto-determin':2214 'autom':4047,4050 'automat':1799,1932,2202 'autoshardedbot':2195 'avail':4058 'avoid':174,545,2680,2695,2700,3848 'await':285,295,329,351,355,426,447,580,602,643,727,749,919,950,960,972,1056,1083,1128,1149,1169,1176,1186,1229,1299,1319,1414,1418,1432,1436,1443,1452,1471,1478,1484,1486,1508,1512,1518,1524,1528,1538,1654,1662,1731,1883,1896,1923,1977,1992,2004,2016,2158,2177,2434,2438,2449,2453,2460,2473,2477,2485,2488,2504,2513,2845,2868,2903,3414,3439,3553,3706,3716,3722,3765 'backoff':71 'bad':3073,3541 'bash':3135 'basic':1597 'beyond':797 'block':3514,3536,3542 'bodi':433,452,1027,1078,1082,1093,1295,1307,2852,2873,3421,3444 'bodyinput':1021,1049 'bot':3,13,15,25,105,118,128,466,489,492,504,551,591,682,684,690,701,707,756,760,764,767,1606,1612,1673,1687,2052,2061,2073,2205,2395,2524,2599,2607,2641,2696,2790,2820,2968,2977,2984,2985,2989,3005,3012,3019,3028,3036,3115,3160,3174,3191,3209,3211,3221,3227,3260,3275,3280,3300,3313,3324,3482,3490,3933,3993,4002,4010,4015,4032,4065,4074 'bot.add':757 'bot.event':561,2217,2245,2894 'bot.guilds':1698,2269 'bot.js':2123 'bot.latency':600 'bot.load':658 'bot.run':664,2938 'bot.shards':2228 'bot.shards.items':2235 'bot.slash':585,613,1157,1310,1494,2466 'bot.sync':581,2904,2933 'bot.user':571 'bot.user.display_avatar.url':1691,1713 'bot.users':1707 'boundari':4136 'break':2350,2558,2758,3003,3202,3367,3507,3641 'broadcast':2168 'broadcastmessag':2174 'browser':3823 'build':8,20,116,127,502,801 'builder':1565,4011 'bulk':1785,1836,2039,3951,3962,3975,3978 'button':84,779,808,837,869,1098,1124,1145,1329,1464,2320,2363,2495,2709,3622 'buttonbuild':815,845,853,861 'buttonrow':840,926 'buttonstyl':816 'buttonstyle.danger':859 'buttonstyle.link':867 'buttonstyle.primary':851 'c':2179 'c.channels.cache.get':2184 'cach':3389 'call':1381,1525,1793,3955 'callback':1226,1288 'callllm':2454 'callopenai':1437 'cancel':855,857,959,963,1138,1143,1153 'cannot':1357,3659 'capabl':4090 'care':576 'catch':332,459,1450,1887 'caus':3522 'cdn':3391 'chang':1476,1562,2798 'channel':744,746,748,2037,2183,2187,4026 'channel.send':750,2188 'channelid':2175,2180,2185,2191 'charact':1741,1747,1751,1759,1764 'check':590,3121,3731,3740,3769 'choos':922 'clarif':4130 'class':676,1103,1192,1239,1251,1838,1942 'clear':4087,4103 'click':2364 'client':135,155,161,163,429,2128,2132,2134,2664,2669,2671,3061,3144,3147,3252,3255,3417,3442,3813,3829 'client-sid':3060,3812,3828 'client.commands':179 'client.commands.set':216 'client.generateinvite':3322 'client.guilds.cache.size':1625,2147 'client.login':261,3086 'client.on':256,2139,3560,3571,3579 'client.once':250 'client.shard.broadcasteval':2178 'client.shard.fetchclientvalues':2159 'client.shard.ids':2143 'client.user.displayavatarurl':1615,1641 'client.users.cache.size':1631 'cmd':1164 'code':2608,2660,3063,3319,3815 'cog':649,661,758,769 'cogs/general.py':669 'collabor':3984 'collect':136,181,794,928,944,1468,1939 'collector':931 'collector.on':943,1467 'collector.stop':955,965 'color':708,1594,1680 'colors.blue':1604 'come':3796 'command':35,44,93,112,178,186,206,212,215,218,317,321,324,345,379,384,399,418,420,434,436,453,458,473,476,478,498,513,524,553,558,573,582,584,586,610,614,675,686,770,799,1158,1311,1495,2201,2207,2319,2337,2362,2370,2467,2471,2589,2708,2724,2733,2735,2748,2759,2765,2777,2787,2840,2853,2856,2862,2874,2877,2905,2909,2934,2945,2954,3168,3180,3188,3192,3218,3231,3334,3344,3346,3353,3357,3360,3369,3393,3408,3422,3426,3445,3453,3460,3474,3620,3890,3898,3921,3930,3937,3945,3958 'command.data.name':217 'command.data.tojson':405 'command.execute':330 'commandfil':188,199,386,397 'commands.autoshardedbot':2206 'commands.bot':552,2697 'commands.cog':678 'commands.cog.listener':731 'commands.length':417 'commands.push':404 'commands.slash':685 'commandspath':183,190,203,381,388,402 'commit':3052,3138 'common':2784,3049 'communiti':915,917 'complet':1429,2347 'complex':130 'compon':37,83,776,925,954,964,1463,2494 'config':153,377,3085,3155,4041 'config.json':3094 'configur':532,2520 'confirm':803,847,849,949,953,1117,1122,1132,1160,1163 'confirmview':1104,1168 'connect':124 'consid':3896,3970 'console.error':322,334,461 'console.log':415,454,1820,1827,1830,2106,2112,2118,2141,2854,2875,3564,3575,3582 'const':134,141,146,160,182,187,196,200,205,221,226,235,239,244,266,283,291,303,316,336,360,365,370,378,380,385,394,398,406,424,445,812,839,884,930,993,1004,1020,1071,1077,1430,1434,1482,1592,1599,1804,1808,1875,1881,1906,1919,2081,2085,2127,2131,2156,2182,2447,2451,2663,2668,2822,2827,3077,3156,3320,3545,3551,3595,3688 'constructor':1840 'content':49,287,338,542,921,952,962,974,1085,1131,1152,1445,1454,1488,1574,2531,2550,2583,2692,2702,2722,2994,3751,3880,3885,3894 'context':2190,2368 'control':3009 'convers':4000 'coro':1964,1968,1987,1993 'correct':2399,3246,3680 'count':2098,2164,2166,2212 'cover':26 'creat':154,3022 'creates/day':2767,2779 'credenti':3826 'criteria':4139 'critic':2315,2522,2972 'cross':2150,4013 'cross-platform':4012 'cross-shard':2149 'ctx':596,624,696,1165,1317,1504,2472 'ctx.author.display_avatar.url':1728 'ctx.defer':1509,1513,2474,2478 'ctx.followup.send':1187,1529,1539,2489 'ctx.respond':603,644,728,1170,1732 'ctx.send':1320 'current':1617,1676 'custom':635,1802,1934 'data':210,271,425,446,824,982,1393,1586,2152,2527,3026,3546,3552,4033,4039 'data.length':457 'databas':1378,1520,2377,4030 'def':563,594,622,679,693,733,754,1106,1121,1142,1162,1195,1225,1242,1254,1287,1315,1501,1944,1961,1980,2219,2247,2469,2896 'defer':1358,1360,1390,1408,1441,1492,1506,1548,2420,2428,2458,3660,3702,3711,3839,3846,3854 'delay':2803 'deleg':3985 'delet':2040 'deploy':95,2741,2809,2836,2857,2878,2885,2952,2961,3112,3341,3351,3424,3458,3472,3942 'deploy-commands.js':472,2815 'deprec':51,2587 'dequ':1941,1952 'describ':1038,4093,4107 'descript':589,617,689,703,1675,1753 'design':910,912,1207,1209,3385 'detect':3785 'determin':2096,2216 'dev':907,1203 'develop':905,1201,2597,2626,2838,2947,3102,3195,3264,3405,3448 'devop':4059 'dirnam':185,224,383 'disconnect':2117,2121,3478,3578 'discord':2,12,14,24,104,117,465,491,503,520,666,671,706,763,1102,1774,2095,2197,2294,2351,2388,2559,2596,2614,2998,3039,3057,3139,3203,3263,3380,3387,3508,3771,3775,3783,3820,3825,3992,4001,4024,4051 'discord-bot':464,762 'discord-bot-architect':1 'discord.applicationcontext':597,625,697,1166,1318,1505 'discord.buttonstyle.green':1119 'discord.buttonstyle.red':1140 'discord.color.blue':709,1681 'discord.com':2632,3250 'discord.com/api/oauth2/authorize':3249 'discord.com/developers/applications':2631 'discord.embed':699,1671 'discord.ext':522,673,2199 'discord.inputtextstyle.long':1280 'discord.inputtextstyle.short':1268 'discord.intents.default':540,2210,2684 'discord.js':27,100,108,140,269,306,364,807,822,1389,1596,1795,1807,2075,2084,2130,2419,2662,2667,2826 'discord.js.org':865 'discord.member':628,739 'discord.option':627,633 'discord.selectoption':1199,1205 'discord.ui.button':1115,1136 'discord.ui.inputtext':1264,1276 'discord.ui.modal':1253 'discord.ui.select':1194 'discord.ui.view':1105,1241 'discord.utils.utcnow':1730 'display':1578 'document':863 'doesn':2541,3631 'dotenv':152,376,526,529,531,3084,3152,3154 'e':1537,2000,2003 'edg':579,2308 'edit':1439,2456 'els':255,354,956,966,2867 'emb':698,729,730,1448,1564,1598,1600,1656,1657,1659,1664,1670,1733,1734,1737,1745,1757 'embed':1568 'embed.add':710,717,1692,1701 'embed.set':1684,1710,1714,1720 'embed.timestamp':1729 'embed1':1665 'embed2':1666 'embed3':1667 'embedbuild':1593,1602 'embedlink':3328 'emit':872 'emoji':908,913,918,1204,1210 'empti':2537,2554 'enabl':535,2567,2594,2624,3916 'entri':470,2080 'env':486,773,3092,3136 'env.local':3093 'environ':3081,3132,3787,3798,3808,4119 'environment-specif':4118 'ephemer':346,1094,1237,1308,1417,1420,1480,1511,1514,1552,2437,2440,2479,2515,3754 'error':333,335,342,460,462,1451,1456,1541,1888,1890,2391,2739,3629,3774,3793,3817,3860,3870,3874 'etc':3215 'even':2392,3298 'event':126,138,220,225,245,304,481,482,873,3488,3495,3538,3543,3570,3573,3924,4052 'event.execute':253,259 'event.name':251,257 'event.once':249 'eventfil':227,238 'events.interactioncreate':309 'eventspath':222,229,242 'everi':2789,2794,2892,2966,3932 'example.com':1609,1644,1683,1718 'example.com/banner.png':1717 'example.com/banner.png'')':1643 'except':1534,1535,1997,1998,2002 'execut':213,281,311,343,835,991,1406,2426,3686,3714,3736 'exist':3232 'expert':4124 'explicit':2931 'exponenti':70 'expos':2970,3044,3098,3819,3827 'exposur':3050 'extens':659 'f':192,231,390,567,604,645,660,722,751,1232,1302,1530,2223,2237,2254,2274,2490,2907 'f.endswith':193,232,391 'fail':2330,2341,3726 'fals':638,1148,1843,1905,1954,2008 'featur':4020,4075 'feedback':986,989,999,1003,1010,1026,1030,1040,1069,1075,1081,1089,1261,1278,1313,1316 'feedback-bodi':1025,1080 'feedback-mod':998,1068 'feedback-titl':1009,1074 'feedbackmod':1252,1322 'fetchrepli':289 'field':711,718,1589,1693,1702,1755,1761,1766 'file':197,204,236,243,395,403,768,1384,2379 'file.json':3548,3555 'filenam':651,662 'filename.endswith':656 'filepath':201,208,240,247 'filter':191,230,389,933 'fire':2543 'first':94,1054,1355,1359,3609,3653,3683,3705,3712,3733,3759 'fix':2413,2621,2805,3068,3244,3404,3534,3675 'flag':2920 'follow':2409 'follow-up':2408 'followup':1549 'footer':1721 'forc':3125 'form':805,980,3698 'format':1579 'formatuptim':1637 'foundat':102,490 'frequent':3475,3476 'fs':142,145,366,369 'fs.promises.readfile':3554 'fs.readdirsync':189,228,387 'fs.readfilesync':3547 'full':122,3008 'function':2154,2173,2835 'futur':1965,1969,1978,1988 'future.set':1994,2001 'gateway':32,123,2027,2601,2647,3477,3509 'gatewayintentbit':137,2665 'gatewayintentbits.guildmembers':2674 'gatewayintentbits.guildmessages':171 'gatewayintentbits.guildpresences':2676 'gatewayintentbits.guilds':165,2673 'gatewayintentbits.messagecontent':172,2678 'gc':3523 'general':677,759 'general.py':772 'generat':1387,3245,3271,3284,3315 'get':2136,2260 'gettotalguild':2155 'git':3054,3122 'github':3042 'gitignor':3090,3091 'global':96,435,1831,2022,2764,2861,2876,2953,3333,3342,3356,3368,3425,3459,3473 'go':2629,2639,3100,3267 'goe':3484 'good':511,3080,3549 'grace':68,1772,3558,3869 'greet':616,618,623,631 'group':771 'guid':2282 'guild':81,92,419,431,2042,2047,2064,2148,2261,2267,2279,2280,2285,2290,2297,2569,2576,2752,2776,2781,2795,2839,2855,2944,3352,3392,3402,3407,3419,3452,3527,3594 'guild.members':2015 'guilds.cache.size':2160 'handl':65,1059,1363,1770,1773,1796,1803,1929,1935,2203,2317,3556,3861,3875,3967,3971,3983 'handler':479,483 'hardcod':3070,3770,3780,3782 'haspermiss':3747 'heartbeat':3512,3517 'hello':642 'help':705,1583 'high':1782,2729,3165,4057 'high-volum':1781 'histori':3123 'hit':1915 'horizont':2067 'hour':442,2773,2866,2884,3364,3375,3436,3466 'i.customid':948,958,968 'i.deferreply':1479 'i.deferupdate':1472 'i.editreply':1487 'i.update':951,961,973 'i.user.id':935 'i.values.join':977 'i/o':2380 'icon':1689,1726 'iconurl':1614,1652 'id':430,432,451,2232,2240,2252,2257,2266,2277,2844,2849,2851,2872,3145,3148,3253,3256,3418,3420,3443,3562,3566,3574,3577,3581,3584 'imag':1590,1715 'immedi':1409,1507,2415,2429,2476,3104,3337,3678,3700 'implement':3586 'import':517,519,523,527,670,674,1101,1936,1940,2196,2200,3206 'index.js':468 'individu':3954 'info':688,694,702,1819,2138,3969 'info.global':1832 'info.retryafter':1825 'info.route':1829 'inform':691,1580 'init':680,1107,1110,1196,1212,1243,1246,1255,1258,1945 'initi':1544,1559 'inlin':1626,1632,1638,1699,1708 'input':796,3697,4133 'instabl':3519 'instant':421,2782,2841,2858,2948,3395,3410,3454 'instead':2712,2914,3899 'integr':3997,4006,4027,4069 'intent':33,50,61,64,159,164,533,539,559,560,742,2135,2209,2519,2534,2545,2551,2563,2602,2648,2653,2672,2683,2698,2699,2703,2723,3881,3895,3902,3907,3914 'intents.members':548,2685 'intents.message':541,2691 'intents.presences':2688 'interact':36,53,131,282,312,331,775,791,832,836,992,1125,1146,1181,1228,1290,1407,2309,2329,2354,2427,3624,3657,3687,3715,3737,3760,3855,3858,3864,3872 'interaction.channel.createmessagecomponentcollector':932 'interaction.client.commands.get':318 'interaction.commandname':319,326 'interaction.createdtimestamp':294 'interaction.customid':1067 'interaction.deferred':350 'interaction.deferreply':1415,1419,2435,2439,2514,3717 'interaction.deferupdate':2505 'interaction.editreply':296,1444,1453,2461 'interaction.fields.gettextinputvalue':1073,1079 'interaction.followup':352 'interaction.ischatinputcommand':314 'interaction.ismodalsubmit':1065 'interaction.replied':349 'interaction.reply':286,356,920,1084,1655,1663,3750 'interaction.response.edit':1129,1150 'interaction.response.send':1230,1300 'interaction.showmodal':1057,3707,3723,3766 'interaction.user.displayavatarurl':1653 'interaction.user.id':936,3748 'interactioncr':1063 'interactioncreate.js':485 'interfac':793 'intermitt':3494 'invalid':2995,2999,3047 'invit':3023,3223,3239,3247,3288,3296,3316 'inviteurl':3321 'issu':3513 'item':1248,1263,1275,2272 'javascript':28,132,264,301,358,806,978,1388,1591,1794,2074,2418,2497,2661,2814,3072,3149,3314,3409,3431,3540,3559,3590,3679,3709,3734 'javascript/typescript':120 'join':736,1235,2540,2986,3020,3499 'join/leave':2572 'js':194,233,392 'keep':2617 'kick':3290 'label':904,909,914,1116,1137,1200,1206,1265,1277 'larg':2072,4064 'latenc':292,298,299,592,598,606,607,720 'later':1563,2417 'launch':2107 'legaci':555 'len':715,1697,1706,2227,2278 'length':1272,1284 'limit':39,67,1323,1735,1769,1777,1798,1822,1917,1931,2021,2727,2746,2763,3966,3973,3982,4095 'link':868 'list':2536,2574 'liter':3806 'll':2384 'llm':1382,3995,3998 'llm-architect':3994 'load':177,219,528,530,648,3150 'local':2339 'log':568,1585,2224,3504,4043 'look':1573 'loop':2801,3539,3544,3947,3960 'main':469,766,2079,2923 'main.py':516,765 'make':2797 'malici':2993 'manag':2077,2086,3596,4077 'manager.on':2103 'manager.spawn':2122,3605 'mani':3220,3526 'manual':2566,2817,2916,2963 'margin':1847 'match':325,4088,4104 'max':1219,1271,1283,1344,1660 'may':2879,3856 'medium':3339,3480,3612 'member':735,738,741,2013,2043,2526,2533,2535,2539,2570,2571,2573,3498 'member.guild.system':745 'member.mention':753 'member.send':2018 'memori':2069,2300,3520 'menu':828,833,875,1191,1334,1351,2366,2369 'menus':781,802,811,1343,1466,1584,2322,2496 'messag':46,48,632,636,640,1130,1151,1231,1301,1346,1569,1739,1786,1913,2034,2176,2181,2189,2192,2503,2530,2549,2582,2585,2701,2714,2721,2747,3016,3213,3500,3502,3781,3801,3824,3850,3871,3879,3884,3891,3893,3911,3935,3956,3977 'message.content':2552 'message/modal':1327 'min':1216 'minim':62,157 'minut':1427,1551,2406,2446 'miss':2385,2517,3161,3487,3497,4141 'mistak':2785 'modal':86,783,979,994,1000,1051,1058,1060,1070,1250,1321,1352,2324,2711,3606,3616,3630,3642,3649,3677,3681,3689,3695,3708,3724,3757,3767 'modal.addcomponents':1041 'modalbuild':818,996,3691 'moder':4042 'modern':103 'modifi':2124 'module.exports':270,307,823,981,1392,2424 'monitor':4062 'ms':300,608,726,1826,2244 'msg':639,647 'mtizndu2nzg5mdeymzq1njc4.abcdef.xyz':3079 'multipl':1658 'must':1052,1353,2591,3607,3650,3777 'my-mod':3693 'n':1090,1092,1304,1306 'name':308,587,615,687,712,719,1159,1312,1496,1611,1613,1622,1628,1634,1686,1688,1694,1703,1762,2922 'need':121,170,510,538,790,2525,2613,2655,3130,3234,3331,3729,3910,3919,3988,4004,4018,4029,4045,4056,4067 'network':3518 'never':2346,3069,3074,3137,3535,3778,3818 'new':162,180,272,408,825,841,844,852,860,886,889,983,995,1006,1022,1042,1046,1394,1601,1810,1854,1897,1908,2087,2133,2511,2670,2829,3295,3308,3597,3690 'node':144,149,368,373 'none':1114,1134,1155,1185,2213 'note':1553 'oauth':3207 'oauth2':3269 'occur':1457,1542 'off-peak':3428 'offlin':3485,3493 'ok':3742 'one':877 'onlin':2578 'openai':1526 'oper':1365,1372,1404,1784,1837,1852,1859,1876,1884,2345,2376,2423,2433,2487,3515,3837,3843,3852,3976,3979 'optim':2070,2097 'option':612,800,924,1198,1222,1223,1348 'os':518 'os.environ':665 'os.listdir':653 'other':2755,3199,3638 'output':4113 'package.json':487 'pars':47,2715 'path':147,150,371,374,3764 'path.join':184,202,223,241,382,401 'pattern':99,509,777,1362,1566,1771,1834,2050,4092 'paus':3524 'payment':4068 'peak':3430 'per':878,1326,1330,1335,1345,1349,1738,1756,1760,1765,1894,1948,1958,2025,2030,2262,2298,2780 'perform':1401 'permiss':3212,3219,3257,3281,3326,3332,3753,4134 'ping':275,288,588,595 'ping.js':480 'placehold':1213 'plan':72 'platform':4014 'point':471,3051 'pong':279,297,605 'portal':2598,2627,3103,3265 'possibl':176,547,2705 'postgr':4035 'postgres-wizard':4034 'potenti':3031 'power':3991 'prefer':507,556,3888 'prefix':554,2208 'premium':4073 'presenc':2528,2544,2577 'pressur':3521 'prevent':3516 'principl':42 'print':566,2222,2236,2253,2273,2906 'privat':2482 'privileg':63,173,544,550,743,2518,2562,2600,2646,2675,2677,2679,2687,2690,2694,3887 'process':1385,1459,1864,1981,2306,2396,2416 'process.env.client':450,2848,2871 'process.env.discord':262,411,1815,2091,2832,3087,3158,3601 'process.env.guild':2843,2850 'product':10,22,2343,2860,2958,3423 'production-readi':9,21 'profession':1572 'professional-look':1571 'promis':1855,1898 'propag':444,2775,3377,3438,3468 'proper':3134 'provid':3007 'public':3065 'push':3126 'py':657 'pycord':30,488,494,1097,1491,1669,2194,2465,2682,2887 'pycord/discord.py':1928 'python':31,495,506,515,668,1096,1490,1668,1927,2193,2464,2681,2886 'queri':1379,1521 'queue':1833,1907,2009 'queue.add':1924,2017 'quick':3738 'r':1899,1901 'random':2987,3483 'rate':38,66,1768,1776,1797,1821,1916,1930,2020,2726,2745,2762,3965,3972,3981 'ratelimit':1818 'ratelimitqueu':1839,1909,1943,2010 're':2500,2508,3238,3287 're-invit':3237,3286 'reaction':3214 'read':2584 'readi':11,23,98,565,2111,2115,2140,2145,2221,2250,2259,2898,2908,2956,3457,3923 'ready.js':484 'recommend':2295,2412,2620,2804,3067,3243,3403,3533,3674 'reconnect':3501,3557,3585 'refresh':416 'regener':3106 'regist':456,2731,2786,2792,2913,3944,3957 'registr':474,2725,2760,3952,3963 'regular':3511 'reject':1857,1861,1878,1889 'remov':3128,3311 'repeat':1791 'replay':3568 'replayedev':3563,3569 'repli':277,337,353,357,1442,2459,3663,3704 'request':58,1461,1649,1723,1893,1947,1957,2024,2029,2044,2398,2604,2658,2932,3900,3906,3912,4086 'requir':60,78,139,143,148,151,158,207,246,268,305,363,367,372,375,400,637,740,821,1269,1281,1595,1806,2065,2083,2129,2288,2292,2352,2565,2666,2719,2825,3083,3153,3279,3510,3531,3591,3646,4132 'requirements.txt':774 'resolv':1856,1860,1877,1885 'respond':2336,2382 'respons':929,1055,1356,1361,1383,1391,1493,1523,1533,1545,1560,2411,2483,2512,3610,3654,3684,3761 'rest':361,407,409,1805,1809,1811,2823,2828,2830 'rest.on':1817 'rest.put':427,448,2846,2869,3415,3440 'restart':2967 'result':1431,1438,1446,1483,1489,1517,1527,1531,1882,1886,1991,1995,1996,2157,2448,2455,2462,2484,2491,2492 'resultemb':1449 'results.reduce':2162 'resum':3567 'retri':1823 'return':315,327,1853,1869,1976,2161,3749 'review':3114,4125 'rich':88,785,1567 'role':894,898,971,1215,1788 'roleselect':1193,1249 'roleview':1240 'round':599,723 'rout':362,1828,2824 'routes.applicationcommands':449,2870,3441 'routes.applicationguildcommands':428,2847,3416 'row':838,876,879 'rule':2313 'run':2303,2816,2960 'safe':1846 'safeti':4135 'scale':2051,2068,2281,3589,4061 'scan':3041 'scope':3163,3208,3228,3242,3259,3309,3323,4106 'screenshot':3066 'script':475,2810,2962,3943 'scroll':2644 'second':56,941,1377,1413,1547,1895,1949,1959,2026,2032,2312,2360,3671,3745 'section':2642 'see':577,2327 'select':85,780,810,874,893,896,970,976,1190,1214,1234,1333,1342,1350,1465,2321,2365,2367,2635,3273,3278 'select-rol':892,969 'selectrow':885,927 'self':681,695,737,1108,1123,1144,1197,1227,1244,1256,1289,1946,1963,1982 'self._process':1975 'self.add':1247,1262,1274 'self.bot':683 'self.bot.guilds':716 'self.bot.latency':724 'self.children':1292,1296 'self.delay':1955,2006 'self.processing':1953,1972,1983,2007 'self.queue':1951,1986 'self.queue.append':1967 'self.queue.popleft':1989 'self.stop':1135,1156 'self.value':1113,1126,1147 'self.values':1236 'send':1911,2509,2990,3015 'sendmessag':3327 'sent':284 'sent.createdtimestamp':293 'separ':2305,2796,2808,3941 'server':713,1623,1695,2055,2611,2988,3021,3034,3177,3196,3304,3381,3834,4040 'server-sid':3833 'set':1557 'setauthor':1610 'setcolor':1603 'setcustomid':846,854,891,997,1008,1024,3692 'setdescript':276,829,987,1400,1616 'setfoot':1647 'setimag':1642 'setlabel':848,856,862,1012,1028 'setmaxlength':1018,1035 'setmaxvalu':901 'setminvalu':899 'setnam':274,827,985,1396 'setplacehold':895,1037 'setrequir':1016,1033 'setstyl':850,858,866,1014,1031 'setthumbnail':1640 'settimeout':1900 'settimestamp':1646 'settitl':1001,1605,3696 'settoken':410,1814,2831 'setup':106,755 'seturl':864,1608 'sever':2314,2521,2728,2971,3164,3338,3479,3611,3773,3792,3816,3840,3862,3882,3903,3925,3948,3968 'shard':41,74,2049,2057,2076,2105,2108,2113,2119,2126,2137,2142,2151,2171,2204,2211,2229,2231,2233,2238,2239,2249,2251,2255,2256,2263,2265,2271,2275,2276,2287,2291,2299,2302,3529,3532,3565,3576,3583,3587,4060 'shard.id':2109,2114,2120 'shard.js':2078 'shard.latency':2241 'shard.on':2110,2116 'shardcreat':2104 'sharddisconnect':3572 'shardingmanag':2082,2088,3598 'shardreconnect':3580 'shardresum':3561 'share':2976,3055 'sharp':578,2307 'show':830,1050,2389,3183,3186,3491,3614,3647,3676,3699,3756 'showmod':3662,3665,3673 'side':3062,3814,3830,3835 'situat':2316,2523,2730,2973,3166,3340,3481,3613 'size':2048 'skill':6,18,4083,4098 'skill-discord-bot-architect' 'slack':4005,4009 'slack-bot-build':4008 'slash':34,43,111,477,512,557,583,609,798,2318,2361,2707,2732,3167,3179,3217,3230,3343,3619,3889,3897 'slashcommandbuild':267,273,813,826,984,1395 'slot':883,1340 'slow':1364,1398,1403,1498,1502,1519,2344,2375,2422,2432,2470,2486,3836,3842,3851 'slow-task':1397,1497 'slowdatabasequeri':1433,2450 'slowoper':1485 'someth':3732 'sometim':3635 'source-sickn33' 'spam':2991 'special':5,17,3645 'specialist':4072 'specif':2033,3401,4120 'specifi':2100 'src':467 'src/commands/ping.js':265 'src/deploy-commands.js':359 'src/events/interactioncreate.js':302 'src/index.js':133 'start':77,2821,2936 'startup':2791,2813,2893,3934,3939 'statist':1620,1679 'status':1581,1607,1618,1674,1677,2546,2579 'step':2622,2656 'still':3758 'stop':4126 'store':2974,4037 'str':634 'string':2555,3800,3805 'stringselectmenubuild':817,890 'stripe':4071 'stripe-specialist':4070 'structur':463,761,1588 'style':1118,1139,1267,1279 'submiss':1061 'submit':988,1002,1260 'subscript':4076 'substitut':4116 'success':455,4138 'super':1109,1211,1245,1257 'support':514 'sure':1173 'symptom':2325,2532,2734,2979,3173,3345,3489,3623 'sync':572,2890,2915,2925,2929,3739,3920,3929,3936 'sys.argv':2927 'take':438,880,1337,1373,2769,2880,3032,3371,3432 'task':1399,1499,1503,1974,4102 'test':90,423,2940,3413,3450,4122 'text':1648,1722,2586 'textinputbuild':819,1007,1023 'textinputstyl':820 'textinputstyle.paragraph':1032 'textinputstyle.short':1015 'thank':1086,1303 'think':3666 'this.process':1862 'this.processing':1842,1866,1870,1904 'this.queue':1841 'this.queue.length':1867,1873 'this.queue.push':1858 'this.queue.shift':1879 'this.requestspersecond':1844,1903 'throttl':1891 'thumbnail':1711 'time':937,1188,1367,1543 'timeout':942,1111,2310,3849,3857 'titl':700,1011,1013,1072,1076,1091,1259,1266,1291,1305,1672,1749 'titleinput':1005,1045 'toggl':2650 'token':263,412,667,1816,2090,2092,2833,2939,2969,2978,2996,3006,3045,3071,3078,3088,3096,3108,3140,3142,3157,3159,3600,3602,3772,3776,3784,3789,3794,3802,3810,3821 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'total':1742 'totalshard':2093,2101,3603 'tradit':3210 'treat':4111 'tri':328,414,1422,1516,1880,1990 'trigger':3986,4053 'true':290,347,543,549,1017,1034,1095,1127,1238,1270,1282,1309,1421,1481,1515,1627,1633,1639,1700,1709,1871,1984,2441,2480,2516,2686,2689,2693,2937,3755 'try/catch':3867,3877 'two':3205 'type':3185 'unauthor':2980,3118 'unknown/offline':2548 'updat':1582,2501,2768,2783,2949,3110,3411 'uptim':1635 'url':1682,1690,1712,1716,1727,3248,3270,3285,3297,3317 'usag':1910,2011 'use':82,115,501,778,789,1371,1577,1780,2060,2618,2706,2806,2918,2943,3089,3131,3283,3293,3406,3786,3807,3832,3878,3892,3940,3950,3961,4080,4081,4096 'user':620,626,629,792,795,1180,1629,1651,1704,1725,1920,1922,2326,3172,3291,3987,4003,4017,4028,4038,4044,4055,4066 'user.mention':646 'user.send':1925 'ux':89,786 'v14':101,109 'valid':3768,4121 'valu':714,721,906,911,916,1202,1208,1217,1220,1294,1298,1624,1630,1636,1696,1705,1767 'vari':2045 'variabl':3082,3133,3788,3790,3809 'verif':2615 'version':1812 'view':1100,1133,1154,1167,1174,1175 'view.value':1183 'view.wait':1177 'visual':1475 'voic':4019,4022,4025 'voice-ag':4021 'volum':1783 'wait':1178,3462 'want':2066 'warn':3841,3863,3883,3904,3926,3949 'welcom':752,1926,2019 'window':2387 'within':54,2358 'without':1366,1474,1914,2802,3289,3310,3528,3838,3853,3859,3873,3980 'wizard':4036 'work':2338,3193,3354,3398,3634 'workflow':2941,3446,4046,4049,4054 'workflow-autom':4048 'wrong':3710","prices":[{"id":"bd61ee80-b2bf-4a40-a81e-a3977a817eb2","listingId":"53428ea7-14e4-4b3f-b927-af5ad6442bc0","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:34:53.909Z"}],"sources":[{"listingId":"53428ea7-14e4-4b3f-b927-af5ad6442bc0","source":"github","sourceId":"sickn33/antigravity-awesome-skills/discord-bot-architect","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/discord-bot-architect","isPrimary":false,"firstSeenAt":"2026-04-18T21:36:08.356Z","lastSeenAt":"2026-05-18T18:50:56.805Z"},{"listingId":"53428ea7-14e4-4b3f-b927-af5ad6442bc0","source":"skills_sh","sourceId":"sickn33/antigravity-awesome-skills/discord-bot-architect","sourceUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/discord-bot-architect","isPrimary":true,"firstSeenAt":"2026-04-18T20:34:53.909Z","lastSeenAt":"2026-05-07T22:40:39.331Z"}],"details":{"listingId":"53428ea7-14e4-4b3f-b927-af5ad6442bc0","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"discord-bot-architect","github":{"repo":"sickn33/antigravity-awesome-skills","stars":37911,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-05-18T08:24:49Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"2569f400f07d1c18c1858fee95218011cd4de5ea","skill_md_path":"skills/discord-bot-architect/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/discord-bot-architect"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"discord-bot-architect","description":"Specialized skill for building production-ready Discord bots."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/discord-bot-architect"},"updatedAt":"2026-05-18T18:50:56.805Z"}}