From 707bbedac2c6f984f2c14831fd109445292f48b3 Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Thu, 12 Mar 2026 09:35:23 -0400 Subject: [PATCH] DiscordKit: can receive and decode hello event --- Sources/DiscordKit/ApiClient.swift | 3 +-- Sources/DiscordKit/Bot.swift | 7 ++++-- Sources/DiscordKit/GatewayClient.swift | 27 +++++++++++++++++++++ Sources/DiscordKit/Models.swift | 33 ++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 Sources/DiscordKit/GatewayClient.swift diff --git a/Sources/DiscordKit/ApiClient.swift b/Sources/DiscordKit/ApiClient.swift index e546f26..368fac7 100644 --- a/Sources/DiscordKit/ApiClient.swift +++ b/Sources/DiscordKit/ApiClient.swift @@ -26,11 +26,10 @@ struct ApiClient { let json = JSONDecoder() let decoded = try json.decode(GetGatewayResponse.self, from: data) return decoded.url - } } -enum ApiError: Error { +public enum ApiError: Error { case invalidResponse case badStatus(_ message: String) } diff --git a/Sources/DiscordKit/Bot.swift b/Sources/DiscordKit/Bot.swift index fcb5bfb..adb28e0 100644 --- a/Sources/DiscordKit/Bot.swift +++ b/Sources/DiscordKit/Bot.swift @@ -9,8 +9,11 @@ public struct Bot { public init(token: String) async throws { client = ApiClient(token: token) - let gateway = try await client.getGatewayURL() + let gatewayURL = try await client.getGatewayURL() + + print(gatewayURL.absoluteURL) + let gateway = GatewayClient(gatewayURL: gatewayURL) + try await gateway.openConnection() - print(gateway.absoluteURL) } } diff --git a/Sources/DiscordKit/GatewayClient.swift b/Sources/DiscordKit/GatewayClient.swift new file mode 100644 index 0000000..d865cc8 --- /dev/null +++ b/Sources/DiscordKit/GatewayClient.swift @@ -0,0 +1,27 @@ +import Foundation +#if canImport(FoundationNetowrking) +import FoundationNetworking +#endif + +struct GatewayClient { + let gatewayURL: URL + + func openConnection() async throws { + let ws = URLSession.shared.webSocketTask(with: gatewayURL.appending(component: "?v=10&encoding=json")) + ws.resume() + let message = try await ws.receive() + guard case .string(let str) = message else { throw GatewayError.invalidMessage } + print(str) + let json = JSONDecoder() + let gwMessage = try json.decode(GatewayMessage.self, from: Data(str.utf8)) + dump(gwMessage) + guard case .hello(let hello) = gwMessage.d else { print("whoops"); return } + dump(hello) + } + +} + +public enum GatewayError: Error { + case invalidMessage + case invalidOpcode +} diff --git a/Sources/DiscordKit/Models.swift b/Sources/DiscordKit/Models.swift index 7bcbb85..9765aba 100644 --- a/Sources/DiscordKit/Models.swift +++ b/Sources/DiscordKit/Models.swift @@ -15,3 +15,36 @@ public struct SessionStartLimit: Codable { let reset_after: Int let max_concurrency: Int } + +public enum GatewayPayload: Decodable { + case hello(HelloPayload) +} + +public struct GatewayMessage: Decodable { + let op: Int + let d: GatewayPayload? + + enum CodingKeys: String, CodingKey { + case t + case s + case op + case d + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + op = try container.decode(Int.self, forKey: .op) + switch op { + case 10: + let hello = try container.decode(HelloPayload.self, forKey: .d) + d = .hello(hello) + default: + d = nil + break + } + } +} + +public struct HelloPayload: Codable { + let heartbeat_interval: Int +}