Skip to content

M1tsumi/SwiftDisc

SwiftDisc Typing

SwiftDisc

CI Swift License Discord

SwiftDisc is a Swift-first Discord API wrapper for building bots and integrations with async/await, typed models, and practical high-level tools.

This README covers install, first bot run, intents, and example entry points.

At a glance

  • Swift 6.2 concurrency model and actor-safe APIs.
  • Gateway and REST support in one library.
  • Built-in rate-limit handling and reconnect logic.
  • High-level routers for commands, slash commands, autocomplete, components, and views.
  • Guild sticker write operations are supported (createGuildSticker, modifyGuildSticker, deleteGuildSticker).
  • Runnable examples in Examples.

Installation

Add SwiftDisc with Swift Package Manager:

// Package.swift
.dependencies([
    .package(url: "https://github.com/M1tsumi/SwiftDisc.git", from: "2.3.0")
]),
.targets([
    .target(
        name: "YourBot",
        dependencies: ["SwiftDisc"]
    )
])

Platform support

  • macOS 11+
  • iOS 14+
  • tvOS 14+
  • watchOS 7+
  • Windows with Swift 6.2+

Quick start (message bot)

import Foundation
import SwiftDisc

@main
struct MyBot {
    static func main() async {
        let token = ProcessInfo.processInfo.environment["DISCORD_BOT_TOKEN"] ?? ""
        let client = DiscordClient(token: token)

        await client.setOnReady { ready in
            print("Logged in as \(ready.user.username)")
        }

        await client.setOnMessage { message in
            guard message.content?.lowercased() == "ping" else { return }
            do {
                try await message.reply(client: client, content: "Pong!")
            } catch {
                print("Reply failed: \(error)")
            }
        }

        do {
            try await client.loginAndConnect(intents: [.guilds, .guildMessages, .messageContent])
            let events = await client.events
            for await _ in events { }
        } catch {
            print("Client failed: \(error)")
        }
    }
}

Quick start (slash command)

import Foundation
import SwiftDisc

@main
struct SlashBot {
    static func main() async {
        let token = ProcessInfo.processInfo.environment["DISCORD_BOT_TOKEN"] ?? ""
        let client = DiscordClient(token: token)

        let slash = SlashCommandRouter()
        await slash.register("ping") { ctx in
            try await ctx.client.createInteractionResponse(
                interactionId: ctx.interaction.id,
                token: ctx.interaction.token,
                content: "Pong!"
            )
        }

        await client.useSlashCommands(slash)

        try? await client.loginAndConnect(intents: [.guilds])
        let events = await client.events
        for await _ in events { }
    }
}

Bot setup checklist

If your bot appears to connect but receives no data, one of these is usually the reason:

  1. DISCORD_BOT_TOKEN is missing or invalid.
  2. Required intents are not passed to loginAndConnect.
  3. Privileged intents (especially messageContent) are not enabled in the Discord Developer Portal.
  4. Bot was invited without the scopes/permissions you expect.

How SwiftDisc is organized

  • DiscordClient: main actor and lifecycle entrypoint.
  • Gateway: real-time events and dispatch.
  • REST client: typed HTTP request/response operations.
  • High-level modules in Sources/SwiftDisc/HighLevel:
    • CommandRouter
    • SlashCommandRouter
    • AutocompleteRouter
    • ViewManager
    • collectors/builders/utilities
  • Typed models in Sources/SwiftDisc/Models.

Example programs

These examples are included and useful for real onboarding:

Packaged executable targets can be run with:

swift run PingBotExample
swift run CommandsBotExample
swift run SlashBotExample
swift run AutocompleteBotExample
swift run ComponentsExample
swift run ViewExample
swift run FileUploadBotExample

Reliability and DX notes

SwiftDisc v2.3.0 is a correctness and reliability patch release that fixes critical compilation issues for Swift 6.2, resolves gateway connection and disconnect handling bugs, corrects multipart attachment handling, and improves WebSocket message size limits. This release ensures stability and proper behavior across gateway, REST, and WebSocket layers.

Debugging capabilities

SwiftDisc provides several debugging and observability features for developers:

  • Gateway decode diagnostics — Enable DiscordConfiguration.enableGatewayDecodeDiagnostics to log gateway payload decoding failures with opcode/event context and payload previews
  • Rate limit observability — Use DiscordConfiguration.onRateLimit to observe REST bucket updates and waits through lightweight RateLimitEvent snapshots
  • Typed error handling — All REST and gateway operations throw DiscordError with descriptive messages and optional debugContext for troubleshooting
  • Router error handlersCommandRouter, SlashCommandRouter, and ViewManager support optional error handlers that receive context about failed operations
  • Default error logging — Routers include default error logging with channel ID, pattern type, and custom ID context when no custom error handler is set

Troubleshooting

  • Build/toolchain mismatch:
    • Use Swift 6.2+.
  • Connected but no command responses:
    • Verify intents and Developer Portal privileged intent settings.
  • 429/rate-limit issues:
    • Avoid tight retry loops and bursty duplicate requests.
  • CI failures:
    • Start by checking runner logs in Errors.

Documentation map

Community and support

License

MIT. See LICENSE.

About

SwiftDisc is a lightweight, native Swift library designed for building powerful Discord bots on iOS and macOS

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Sponsor this project

Contributors

Languages