Skip to content

Releases: M1tsumi/SwiftDisc

SwiftDisc v0.10.0

14 Nov 19:58

Choose a tag to compare

[v0.10.0] - 2025-11-14

This release introduces experimental voice support, zero-dependency encryption, and developer-friendly utilities — alongside scaffolding for Discord’s latest features like Components V2 and Polls. Caelum continues to evolve as a Swift-native Discord toolkit for bots, apps, and automation.

🌟 Highlights

  • Developer Discord Utils: Mentions, emoji helpers, timestamps, markdown escaping.
  • Experimental Voice (macOS/iOS): Connect flow, UDP IP discovery, protocol select, Session Description, speaking.
  • Zero-dependency encryption: Pure-Swift Secretbox (XSalsa20-Poly1305) and RTP sender.
  • Music-bot friendly: Opus-in pipeline with VoiceAudioSource and PipeOpusSource for stdin piping on macOS.
  • Components V2 & Polls scaffolding: Generic JSON and typed envelopes to use latest Discord features now.

🆕 Added

Internal

  • Internal/DiscordUtils.swift: Mentions, EmojiUtils, DiscordTimestamp, MessageFormat.
  • Internal/JSONValue.swift: Lightweight JSONValue for flexible payload composition (Components V2, Polls, future APIs).

Voice

  • DiscordConfiguration.enableVoiceExperimental feature flag.
  • Voice Gateway handshake and UDP IP discovery (Network.framework).
  • VoiceGateway, VoiceClient, VoiceSender (RTP), Secretbox (XSalsa20-Poly1305), AudioSource protocol, PipeOpusSource.
  • Public API on DiscordClient: joinVoice, leaveVoice, playVoiceOpus, play(source:).

Examples

  • Examples/VoiceStdin.swift: Stream framed Opus from stdin to a voice channel.

Models

  • Models/AdvancedMessagePayloads.swift: V2MessagePayload, PollPayload typed envelopes.

REST

  • Components V2:
    • postMessage(channelId:payload:) (generic)
    • sendComponentsV2Message(channelId:payload:) (typed envelope)
  • Polls:
    • createPollMessage(channelId:content:poll:...) (generic)
    • createPollMessage(channelId:payload:...) (typed envelope)
  • Localization:
    • setCommandLocalizations(applicationId:commandId:nameLocalizations:descriptionLocalizations:)
  • Forwarding:
    • forwardMessageByReference(targetChannelId:sourceChannelId:messageId:)
  • Application-scoped resources:
    • post/patch/deleteApplicationResource(...) (generic)
  • App Emoji wrappers:
    • createAppEmoji(...), updateAppEmoji(...), deleteAppEmoji(...)
  • UserApps wrappers:
    • createUserAppResource(...), updateUserAppResource(...), deleteUserAppResource(...)

✏️ Changed

  • README:
    • Expanded Voice section (usage, requirements, macOS ffmpeg piping, iOS guidance)
    • Added Components V2 (generic + typed envelope) examples
    • Added Polls (generic + typed envelope) examples
    • Added Localization and Forwarding usage
    • Added Generic Application Resources, App Emoji, and UserApps usage
  • advaithpr.ts: Updated feature matrix (Components V2, Polls, Localization, Forwarding, App Emoji, UserApps → ✅)

📝 Notes

  • Voice is send-only; input must be Opus packets (48kHz, ~20ms).
  • No external dependencies were added.
  • iOS cannot spawn ffmpeg; provide Opus from your app/backend.

SwiftDisc v0.9.0

14 Nov 02:56

Choose a tag to compare

v0.9.0 – "The Big Visibility & Extensibility Release" – 2025-11-13

We’re thrilled to ship v0.9.0, a massive leap forward in completeness, flexibility, and developer experience. This release brings near-100% gateway coverage, powerful raw REST passthroughs, polished file handling, full autocomplete support, and a brand-new lightweight extensions/cogs system — all while staying true to SwiftDiscord’s pure-Swift, zero-dependency philosophy.

Highlights

  • 100% gateway event visibility – every event Discord sends is now exposed, including threads, scheduled events, and a universal raw fallback.
  • Raw REST passthrough – call any endpoint (even future ones) without waiting for library wrappers.
  • Smart file uploads – automatic MIME detection + configurable size guardrails.
  • End-to-end autocomplete – from registration to response in just a few lines.
  • Advanced caching – per-type TTLs + per-channel message LRU with instant pruning.
  • Extensions & Cogs – modular, hot-reloadable command groups with zero boilerplate.

Added

