DiscordKit: can receive and decode hello event

This commit is contained in:
2026-03-12 09:35:23 -04:00
parent d42227ba55
commit 707bbedac2
4 changed files with 66 additions and 4 deletions

View File

@@ -26,11 +26,10 @@ struct ApiClient {
let json = JSONDecoder() let json = JSONDecoder()
let decoded = try json.decode(GetGatewayResponse.self, from: data) let decoded = try json.decode(GetGatewayResponse.self, from: data)
return decoded.url return decoded.url
} }
} }
enum ApiError: Error { public enum ApiError: Error {
case invalidResponse case invalidResponse
case badStatus(_ message: String) case badStatus(_ message: String)
} }

View File

@@ -9,8 +9,11 @@ public struct Bot {
public init(token: String) async throws { public init(token: String) async throws {
client = ApiClient(token: token) 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)
} }
} }

View File

@@ -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
}

View File

@@ -15,3 +15,36 @@ public struct SessionStartLimit: Codable {
let reset_after: Int let reset_after: Int
let max_concurrency: 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
}