From d42227ba5566a9dd9d8d0ef4388e98a0e83e7c84 Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Thu, 12 Mar 2026 08:00:07 -0400 Subject: [PATCH] DiscordKit feat: impl getGatewayURL --- .vscode/launch.json | 24 ++++++++++++++++++ Package.resolved | 22 ++++++++-------- Package.swift | 9 +++++-- Sources/DiscordKit/ApiClient.swift | 36 +++++++++++++++++++++++++++ Sources/DiscordKit/Bot.swift | 16 ++++++++++++ Sources/DiscordKit/Models.swift | 17 +++++++++++++ Sources/zundamon/MessageHandler.swift | 2 ++ Sources/zundamon/Wolfram.swift | 2 ++ Sources/zundamon/Zundamon.swift | 34 ++++++++++++++----------- 9 files changed, 135 insertions(+), 27 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 Sources/DiscordKit/ApiClient.swift create mode 100644 Sources/DiscordKit/Bot.swift create mode 100644 Sources/DiscordKit/Models.swift diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..aef9fc3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "configurations": [ + { + "type": "swift", + "request": "launch", + "args": [], + "cwd": "${workspaceFolder:zunda-bot}", + "name": "Debug zundamon", + "target": "zundamon", + "configuration": "debug", + "preLaunchTask": "swift: Build Debug zundamon" + }, + { + "type": "swift", + "request": "launch", + "args": [], + "cwd": "${workspaceFolder:zunda-bot}", + "name": "Release zundamon", + "target": "zundamon", + "configuration": "release", + "preLaunchTask": "swift: Build Release zundamon" + } + ] +} \ No newline at end of file diff --git a/Package.resolved b/Package.resolved index 582d10d..ebd3ccb 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "b3f560c4f196109910c6c326162b62c9d4c171d5ba1f22725daa5f5a9ffd2c75", + "originHash" : "8fae71593cfeba2ef52421241b82a32253b5dfcaf81f7533c3f5b0f981822d3a", "pins" : [ { "identity" : "async-http-client", @@ -24,8 +24,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/DiscordBM/DiscordBM.git", "state" : { - "revision" : "90d98d45ae3ee8ed8a2d3d6d86be4aa8ab56515c", - "version" : "1.16.0" + "branch" : "main", + "revision" : "90d98d45ae3ee8ed8a2d3d6d86be4aa8ab56515c" } }, { @@ -60,8 +60,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-async-algorithms.git", "state" : { - "revision" : "2971dd5d9f6e0515664b01044826bcea16e59fac", - "version" : "1.1.2" + "revision" : "9d349bcc328ac3c31ce40e746b5882742a0d1272", + "version" : "1.1.3" } }, { @@ -87,8 +87,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections.git", "state" : { - "revision" : "7b847a3b7008b2dc2f47ca3110d8c782fb2e5c7e", - "version" : "1.3.0" + "revision" : "8d9834a6189db730f6264db7556a7ffb751e99ee", + "version" : "1.4.0" } }, { @@ -96,8 +96,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-configuration.git", "state" : { - "revision" : "1bb939fe7bbb00b8f8bab664cc90020c035c08d9", - "version" : "1.1.0" + "revision" : "be76c4ad929eb6c4bcaf3351799f2adf9e6848a9", + "version" : "1.2.0" } }, { @@ -114,8 +114,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-distributed-tracing.git", "state" : { - "revision" : "e109d8b5308d0e05201d9a1dd1c475446a946a11", - "version" : "1.4.0" + "revision" : "dc4030184203ffafbb2ec614352487235d747fe0", + "version" : "1.4.1" } }, { diff --git a/Package.swift b/Package.swift index 24ecdf4..4a70da0 100644 --- a/Package.swift +++ b/Package.swift @@ -5,8 +5,9 @@ import PackageDescription let package = Package( name: "zundamon", + platforms: [.macOS(.v13)], dependencies: [ - .package(url: "https://github.com/DiscordBM/DiscordBM.git", from: "1.16.0"), + .package(url: "https://github.com/DiscordBM/DiscordBM.git", branch: "main"), .package(url: "https://github.com/thebarndog/swift-dotenv.git", from: "2.1.0"), .package(url: "https://github.com/CoreOffice/XMLCoder.git", from: "0.18.0") ], @@ -18,8 +19,12 @@ let package = Package( dependencies: [ .product(name: "DiscordBM", package: "discordbm"), .product(name: "SwiftDotenv", package: "swift-dotenv"), - .product(name: "XMLCoder", package: "xmlcoder") + .product(name: "XMLCoder", package: "xmlcoder"), + .target(name: "DiscordKit") ], ), + .target( + name: "DiscordKit", + ), ] ) diff --git a/Sources/DiscordKit/ApiClient.swift b/Sources/DiscordKit/ApiClient.swift new file mode 100644 index 0000000..e546f26 --- /dev/null +++ b/Sources/DiscordKit/ApiClient.swift @@ -0,0 +1,36 @@ +import Foundation +#if canImport(FoundationNetowrking) +import FoundationNetworking +#endif + +struct ApiClient { + static let apiUrl: URL = URL(string: "https://discord.com/api/v10")! + let token: String + + private func authReq(_ request: consuming URLRequest) async throws -> (Data, URLResponse) { + request.setValue("Bot \(token)", forHTTPHeaderField: "Authorization") + request.setValue("DiscordKit (https:\\candy123.moe, v0.0.1)", forHTTPHeaderField: "User-Agent") + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + let (data, res) = try await URLSession.shared.data(for: request) + guard let res = res as? HTTPURLResponse else { throw ApiError.invalidResponse } + guard res.statusCode >= 200 && res.statusCode <= 299 else { throw ApiError.badStatus("Status code not 2xx: \(res.statusCode)") } + + return (data, res) + } + + func getGatewayURL() async throws -> URL { + var req = URLRequest(url: ApiClient.apiUrl.appending(path: "/gateway/bot")) + req.httpMethod = "GET" + let (data, _) = try await authReq(req) + + let json = JSONDecoder() + let decoded = try json.decode(GetGatewayResponse.self, from: data) + return decoded.url + + } +} + +enum ApiError: Error { + case invalidResponse + case badStatus(_ message: String) +} diff --git a/Sources/DiscordKit/Bot.swift b/Sources/DiscordKit/Bot.swift new file mode 100644 index 0000000..fcb5bfb --- /dev/null +++ b/Sources/DiscordKit/Bot.swift @@ -0,0 +1,16 @@ +import Foundation +#if canImport(FoundationNetowrking) +import FoundationNetworking +#endif + +public struct Bot { + let client: ApiClient + + public init(token: String) async throws { + client = ApiClient(token: token) + + let gateway = try await client.getGatewayURL() + + print(gateway.absoluteURL) + } +} diff --git a/Sources/DiscordKit/Models.swift b/Sources/DiscordKit/Models.swift new file mode 100644 index 0000000..7bcbb85 --- /dev/null +++ b/Sources/DiscordKit/Models.swift @@ -0,0 +1,17 @@ +import Foundation +#if canImport(FoundationNetowrking) +import FoundationNetworking +#endif + +public struct GetGatewayResponse: Codable { + let url: URL + let shards: Int + let session_start_limit: SessionStartLimit +} + +public struct SessionStartLimit: Codable { + let total: Int + let remaining: Int + let reset_after: Int + let max_concurrency: Int +} diff --git a/Sources/zundamon/MessageHandler.swift b/Sources/zundamon/MessageHandler.swift index 4afb467..2943818 100644 --- a/Sources/zundamon/MessageHandler.swift +++ b/Sources/zundamon/MessageHandler.swift @@ -1,5 +1,7 @@ import Foundation +#if canImport(FoundationNetworking) import FoundationNetworking +#endif import DiscordBM struct MessageHandler { diff --git a/Sources/zundamon/Wolfram.swift b/Sources/zundamon/Wolfram.swift index 979eb49..d0833c9 100644 --- a/Sources/zundamon/Wolfram.swift +++ b/Sources/zundamon/Wolfram.swift @@ -1,5 +1,7 @@ import Foundation +#if canImport(FoundationNetworking) import FoundationNetworking +#endif import XMLCoder import DiscordBM diff --git a/Sources/zundamon/Zundamon.swift b/Sources/zundamon/Zundamon.swift index 2a23d59..18bab17 100644 --- a/Sources/zundamon/Zundamon.swift +++ b/Sources/zundamon/Zundamon.swift @@ -1,5 +1,6 @@ import Foundation import DiscordBM +import DiscordKit import SwiftDotenv @main @@ -10,28 +11,33 @@ struct Zundamon { let tmp = Result { try Dotenv.configure() } switch (tmp) { case .success: - print("Loaded .env file") + break case .failure: + print("Failed to load .env file") break } let token = ProcessInfo.processInfo.environment["DISCORD_TOKEN"]! - let bot = await BotGatewayManager(token: token, intents: [.guildMessages, .messageContent]) + guard !token.isEmpty else { fatalError("Err: Empty DISCORD_TOKEN. Exiting...") } - await withTaskGroup(of: Void.self) { taskGroup in - taskGroup.addTask { - await bot.connect() - let tmp = try! await bot.client.getOwnUser() - ownID = try! tmp.decode().id - } + let bot = try await DiscordKit.Bot(token: token) - for await event in await bot.events { - taskGroup.addTask { - await EventHandler(event: event, client: bot.client).handleAsync() - } - } - } + // let bot = await BotGatewayManager(token: token, intents: [.guildMessages, .messageContent]) + + //await withTaskGroup(of: Void.self) { taskGroup in + // taskGroup.addTask { + // await bot.connect() + // let tmp = try! await bot.client.getOwnUser() + // ownID = try! tmp.decode().id + // } + + // for await event in await bot.events { + // taskGroup.addTask { + // await EventHandler(event: event, client: bot.client).handleAsync() + // } + // } + //} } }