Gateway

  • Full thread events: THREAD_CREATE, THREAD_UPDATE, THREAD_DELETE, THREAD_MEMBER_UPDATE, THREAD_MEMBERS_UPDATE
  • Full scheduled-event suite: GUILD_SCHEDULED_EVENT_CREATE/UPDATE/DELETE/USER_ADD/USER_REMOVE
  • Universal fallback: DiscordEvent.raw(String, Data) dispatched for any unknown or future payload

REST

  • Raw endpoint helpers: rawGET, rawPOST, rawPATCH, rawPUT, rawDELETE with automatic JSON (de)serialization

File Uploads

  • FileAttachment.contentType with automatic inference from filename
  • Configurable upload limit via DiscordConfiguration.maxUploadBytes (default 100 MB) with clear validation errors

Interactions

  • Autocomplete support: InteractionResponseType.autocompleteResult (=8)
  • createAutocompleteResponse(...) builder + AutocompleteRouter for clean registration
  • Full wiring into EventDispatcher

Caching

  • Cache.Configuration with per-type TTL and per-channel message LRU
  • Typed getters, removeMessage(id:), and background pruning task

Extensions / Cogs

  • SwiftDiscExtension protocol + Cog base class
  • DiscordClient.loadExtension(_:), unloadExtensions(), hot-reload ready

Permissions

  • PermissionsUtil.effectivePermissions(member:in:) covering channel overwrites
  • PermissionOverwrite model added to Channel

Examples

  • Examples/AutocompleteBot.swift
  • Examples/FileUploadBot.swift
  • Examples/ThreadsAndScheduledEventsBot.swift
  • Updated Examples/README.md with setup instructions

Changed

  • README completely refreshed with new feature table of contents, quick-start guide, and DISCORD_BOT_TOKEN env-var usage
  • Minor breaking: some internal event structs renamed for consistency (migration guide in README)

A huge thank you to everyone who tested the betas and opened issues — this release wouldn’t be this solid without you!

Upgrade today and start building richer, more resilient bots with confidence.

Happy coding!
~ The SwiftDiscord Team

SwiftDisc v0.8.0

13 Nov 17:07

Choose a tag to compare

🎉 SwiftDisc v0.8.0 Released!

We're excited to announce SwiftDisc v0.8.0 — a major update focused on developer experience, interaction capabilities, and gateway reliability!

✨ What's New

🎨 Fluent Builders for Everything

Building Discord interactions just got a whole lot cleaner! Say goodbye to verbose JSON structures and hello to type-safe, fluent builders:

// Before: Complex nested structures
// After: Beautiful, readable code
let command = SlashCommandBuilder(name: "greet", description: "Greet someone")
    .addStringOption(name: "user", description: "Who to greet", required: true)
    .addIntegerOption(name: "enthusiasm", description: "Excitement level (1-10)")
        .addChoice(name: "Calm", value: 1)
        .addChoice(name: "Excited", value: 5)
        .addChoice(name: "SUPER EXCITED!", value: 10)
    .build()

📝 Modal Support

Create interactive forms with Discord Modals! Perfect for collecting detailed user input:

// Show a modal with text inputs
try await client.createInteractionModal(
    interactionId: interaction.id,
    interactionToken: interaction.token,
    customId: "feedback_modal",
    title: "Share Your Feedback",
    components: [
        ComponentsBuilder()
            .addActionRow()
                .addTextInput(
                    customId: "feedback_text",
                    label: "What do you think?",
                    style: .paragraph,
                    required: true,
                    placeholder: "Tell us your thoughts..."
                )
            .build()
    ]
)

🎮 Message Component Builders

Building interactive messages is now intuitive and type-safe:

let components = ComponentsBuilder()
    .addActionRow()
        .addButton(customId: "accept", label: "Accept", style: .success)
        .addButton(customId: "decline", label: "Decline", style: .danger)
    .addActionRow()
        .addSelectMenu(customId: "choose_role")
            .setPlaceholder("Select your role")
            .addOption(label: "Developer", value: "dev", emoji: "💻")
            .addOption(label: "Designer", value: "design", emoji: "🎨")
    .build()

🎭 Rich Presence Activities

Take your bot's presence to the next level with fully customizable activities:

// Simple status update
client.setStatus(.dnd)

// Rich activity with all the bells and whistles
let activity = ActivityBuilder(name: "with SwiftDisc", type: .playing)
    .setState("Building bots")
    .setDetails("v0.8.0 is live!")
    .setTimestamps(start: Date())
    .setLargeImage(key: "logo", text: "SwiftDisc")
    .addButton(label: "Join Discord", url: "https://discord.gg/...")
    .build()

client.setActivity(activity)

🔧 Enhanced Slash Command Management

Complete control over your application commands:

