Spaces:
Running
Running
File size: 5,651 Bytes
4fc4790 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | import OpenClawProtocol
import Foundation
extension ChannelsStore {
func start() {
guard !self.isPreview else { return }
guard self.pollTask == nil else { return }
self.pollTask = Task.detached { [weak self] in
guard let self else { return }
await self.refresh(probe: true)
await self.loadConfigSchema()
await self.loadConfig()
while !Task.isCancelled {
try? await Task.sleep(nanoseconds: UInt64(self.interval * 1_000_000_000))
await self.refresh(probe: false)
}
}
}
func stop() {
self.pollTask?.cancel()
self.pollTask = nil
}
func refresh(probe: Bool) async {
guard !self.isRefreshing else { return }
self.isRefreshing = true
defer { self.isRefreshing = false }
do {
let params: [String: AnyCodable] = [
"probe": AnyCodable(probe),
"timeoutMs": AnyCodable(8000),
]
let snap: ChannelsStatusSnapshot = try await GatewayConnection.shared.requestDecoded(
method: .channelsStatus,
params: params,
timeoutMs: 12000)
self.snapshot = snap
self.lastSuccess = Date()
self.lastError = nil
} catch {
self.lastError = error.localizedDescription
}
}
func startWhatsAppLogin(force: Bool, autoWait: Bool = true) async {
guard !self.whatsappBusy else { return }
self.whatsappBusy = true
defer { self.whatsappBusy = false }
var shouldAutoWait = false
do {
let params: [String: AnyCodable] = [
"force": AnyCodable(force),
"timeoutMs": AnyCodable(30000),
]
let result: WhatsAppLoginStartResult = try await GatewayConnection.shared.requestDecoded(
method: .webLoginStart,
params: params,
timeoutMs: 35000)
self.whatsappLoginMessage = result.message
self.whatsappLoginQrDataUrl = result.qrDataUrl
self.whatsappLoginConnected = nil
shouldAutoWait = autoWait && result.qrDataUrl != nil
} catch {
self.whatsappLoginMessage = error.localizedDescription
self.whatsappLoginQrDataUrl = nil
self.whatsappLoginConnected = nil
}
await self.refresh(probe: true)
if shouldAutoWait {
Task { await self.waitWhatsAppLogin() }
}
}
func waitWhatsAppLogin(timeoutMs: Int = 120_000) async {
guard !self.whatsappBusy else { return }
self.whatsappBusy = true
defer { self.whatsappBusy = false }
do {
let params: [String: AnyCodable] = [
"timeoutMs": AnyCodable(timeoutMs),
]
let result: WhatsAppLoginWaitResult = try await GatewayConnection.shared.requestDecoded(
method: .webLoginWait,
params: params,
timeoutMs: Double(timeoutMs) + 5000)
self.whatsappLoginMessage = result.message
self.whatsappLoginConnected = result.connected
if result.connected {
self.whatsappLoginQrDataUrl = nil
}
} catch {
self.whatsappLoginMessage = error.localizedDescription
}
await self.refresh(probe: true)
}
func logoutWhatsApp() async {
guard !self.whatsappBusy else { return }
self.whatsappBusy = true
defer { self.whatsappBusy = false }
do {
let params: [String: AnyCodable] = [
"channel": AnyCodable("whatsapp"),
]
let result: ChannelLogoutResult = try await GatewayConnection.shared.requestDecoded(
method: .channelsLogout,
params: params,
timeoutMs: 15000)
self.whatsappLoginMessage = result.cleared
? "Logged out and cleared credentials."
: "No WhatsApp session found."
self.whatsappLoginQrDataUrl = nil
} catch {
self.whatsappLoginMessage = error.localizedDescription
}
await self.refresh(probe: true)
}
func logoutTelegram() async {
guard !self.telegramBusy else { return }
self.telegramBusy = true
defer { self.telegramBusy = false }
do {
let params: [String: AnyCodable] = [
"channel": AnyCodable("telegram"),
]
let result: ChannelLogoutResult = try await GatewayConnection.shared.requestDecoded(
method: .channelsLogout,
params: params,
timeoutMs: 15000)
if result.envToken == true {
self.configStatus = "Telegram token still set via env; config cleared."
} else {
self.configStatus = result.cleared
? "Telegram token cleared."
: "No Telegram token configured."
}
await self.loadConfig()
} catch {
self.configStatus = error.localizedDescription
}
await self.refresh(probe: true)
}
}
private struct WhatsAppLoginStartResult: Codable {
let qrDataUrl: String?
let message: String
}
private struct WhatsAppLoginWaitResult: Codable {
let connected: Bool
let message: String
}
private struct ChannelLogoutResult: Codable {
let channel: String?
let accountId: String?
let cleared: Bool
let envToken: Bool?
}
|