A powerful Discord library, built for PigBot.
  • Luau 99.6%
  • Nix 0.4%
Find a file
2026-02-08 19:50:26 -06:00
.github initial implementation of BleuCord 2026-02-08 19:50:26 -06:00
docs initial implementation of BleuCord 2026-02-08 19:50:26 -06:00
src initial implementation of BleuCord 2026-02-08 19:50:26 -06:00
tests initial implementation of BleuCord 2026-02-08 19:50:26 -06:00
.editorconfig initial setup 2026-02-08 18:24:54 -06:00
.env.example initial setup 2026-02-08 18:24:54 -06:00
.envrc initial setup 2026-02-08 18:24:54 -06:00
.gitignore initial setup 2026-02-08 18:24:54 -06:00
.luaurc initial setup 2026-02-08 18:24:54 -06:00
COMMANDS.md initial implementation of BleuCord 2026-02-08 19:50:26 -06:00
flake.lock initial implementation of BleuCord 2026-02-08 19:50:26 -06:00
flake.nix initial setup 2026-02-08 18:24:54 -06:00
README.md initial implementation of BleuCord 2026-02-08 19:50:26 -06:00

Bleucord

A fully-featured Discord API library for the BleuMoon/Lune runtime, written in Luau.

Version: 1.0.0 · Discord API: v10

Features

  • Complete Discord API Coverage — REST, Gateway WebSocket, and all event types
  • Builder Pattern — Fluent builders for embeds, slash commands, and message components
  • Automatic Rate Limiting — Per-route and global rate limit handling with retry logic
  • Multi-Shard Support — Automatic shard management with configurable shard IDs
  • Type Safety — Full --!strict type annotations across every module
  • Caching — Built-in LRU caches for guilds, channels, users, messages, and members
  • Zero Dependencies — Everything is self-contained; no package manager required

Quick Start

Prerequisites

Setup

  1. Clone this repository
  2. Set your bot token as an environment variable:
    export DISCORD_TOKEN="your-bot-token-here"
    
  3. Enter the development shell and run:
    nix develop --command lune run src/main
    

Minimal Bot

local Bleucord = require("src/bleucord")
local Client = Bleucord.Client
local Intents = Bleucord.Intents

local client = Client.new({
    intents = Intents.combine(
        Intents.FLAGS.GUILDS,
        Intents.FLAGS.GUILD_MESSAGES,
        Intents.FLAGS.MESSAGE_CONTENT
    ),
})

client:on("ready", function()
    print(`Logged in as {client.user:displayName()}!`)
end)

client:on("messageCreate", function(message)
    if message.author and message.author.bot then return end

    if message.content == "!ping" then
        client.rest:createMessage(message.channelId, {
            content = "Pong! 🏓",
        })
    end
end)

client:login()

Rich Embed Example

local EmbedBuilder = Bleucord.EmbedBuilder
local Color = Bleucord.Color

client:on("messageCreate", function(message)
    if message.content == "!embed" then
        local embed = EmbedBuilder.new()
            :setTitle("Hello from Bleucord!")
            :setDescription("This is a rich embed built with the EmbedBuilder.")
            :setColor(Color.BLURPLE)
            :addField("Field 1", "Some value", true)
            :addField("Field 2", "Another value", true)
            :setFooter("Powered by Bleucord")
            :setTimestamp()
            :toJSON()

        client.rest:createMessage(message.channelId, {
            embeds = { embed },
        })
    end
end)

Slash Commands & Interactions

local SlashCommandBuilder = Bleucord.SlashCommandBuilder

-- Register a global command
client:on("ready", function()
    local command = SlashCommandBuilder.new()
        :setName("greet")
        :setDescription("Greet someone!")
        :addUserOption(function(opt)
            return opt:setName("user"):setDescription("Who to greet"):setRequired(true)
        end)
        :toJSON()

    client.rest:createGlobalApplicationCommand(client.application.id, command)
end)

-- Handle interactions
client:on("interactionCreate", function(interaction)
    if interaction:isCommand() and interaction.data.name == "greet" then
        local userId = interaction:getStringOption("user")
        interaction:reply({
            content = `Hello, <@{userId}>!`,
        })
    end
end)

Buttons & Components

local ActionRowBuilder = Bleucord.ActionRowBuilder
local ButtonBuilder = Bleucord.ButtonBuilder
local ButtonStyle = Bleucord.ButtonStyle

client:on("messageCreate", function(message)
    if message.content == "!button" then
        local row = ActionRowBuilder.new()
            :addButton(
                ButtonBuilder.new()
                    :setCustomId("my_button")
                    :setLabel("Click Me!")
                    :setStyle(ButtonStyle.PRIMARY)
            )
            :toJSON()

        client.rest:createMessage(message.channelId, {
            content = "Here's a button:",
            components = { row },
        })
    end
end)

client:on("interactionCreate", function(interaction)
    if interaction:isButton() and interaction.data.custom_id == "my_button" then
        interaction:reply({
            content = "You clicked the button!",
            flags = Bleucord.MessageFlags.EPHEMERAL,
        })
    end
end)

Documentation

Guide Description
Getting Started Installation, setup, and your first bot
Client Client class, options, events, and lifecycle
Gateway & Intents WebSocket connection, intents, sharding
REST Client HTTP client, rate limiting, all endpoint methods
Structures User, Guild, Channel, Message, Member, Interaction, Presence
Builders EmbedBuilder, SlashCommandBuilder, ComponentBuilder
Utilities Cache, EventEmitter, Color, Permissions, Snowflake, Logger
Events Guide Complete event reference with payloads
Intents Guide Understanding and configuring gateway intents
Interactions Guide Slash commands, buttons, select menus, modals

Running Tests

nix develop --command lune run tests/run_tests

The test suite includes 112 unit tests covering all modules.

Project Structure

src/
├── main.luau                    # Example bot
└── bleucord/
    ├── init.luau                # Library entry point
    ├── client.luau              # Main Client class
    ├── builders/
    │   ├── embed.luau           # EmbedBuilder
    │   ├── command.luau         # SlashCommandBuilder, ContextMenuCommandBuilder
    │   └── component.luau       # ActionRowBuilder, ButtonBuilder, SelectMenuBuilder, etc.
    ├── gateway/
    │   ├── init.luau            # Gateway manager (multi-shard)
    │   ├── shard.luau           # Individual WebSocket shard
    │   └── intents.luau         # Intent flags and presets
    ├── rest/
    │   ├── init.luau            # REST client (~150 endpoint methods)
    │   ├── endpoints.luau       # URL path builders
    │   └── rate_limiter.luau    # Rate limit handling
    ├── structures/
    │   ├── user.luau            # User model
    │   ├── guild.luau           # Guild + Role models
    │   ├── channel.luau         # Channel model (all types)
    │   ├── member.luau          # Guild Member model
    │   ├── message.luau         # Message model
    │   ├── interaction.luau     # Interaction model + response methods
    │   └── presence.luau        # Presence + Activity helpers
    └── utils/
        ├── event_emitter.luau   # Pub/sub event system
        ├── logger.luau          # Levelled logging
        ├── cache.luau           # Generic LRU cache
        ├── color.luau           # Color constants + utilities
        ├── permissions.luau     # Permission bitfield utilities
        └── snowflake.luau       # Snowflake ID utilities
tests/
├── test_runner.luau             # Test framework
└── run_tests.luau               # 112 unit tests

Development

This project uses Nix flakes for development environment management.

Enter the development environment:

nix develop

This provides:

  • BleuMoon (Lune) runtime
  • Nix LSP and formatting tools

License

TBD