// Create a new slash command
let builder = SlashCommandBuilder(name: "poll", description: "Create a poll")
    .addStringOption(name: "question", description: "Poll question", required: true)
    .addIntegerOption(name: "duration", description: "Duration in minutes")
        .setMinValue(1)
        .setMaxValue(1440)

try await client.createGlobalApplicationCommand(applicationId: appId, command: builder.build())

// Bulk overwrite for efficient updates
try await client.bulkOverwriteGlobalApplicationCommands(
    applicationId: appId,
    commands: [command1, command2, command3]
)

🛡️ Rock-Solid Gateway Reliability

We've refined the gateway connection to be even more resilient:

  • Improved Heartbeat Timing — Proper jitter and ACK validation following Discord's guidelines
  • Smarter Reconnection — Indefinite retry with exponential backoff (capped for stability)
  • Better Session Management — Enhanced resume logic for seamless reconnects

Your bots will stay connected and responsive, even during network hiccups!

📋 Full Changelog

Added

  • Slash Commands

    • SlashCommandBuilder with fluent option helpers (string, integer, number, boolean, user, channel, role, mentionable, attachment)
    • Choice support for string and integer options
    • Min/max value constraints for number options
    • Complete REST API coverage: list, create, delete, bulk overwrite (global and guild-scoped)
  • Modals

    • InteractionResponseType.modal (type 9)
    • DiscordClient.createInteractionModal(...) helper method
    • MessageComponent.textInput (type 4) with style variants (short/paragraph)
    • Text input validation helpers (min/max length, required/optional)
  • Message Components

    • Fluent builders: ComponentsBuilder, ActionRowBuilder, ButtonBuilder, SelectMenuBuilder, TextInputBuilder
    • Type-safe component construction
    • Support for emojis, disabled states, and custom IDs
  • Rich Presence

    • Expanded Activity model with state, details, timestamps, assets, party, secrets, and buttons
    • ActivityBuilder for composing complex activities
    • Convenience helpers: setStatus(_:) and setActivity(...)
    • Button support in activities (label + URL)

Fixed

  • Gateway heartbeat loop now sends before sleeping and includes proper initial jitter
  • Reconnect attempts retry indefinitely with exponential backoff (capped at reasonable intervals)
  • Improved ACK validation to prevent premature disconnections

🚀 Migration Guide

Updating Slash Commands

If you were manually constructing command JSON:

// Old way ❌
let command: [String: Any] = [
    "name": "hello",
    "description": "Say hello",
    "options": [
        ["type": 3, "name": "name", "description": "Your name", "required": true]
    ]
]

// New way ✅
let command = SlashCommandBuilder(name: "hello", description: "Say hello")
    .addStringOption(name: "name", description: "Your name", required: true)
    .build()

Building Components

// Old way ❌
let components = [[
    "type": 1,
    "components": [[
        "type": 2,
        "style": 3,
        "custom_id": "btn",
        "label": "Click Me"
    ]]
]]

// New way ✅
let components = ComponentsBuilder()
    .addActionRow()
        .addButton(customId: "btn", label: "Click Me", style: .success)
    .build()

📦 Installation

Update your Package.swift:

dependencies: [
    .package(url: "https://github.com/M1tsumi/SwiftDisc.git", from: "0.8.0")
]

Happy building! 🎉

SwiftDisc v0.7.0

12 Nov 05:40
6e12748

Choose a tag to compare

SwiftDisc v0.7.0 – "Windsurf" Released! Compile-Time Safety & Full REST/Gateway Coverage

Released: 2025-11-12

We're thrilled to ship v0.7.0, the most significant leap in type safety and API completeness yet.
All core IDs are now Snowflake<T> — goodbye runtime crashes, hello compile-time guarantees.


Highlights

  • Full Snowflake<T> migration across models, REST, and Gateway — compile-time ID safety
  • Massive REST expansion: reactions, threads, bulk ops, file uploads, emojis, roles, interactions, prune, and more
  • Complete Gateway event suite: message reactions, bulk deletes, full guild lifecycle, member chunks

Added

Models

  • Generic Snowflake<T> with typed aliases:
    UserID, ChannelID, MessageID, GuildID, RoleID, EmojiID, ApplicationID, AttachmentID, OverwriteID, InteractionID, ApplicationCommandID
  • Reaction, PartialEmoji, ThreadMember, ThreadListResponse

REST Endpoints

  • Reactions: add/remove (self/user), get, bulk remove, remove by emoji
  • Threads: start/join/leave, manage members, list active/archived/joined/public/private
  • Bulk Ops: bulkDeleteMessages, crosspostMessage
  • Pins: getPinnedMessages, pinMessage, unpinMessage
  • File Uploads: sendMessageWithFiles, editMessageWithFiles (multipart/form-data)
  • Emojis: full CRUD (list, get, create, modify, delete)
  • User/Bot: getUser, modifyCurrentUser, listGuilds, leaveGuild, createDM, createGroupDM
  • Prune: getPruneCount, beginPrune with typed PrunePayload/PruneResponse
  • Roles: full CRUD + bulk position updates via typed IDs
  • Permission Overwrites: edit/delete with OverwriteID
  • Interaction Follow-ups: get/edit/delete original & followups

Gateway

  • Messages: MESSAGE_UPDATE, MESSAGE_DELETE, MESSAGE_DELETE_BULK, all reaction events
  • Guild: GUILD_MEMBER_ADD/REMOVE/UPDATE, role CRUD, emoji/sticker updates, GUILD_MEMBERS_CHUNK
  • Request Members: typed op 8 sender

HTTP

  • postMultipart, patchMultipart with payload_json + files[n]
  • Convenience put(path:) and delete(path:) for 204 responses

Documentation

  • README: Updated to v0.7.0, install snippet, prominent Discord CTA button

Changed

  • All core models (User, Guild, Channel, Message, GuildMember, Emoji, Interaction) now use typed Snowflake<T>
  • REST method signatures refactored for compile-time safety — no more String IDs

Notes

  • Remaining auxiliary models will adopt Snowflake<T> in follow-up PRs
  • permissions fields remain String? for now (typed bitset planned)

SwiftDisc is now production-ready for large-scale bots with full type safety and API parity.

SwiftDisc v0.6.0

12 Nov 01:34

Choose a tag to compare

[v0.6.0] - 2025-11-11

🚀 Highlights

SwiftDisc v0.6.0 is here — and it's Discord API-ready! This release delivers broad REST coverage (minus voice), advanced gateway stability, robust rate limiting, polished documentation, and CI support across platforms.

✅ Added

Slash Commands

  • Typed routing via SlashCommandRouter with subcommand path resolution and typed accessors
  • Full management: create/list/delete/bulk-overwrite for global and guild commands
  • Options: all official types + choices support
  • Permissions: default_member_permissions, dm_permission

Gateway & Stability

  • GatewayClient converted to actor; serialized event handling via EventDispatcher
  • Reconnect with exponential backoff; shard preservation; non-fatal decode errors

Sharding

  • loginAndConnectSharded(index:total:) and ShardManager for multi-shard orchestration

REST Coverage

  • Channels, Guilds, Members, Roles, Messages, Interactions, Webhooks, Bans — full CRUD and utility endpoints

Models

  • Rich Embed, MessageComponent, expanded Interaction, Guild, Channel, Role, and more

Cross-Platform & CI

  • Unified WebSocket adapter via URLSession
  • GitHub Actions CI for macOS and Windows; code coverage badge

High-Level API & Utilities

  • CommandRouter, SlashCommandRouter with onError callbacks
  • BotUtils: message chunking, mention/prefix helpers

Docs & Examples

  • README: minreqs checklist, Production Deployment section, polished header/buttons
  • Examples: Ping, Prefix Commands, Slash bot

🔧 Changed

  • Rate limiter: fixed bucket reset handling
  • REST/HTTP: improved headers, retries, and backoff
  • Event processing: moved to actor; simplified client sinks

SwiftDisc v0.2.0

11 Nov 23:05

Choose a tag to compare

[v0.2.0] - 2025-11-11

🚀 Phase 2: REST Maturity

This release marks a major milestone in SwiftDisc's REST capabilities. With robust rate limiting, error handling, and expanded endpoint support, SwiftDisc is now ready for serious bot development and integration.

✅ Added

  • Per-route rate limiting with automatic retry logic
  • Detailed error payload decoding for improved diagnostics
  • Initial REST endpoint coverage:
    • Channels
    • Guilds
    • Interactions
    • Webhooks

🛠 Changed

  • Internal REST layer refactored for modularity and future expansion
  • Improved logging and diagnostics for REST failures

SwiftDisc v0.1.0

11 Nov 22:30

Choose a tag to compare

[0.1.0] - 2025-11-11

🚀 Added

  • Gateway Phase 1 completed: Identify, Resume, and Reconnect logic implemented.
  • Heartbeat ACK tracking with jitter and adaptive backoff.
  • Full intent support with clarified documentation.
  • Priority event handling: READY, MESSAGE_CREATE, GUILD_CREATE, INTERACTION_CREATE.
  • Initial support for sharding and presence updates.

🛠️ Changed

  • README updated to reflect Phase 1 completion and gateway implementation details.
  • Developer documentation expanded to cover resume/reconnect logic and new event support.